# Operator Data API Reference Full reference for the data ingestion API. **Base path:** `/functions/v1/operator-data-api` **Authentication:** `Authorization: Bearer oh_live_...` --- ## List templates {#list-templates} ``` GET /templates ``` Returns all available data templates. ```bash curl https://api.onehazel.com/operator-data-api/templates \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` **Response:** ```json { "success": true, "data": [ { "id": "tpl_igaming", "name": "iGaming", "version": "1.0", "schema": { "entity_types": { "player": { "required": [...], "optional": [...] } }, "event_types": { "transaction": { "required": ["type", "amount", "currency"], "optional": [...] } }, "state_keys": ["balance", "kyc_status", "risk_score", "loyalty_tier"], "pii_fields": { "player": ["first_name", "last_name", "email", "phone", "date_of_birth"] } }, "created_at": "2026-01-01T00:00:00.000Z" } ] } ``` --- ## Get settings {#get-settings} ``` GET /settings ``` Returns the operator's configured template and data retention settings. ```bash curl https://api.onehazel.com/operator-data-api/settings \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` **Response:** ```json { "success": true, "data": { "template": { "id": "tpl_igaming", "name": "iGaming", "version": "1.0" }, "dataRetentionDays": null, "retentionPolicy": null } } ``` --- ## Update settings {#update-settings} ``` PUT /settings ``` Set the data template and/or retention policy. | Field | Type | Description | |---|---|---| | `templateId` | string | Template ID (e.g. `tpl_igaming`) | | `dataRetentionDays` | number | Global data retention in days | | `retentionPolicy` | object | Per-type retention configuration | ### Retention policy ```json { "retentionPolicy": { "entity_events": { "hot_days": 90, "archive_days": 365 }, "entity_states": { "hot_days": 30, "archive_days": 180 } } } ``` **Constraints:** - `entity_events.hot_days` minimum: 30 - `entity_events.archive_days` maximum: 1825 (5 years) - `entity_states.hot_days` minimum: 30 - `entity_states.archive_days` maximum: 1825 (5 years) ```bash curl -X PUT https://api.onehazel.com/operator-data-api/settings \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateId": "tpl_igaming", "retentionPolicy": { "entity_events": { "hot_days": 90, "archive_days": 365 } } }' ``` --- ## Create or update entity {#create-entity} ``` POST /entities ``` | Field | Type | Required | Description | |---|---|---|---| | `entityType` | string | Yes | Entity type from template | | `externalId` | string | Yes | Your unique identifier | | `data` | object | Yes | Entity data payload | **Headers:** | Header | Required | Description | |---|---|---| | `Idempotency-Key` | No | Prevents duplicate processing (7 day TTL) | **Rate limit:** `ingest:realtime` ```bash curl -X POST https://api.onehazel.com/operator-data-api/entities \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entityType": "player", "externalId": "player_12345", "data": { "first_name": "James", "last_name": "Wilson", "email": "james@example.com", "country": "GB", "currency": "GBP" } }' ``` **Response (201 / 200):** ```json { "success": true, "data": { "id": "ent_a1b2c3d4e5f67890", "externalId": "player_12345", "entityType": "player", "action": "created" } } ``` `action` is `"created"` (201) for new entities, `"updated"` (200) for existing ones. --- ## Get entity {#get-entity} ``` GET /entities/:externalId ``` Returns entity with decrypted PII fields. ```bash curl https://api.onehazel.com/operator-data-api/entities/player_12345 \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` --- ## Delete entity (GDPR) {#delete-entity} ``` DELETE /entities/:externalId ``` Soft-deletes the entity: data is replaced with `{ "_deleted": true }`, related events are redacted to `{ "_redacted": true }`, and all states are removed. ```bash curl -X DELETE https://api.onehazel.com/operator-data-api/entities/player_12345 \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` --- ## Record event {#record-event} ``` POST /entities/:externalId/events ``` | Field | Type | Required | Description | |---|---|---|---| | `eventType` | string | Yes | Event type from template | | `data` | object | Yes | Event data payload | **Headers:** | Header | Required | Description | |---|---|---| | `Idempotency-Key` | No | Prevents duplicate events (7 day TTL, scoped per operator) | **Rate limit:** `ingest:realtime` If an event with the same idempotency key already exists, returns the original event ID with `"action": "duplicate"`. ```bash curl -X POST https://api.onehazel.com/operator-data-api/entities/player_12345/events \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: deposit-abc123" \ -d '{ "eventType": "transaction", "data": { "type": "deposit", "amount": 50.00, "currency": "GBP", "method": "card" } }' ``` --- ## List events {#list-events} ``` GET /entities/:externalId/events ``` | Parameter | Type | Default | Description | |---|---|---|---| | `type` | string | — | Filter by event type | | `limit` | integer | 100 | Max 100 | | `offset` | integer | 0 | Pagination offset | ```bash curl "https://api.onehazel.com/operator-data-api/entities/player_12345/events?type=transaction&limit=20" \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` --- ## Update state {#update-state} ``` PUT /entities/:externalId/state/:key ``` Request body: `{ "value": }` or the value directly. **Rate limit:** `ingest:realtime` ```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" } }' ``` --- ## Get all states {#get-all-states} ``` GET /entities/:externalId/state ``` ```bash curl https://api.onehazel.com/operator-data-api/entities/player_12345/state \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` --- ## Get single state {#get-state} ``` GET /entities/:externalId/state/:key ``` ```bash curl https://api.onehazel.com/operator-data-api/entities/player_12345/state/kyc_status \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` --- ## Batch entities {#batch-entities} ``` POST /batch/entities ``` Array of `{ entityType, externalId, data }` objects. Maximum 1,000 items. **Rate limit:** `ingest:batch` --- ## Batch events {#batch-events} ``` POST /batch/events ``` Array of `{ externalId, eventType, data }` objects. Maximum 5,000 items. **Rate limit:** `ingest:batch` --- ## Batch states {#batch-states} ``` POST /batch/states ``` Array of `{ externalId, stateKey, value }` objects. Maximum 1,000 items. **Rate limit:** `ingest:batch` --- ## Job status {#job-status} ``` GET /batch/jobs/:jobId ``` Returns the status of a batch job, scoped to the authenticated operator. ```bash curl https://api.onehazel.com/operator-data-api/batch/jobs/job_d4e5f6789012abcd \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` **Response:** ```json { "success": true, "data": { "id": "job_d4e5f6789012abcd", "type": "batch_ingest_entities", "status": "completed", "progress": 100, "output": { "succeeded": 100, "failed": 2, "errors": [...] }, "error": null, "created_at": "2026-04-06T12:00:00.000Z", "completed_at": "2026-04-06T12:00:05.000Z" } } ``` --- ## Error codes | HTTP Status | Error Code | Description | |---|---|---| | `400` | `MISSING_FIELDS` | Required fields are missing | | `400` | `VALIDATION_FAILED` | Data fails template validation | | `400` | `TEMPLATE_NOT_CONFIGURED` | No template set — call `PUT /settings` first | | `400` | `INVALID_INPUT` | Invalid batch input (not an array, empty, or exceeds limit) | | `401` | `UNAUTHORIZED` | Missing or invalid API key | | `404` | `ENTITY_NOT_FOUND` | Entity with given externalId not found | | `404` | `NOT_FOUND` | Resource not found | | `429` | `RATE_LIMITED` | Rate limit exceeded | | `500` | `INTERNAL_ERROR` | Server error |