Propose to the field map
Tell CEEJAY which fields and events your game sends, so the community can approve them before the first value is sent.
POST /v1/games/{game}/field-map/propose · requires players:write
Call it once when you build the integration, or when your game gets a new value worth sending. Names CEEJAY does not recognise become proposals, and the community's team approves them in the dashboard. Without it, the first call to Set player fields or Log player events with a new name proposes it too. The field map explains the states.
Path parameters
Prop
Type
Body parameters
Send at least one field or event, in sample, fields or events.
Prop
Type
Each entry of fields holds:
Prop
Type
Each entry of events holds sourceKey (1 to 80 characters, required), key and label (up to 80 characters).
Returns
Prop
Type
The entries are shaped as in Get the field map.
Example
curl -X POST https://ceejay.communitystudios.xyz/api/v1/games/rugby_manager/field-map/propose \
-H "Authorization: Bearer $CEEJAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sample": {
"fields": {
"league_position": 3,
"club": "Harbour Town",
"coins_spent_cents": 12900
},
"events": ["match_won", "cup_entered"]
}
}'The TypeScript tab calls ceejay.fieldMap.propose from the TypeScript SDK. It returns the data of the response below.
{
"success": true,
"data": {
"fields": [
{
"key": "league_position",
"sourceKey": "league_position",
"name": "League position",
"type": "number",
"options": [],
"unit": null,
"scale": null,
"category": "progress",
"standard": false,
"sensitive": false,
"state": "proposed"
},
{
"key": "club",
"sourceKey": "club",
"name": "Club",
"type": "text",
"options": [],
"unit": null,
"scale": null,
"category": "progress",
"standard": false,
"sensitive": false,
"state": "proposed"
},
{
"key": "coins_spent_cents",
"sourceKey": "coins_spent_cents",
"name": "Coins spent cents",
"type": "number",
"options": [],
"unit": null,
"scale": 0.01,
"category": "progress",
"standard": false,
"sensitive": false,
"state": "proposed"
}
],
"events": [
{
"key": "match_won",
"sourceKey": "match_won",
"label": "Won a match",
"keepsQuantity": false,
"state": "proposed",
"rewardMode": "once"
},
{
"key": "cup_entered",
"sourceKey": "cup_entered",
"label": "Entered the cup",
"keepsQuantity": false,
"state": "proposed",
"rewardMode": "once"
}
],
"skipped": []
}
}How a proposal is made
The rules are fixed and no AI model reads your values, so no player value leaves CEEJAY.
- A name that is a known alias of a standard field maps to that standard field (
levelis Game level,last_seenis Last played), including a standard field that has not received its first value yet. trueandfalsecreate a yes or no field, a number a number field, text that reads as a date a date field, and everything else a text field. The community's team chooses the choices of a dropdown.- A name that ends in
_centsproposes a scale of0.01. - A key is generated from the name:
League Position,leaguePositionandleague-positionare allleague_position. - An entry that is approved, or that the team marked unused, is never modified: it is returned in
skippedwith the reason.
Who approves
An API key cannot approve proposals. A team member does that in the dashboard, where they choose the name, the type, the choices and the share category, and can mark the field sensitive. The team is notified when a new entry is added to the map, at most once a day for each game.
Safe to repeat
A name that is already proposed is matched, not created twice, so the request takes no idempotencyKey. The SDK does not retry automatically; retrying it yourself is safe.
The scope
players:write is part of *, so a Full Access key can call this.
Limits
This request is counted against the key's own requests per minute: 60 unless a higher limit was set on it, and never more than 600. Rate limits has the numbers and the headers.
Errors
| Status | code | error | When |
|---|---|---|---|
400 | bad_request | The request body must be a JSON object | The body is null, text, a number or a list |
400 | bad_request | Send at least one field or event to propose, in sample, fields or events | The request names no field and no event |
400 | bad_request | sample must be an object | sample was sent, and it is not an object |
400 | bad_request | type must be one of: text, number, date, choice, yes_no, ordered | An entry of sample, fields or events cannot be read. field names where, such as fields.type, fields.sourceKey or events.key |
403 | community_not_active | This community is no longer active on CEEJAY | The community removed CEEJAY from its server |
403 | game_not_allowed | This API key is limited to other games | The key is limited to other games of the community |
403 | audience_not_allowed | A game made for children cannot connect players or send player data | The game is set up as made for children. Such a game connects nobody and takes no player data |
404 | not_available | This is not available on this instance yet. | Connect is not enabled for this instance. It is enabled per instance. The body adds feature, which is players. Retrying will not change the response |
404 | game_not_found | Game not found | The community has no game with this slug, or the game was removed. A slug that is not 2 to 32 lower-case letters, digits and underscores, starting with a letter, gets this response too |
409 | game_paused | This game is paused | The game is paused or suspended |
Every error body also carries requestId, and a 400 with the code bad_request names the invalid field in field. Match on code, not on the message text, which can change.
The errors every request shares (401, 403 for a missing scope, 405, 429, 500) are on the Errors page.

