> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sluice.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /api/ingest

> Ingest events from the Sluice SDK or Go agent.

Accepts a batch of normalized events from the SDK or agent. This is the primary data ingestion endpoint — all job, worker, and queue data enters Sluice through this endpoint.

## Authentication

API key via `Authorization: Bearer sk_...` header.

## Request body

```json theme={null}
{
  "events": [
    {
      "type": "job_state_change",
      "timestamp": "2026-02-27T10:30:00.000Z",
      "framework": "celery",
      "connectionId": "550e8400-e29b-41d4-a716-446655440000",
      "job": {
        "externalId": "abc123-def456",
        "name": "app.tasks.send_email",
        "queue": "default",
        "state": "completed",
        "previousState": "active",
        "workerId": "celery@worker-1",
        "attempt": 1,
        "createdAt": "2026-02-27T10:29:55.000Z",
        "startedAt": "2026-02-27T10:29:56.000Z",
        "completedAt": "2026-02-27T10:30:00.000Z"
      }
    }
  ]
}
```

### Event fields

| Field          | Type     | Required | Description                                                                                |
| -------------- | -------- | -------- | ------------------------------------------------------------------------------------------ |
| `type`         | `string` | Yes      | Event type identifier (e.g., `job_state_change`, `worker_state_change`, `queue_snapshot`). |
| `timestamp`    | `string` | Yes      | ISO 8601 datetime.                                                                         |
| `framework`    | `string` | Yes      | One of `celery`, `bullmq`, `sidekiq`.                                                      |
| `connectionId` | `string` | Yes      | UUID of the connection. Must match the authenticated API key's connection.                 |
| `job`          | `object` | No       | Job event payload. Present for job-related events.                                         |
| `worker`       | `object` | No       | Worker event payload. Present for worker-related events.                                   |
| `queue`        | `object` | No       | Queue snapshot payload. Present for queue metrics.                                         |

Exactly one of `job`, `worker`, or `queue` should be present per event.

### Job payload

| Field           | Type      | Required | Description                                                                                                |
| --------------- | --------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `externalId`    | `string`  | Yes      | Framework-native job ID (Celery task UUID). Max 512 chars.                                                 |
| `name`          | `string`  | Yes      | Task/job type name (e.g., `app.tasks.send_email`). Max 1024 chars.                                         |
| `queue`         | `string`  | No       | Queue name. Max 255 chars.                                                                                 |
| `state`         | `string`  | Yes      | Unified state: `unknown`, `queued`, `scheduled`, `active`, `completed`, `failed`, `retrying`, `cancelled`. |
| `previousState` | `string`  | No       | Previous unified state.                                                                                    |
| `workerId`      | `string`  | No       | Worker identifier. Max 512 chars.                                                                          |
| `attempt`       | `integer` | No       | Current attempt number (1-indexed).                                                                        |
| `maxRetries`    | `integer` | No       | Configured retry limit.                                                                                    |
| `progress`      | `number`  | No       | Progress value between 0.0 and 1.0.                                                                        |
| `error`         | `string`  | No       | Error message on failure. Max 10,000 chars.                                                                |
| `stacktrace`    | `string`  | No       | Full traceback on failure. Max 50,000 chars.                                                               |
| `createdAt`     | `string`  | No       | ISO 8601 — when the job was dispatched.                                                                    |
| `startedAt`     | `string`  | No       | ISO 8601 — when execution began.                                                                           |
| `completedAt`   | `string`  | No       | ISO 8601 — when execution finished.                                                                        |
| `extensions`    | `object`  | No       | Framework-specific fields that don't map to the common model.                                              |

### Worker payload

| Field         | Type       | Required | Description                                                       |
| ------------- | ---------- | -------- | ----------------------------------------------------------------- |
| `externalId`  | `string`   | Yes      | Framework-native worker ID (e.g., `celery@worker-1`).             |
| `hostname`    | `string`   | Yes      | Worker hostname.                                                  |
| `pid`         | `integer`  | No       | Worker process ID.                                                |
| `state`       | `string`   | Yes      | One of `online`, `busy`, `idle`, `offline`, `heartbeat`.          |
| `concurrency` | `integer`  | No       | Max concurrent jobs.                                              |
| `activeJobs`  | `integer`  | No       | Currently processing count.                                       |
| `queues`      | `string[]` | No       | Queues this worker consumes.                                      |
| `metadata`    | `object`   | No       | Framework-specific metadata (software versions, pool type, etc.). |

### Queue payload

| Field       | Type      | Required | Description                     |
| ----------- | --------- | -------- | ------------------------------- |
| `name`      | `string`  | Yes      | Queue name. Max 255 chars.      |
| `depth`     | `integer` | Yes      | Current number of pending jobs. |
| `consumers` | `integer` | No       | Number of active consumers.     |

## Limits

* Maximum **1,000 events** per request.
* Maximum **5 MB** request body.
* Free tier: **10,000 events per day**. Resets at midnight UTC.

## Response

<CodeGroup>
  ```json 200 — Success theme={null}
  {
    "accepted": 42,
    "rejected": 0,
    "skipped": 3,
    "truncated": 0,
    "usage": {
      "used": 8042,
      "limit": 10000,
      "remaining": 1958,
      "resetAt": "2026-02-28T00:00:00.000Z"
    }
  }
  ```

  ```json 400 — Validation error theme={null}
  {
    "error": {
      "code": "VALIDATION_ERROR",
      "message": "Request body failed schema validation.",
      "docs_url": "https://docs.sluice.sh/troubleshooting/api-errors",
      "details": {
        "events": ["Array must contain at least 1 element(s)"]
      }
    }
  }
  ```

  ```json 429 — Daily limit exceeded theme={null}
  {
    "error": {
      "code": "DAILY_LIMIT_EXCEEDED",
      "message": "Daily limit reached (10,000 events). Previously ingested data is preserved. Upgrade for higher limits.",
      "docs_url": "https://docs.sluice.sh/troubleshooting/usage-limits"
    },
    "usage": {
      "used": 10000,
      "limit": 10000,
      "remaining": 0,
      "resetAt": "2026-02-28T00:00:00.000Z"
    }
  }
  ```
</CodeGroup>

### Response fields

| Field       | Type      | Description                                                             |
| ----------- | --------- | ----------------------------------------------------------------------- |
| `accepted`  | `integer` | Number of events successfully processed.                                |
| `rejected`  | `integer` | Number of events that failed validation or processing.                  |
| `skipped`   | `integer` | Number of duplicate events that were skipped.                           |
| `truncated` | `integer` | Number of events dropped because the daily limit was reached mid-batch. |
| `usage`     | `object`  | Current usage counters for the day.                                     |
