Skip to content
For LLMsView as Markdown·

Batch Operations ​

Batch endpoints let you send large volumes of data in a single request. Use them for initial data loads, migrations, or periodic bulk syncs.

Batch entities ​

POST /operator-data-api/batch/entities

Upserts up to 1,000 entities in a single request. Each entity follows the same format as the individual POST /entities endpoint.

Request body ​

An array of entity objects:

json
[
  { "entityType": "player", "externalId": "player_001", "data": { ... } },
  { "entityType": "player", "externalId": "player_002", "data": { ... } }
]

Example ​

bash
curl -X POST https://api.onehazel.com/operator-data-api/batch/entities \
  -H "Authorization: Bearer oh_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "entityType": "player",
      "externalId": "player_001",
      "data": {
        "first_name": "Alice",
        "last_name": "Chen",
        "email": "alice@example.com",
        "country": "GB",
        "currency": "GBP",
        "status": "active"
      }
    },
    {
      "entityType": "player",
      "externalId": "player_002",
      "data": {
        "first_name": "Bob",
        "last_name": "Smith",
        "email": "bob@example.com",
        "country": "MT",
        "currency": "EUR",
        "status": "active"
      }
    }
  ]'

Response ​

json
{
  "success": true,
  "data": {
    "jobId": "job_d4e5f6789012abcd",
    "succeeded": 2,
    "failed": 0,
    "errors": []
  }
}

Partial failures ​

If some entities fail validation, the response includes details for each failure:

json
{
  "success": true,
  "data": {
    "jobId": "job_d4e5f6789012abcd",
    "succeeded": 1,
    "failed": 1,
    "errors": [
      {
        "index": 1,
        "externalId": "player_002",
        "code": "VALIDATION_FAILED",
        "message": "Missing required field: \"email\""
      }
    ]
  }
}

Batch events ​

POST /operator-data-api/batch/events

Inserts up to 5,000 events in a single request. Each event must reference an existing entity by externalId.

Request body ​

An array of event objects:

json
[
  { "externalId": "player_001", "eventType": "transaction", "data": { ... } },
  { "externalId": "player_001", "eventType": "game_activity", "data": { ... } }
]

Example ​

bash
curl -X POST https://api.onehazel.com/operator-data-api/batch/events \
  -H "Authorization: Bearer oh_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "externalId": "player_001",
      "eventType": "transaction",
      "data": {
        "type": "deposit",
        "amount": 100.00,
        "currency": "GBP",
        "method": "bank_transfer"
      }
    },
    {
      "externalId": "player_001",
      "eventType": "game_activity",
      "data": {
        "game_id": "european-roulette",
        "bet_amount": 10.00,
        "win_amount": 25.00,
        "currency": "GBP"
      }
    },
    {
      "externalId": "player_002",
      "eventType": "transaction",
      "data": {
        "type": "deposit",
        "amount": 50.00,
        "currency": "EUR",
        "method": "card"
      }
    }
  ]'

Response ​

json
{
  "success": true,
  "data": {
    "succeeded": 3,
    "failed": 0,
    "errors": []
  }
}

Batch states ​

POST /operator-data-api/batch/states

Upserts up to 1,000 state snapshots in a single request.

Request body ​

An array of state objects:

json
[
  { "externalId": "player_001", "stateKey": "balance", "value": { ... } },
  { "externalId": "player_001", "stateKey": "kyc_status", "value": "verified" }
]

Example ​

bash
curl -X POST https://api.onehazel.com/operator-data-api/batch/states \
  -H "Authorization: Bearer oh_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "externalId": "player_001",
      "stateKey": "balance",
      "value": { "amount": 250.00, "currency": "GBP" }
    },
    {
      "externalId": "player_001",
      "stateKey": "kyc_status",
      "value": "verified"
    },
    {
      "externalId": "player_002",
      "stateKey": "balance",
      "value": { "amount": 50.00, "currency": "EUR" }
    },
    {
      "externalId": "player_002",
      "stateKey": "loyalty_tier",
      "value": "silver"
    }
  ]'

Response ​

json
{
  "success": true,
  "data": {
    "succeeded": 4,
    "failed": 0,
    "errors": []
  }
}

Checking job status ​

Batch entity operations create a job record that you can poll:

GET /operator-data-api/batch/jobs/:jobId

Example ​

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": 2,
      "failed": 0,
      "errors": []
    },
    "error": null,
    "created_at": "2026-04-06T12:00:00.000Z",
    "completed_at": "2026-04-06T12:00:01.500Z"
  }
}

Limits ​

EndpointMaximum items per request
POST /batch/entities1,000
POST /batch/events5,000
POST /batch/states1,000

Synchronous vs asynchronous ​

Batch entity operations create a job queue entry for tracking, but currently process inline (synchronously). The response includes the full result immediately.

For initial data seeding where you need guaranteed ordering (e.g. create entities before recording events against them), use the individual POST /entities endpoint in sequence rather than the batch endpoint.

Error codes ​

HTTP StatusError CodeDescription
400INVALID_INPUTBody is not a non-empty array, or exceeds the maximum batch size
400TEMPLATE_NOT_CONFIGUREDNo template set. Call PUT /settings first
401UNAUTHORIZEDMissing or invalid API key
404NOT_FOUNDJob ID not found (for status check)
429RATE_LIMITEDRate limit exceeded for ingest:batch
500INTERNAL_ERRORServer error