States
States are key-value snapshots attached to entities. Unlike events (which are append-only), states represent the current value of something — a player's balance, KYC status, or risk score. Writing a state replaces the previous value for that key.
Update a state
PUT /operator-data-api/entities/:externalId/state/:keyPath parameters
| Parameter | Description |
|---|---|
externalId | The entity's external ID |
key | The state key (must be defined in your template) |
Request body
The request body can be either:
- An object with a
valuefield:{ "value": ... } - The value directly as the body
The value can be any JSON type — string, number, boolean, object, or array.
Valid state keys (iGaming template)
| Key | Typical value | Description |
|---|---|---|
balance | { "amount": 145.50, "currency": "GBP" } | Current wallet balance |
kyc_status | "verified" | KYC verification status |
risk_score | "low" | Responsible gaming risk assessment |
loyalty_tier | "gold" | Loyalty programme tier |
Upsert semantics
States use upsert on the composite key (entity_id, state_key). If a state already exists for this entity and key, it is overwritten. If not, it is created.
Example: Update balance
bash
curl -X PUT https://api.onehazel.com/operator-data-api/entities/player_12345/state/balance \
-H "Authorization: Bearer oh_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"value": {
"amount": 145.50,
"currency": "GBP",
"last_updated": "2026-04-06T14:30:00Z"
}
}'Response:
json
{
"success": true,
"data": {
"stateKey": "balance",
"value": {
"amount": 145.50,
"currency": "GBP",
"last_updated": "2026-04-06T14:30:00Z"
}
}
}Example: Update KYC status
bash
curl -X PUT https://api.onehazel.com/operator-data-api/entities/player_12345/state/kyc_status \
-H "Authorization: Bearer oh_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"value": "verified"
}'Example: Update risk score
bash
curl -X PUT https://api.onehazel.com/operator-data-api/entities/player_12345/state/risk_score \
-H "Authorization: Bearer oh_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"value": "medium"
}'Get all states
GET /operator-data-api/entities/:externalId/stateReturns all current state snapshots for an entity.
Example
bash
curl https://api.onehazel.com/operator-data-api/entities/player_12345/state \
-H "Authorization: Bearer oh_live_YOUR_API_KEY"Response:
json
{
"success": true,
"data": [
{
"state_key": "balance",
"value": { "amount": 145.50, "currency": "GBP" },
"updated_at": "2026-04-06T14:30:00.000Z"
},
{
"state_key": "kyc_status",
"value": "verified",
"updated_at": "2026-04-06T11:00:00.000Z"
},
{
"state_key": "risk_score",
"value": "medium",
"updated_at": "2026-04-06T14:35:00.000Z"
}
]
}Get a single state
GET /operator-data-api/entities/:externalId/state/:keyExample
bash
curl https://api.onehazel.com/operator-data-api/entities/player_12345/state/balance \
-H "Authorization: Bearer oh_live_YOUR_API_KEY"Response:
json
{
"success": true,
"data": {
"state_key": "balance",
"value": { "amount": 145.50, "currency": "GBP" },
"updated_at": "2026-04-06T14:30:00.000Z"
}
}Event fan-out
When a state is updated, OneHazel emits an internal event of type entity_state.updated.<key> (e.g. entity_state.updated.kyc_status). This can trigger workflows.
Error codes
| HTTP Status | Error Code | Description |
|---|---|---|
400 | VALIDATION_FAILED | Unknown state key — check your template's state_keys list |
400 | TEMPLATE_NOT_CONFIGURED | No template set — call PUT /settings first |
401 | UNAUTHORIZED | Missing or invalid API key |
404 | ENTITY_NOT_FOUND | No entity with that externalId exists |
404 | NOT_FOUND | State key does not exist for this entity (GET only) |
429 | RATE_LIMITED | Rate limit exceeded |
500 | INTERNAL_ERROR | Server error |