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

# Custom Engine

> Send query data from any custom engine to Ryft via the Ingest API. Covers authentication, payload format, and bulk ingestion.

For query engines not natively supported by Ryft, you can send query data directly using the Ryft Ingest API.

### Get your Ryft Ingest Token

Ryft will provide a unique ingest token for your environment. This token is required to authenticate requests to the Ingest API.

### Send Query Data

Send a `POST` request to the ingest endpoint with your query data as JSON:

```bash{2} theme={null}
curl -X POST https://ingest.ryft.io/ingest/push/queries \
  -H "X-Ryft-Token: <RYFT_INGEST_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "context": {
      "catalog": "iceberg",
      "schema": "gold",
      "queryType": "SELECT",
      "user": "my-service",
      "userAgent": "my-client"
    },
    "timestamp": "2026-03-10T12:00:00.000Z",
    "duration_ms": 100,
    "query": "SELECT * FROM gold.my_table",
    "queryId": "test-001",
    "queryState": "FINISHED",
    "tags": ["source:my-engine"]
  }'
```

A `200` response means the message was accepted and will be processed.

### Bulk Ingestion

You can send multiple queries in a single request by passing a JSON array instead of a single object:

```bash{2} theme={null}
curl -X POST https://ingest.ryft.io/ingest/push/queries \
  -H "X-Ryft-Token: <RYFT_INGEST_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "context": { "catalog": "iceberg" },
      "queryId": "q-123",
      "query": "SELECT * FROM my_table",
      "queryState": "FINISHED",
      "duration_ms": 1230,
      "timestamp": "2026-03-10T12:00:00.000Z"
    },
    {
      "context": { "catalog": "iceberg" },
      "queryId": "q-124",
      "query": "SELECT count(*) FROM events",
      "queryState": "FINISHED",
      "duration_ms": 450,
      "timestamp": "2026-03-10T12:01:00.000Z"
    }
  ]'
```

### Payload Schema

| Field                        | Type                | Required                   | Description                                                                                                                         |
| ---------------------------- | ------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `context`                    | object              | **yes**                    | Query environment context. All fields within are optional — pass `{}` if no context is available.                                   |
| `context.catalog`            | string              | no                         | Catalog name (e.g. `iceberg`)                                                                                                       |
| `context.schema`             | string              | no                         | Default namespace for unqualified table names                                                                                       |
| `context.queryType`          | string              | no                         | One of: `SELECT`, `EXPLAIN`, `DESCRIBE`, `INSERT`, `UPDATE`, `DELETE`, `ANALYZE`, `DATA_DEFINITION`, `ALTER_TABLE_EXECUTE`, `MERGE` |
| `context.serverVersion`      | string              | no                         | Query engine version                                                                                                                |
| `context.user`               | string              | no                         | User or service account that ran the query                                                                                          |
| `context.userAgent`          | string              | no                         | Client identifier                                                                                                                   |
| `query`                      | string              | **yes**                    | The SQL query text                                                                                                                  |
| `queryId`                    | string              | **yes**                    | Unique query identifier                                                                                                             |
| `queryState`                 | string              | **yes**                    | Terminal query state: `FINISHED`, `SUCCEEDED`, or `FAILED`                                                                          |
| `timestamp`                  | string              | **yes**                    | ISO 8601 timestamp of query execution                                                                                               |
| `duration_ms`                | number              | **yes**                    | Execution time in milliseconds                                                                                                      |
| `tags`                       | string\[]           | no                         | Free-form labels for filtering in Query Explorer                                                                                    |
| `failureInfo`                | object or object\[] | no                         | Only needed for failed queries (`queryState: "FAILED"`). Can be a single object or an array.                                        |
| `failureInfo.errorCode.type` | string              | yes (within `failureInfo`) | One of: `USER_ERROR`, `INTERNAL_ERROR`, `INSUFFICIENT_RESOURCES`, `EXTERNAL`                                                        |
| `failureInfo.errorCode.code` | number              | no                         | Numeric error code (free-form)                                                                                                      |
| `failureInfo.errorCode.name` | string              | no                         | Error name (free-form)                                                                                                              |
| `failureInfo.failureMessage` | string              | no                         | Human-readable error description                                                                                                    |
| `failureInfo.failureType`    | string              | no                         | Exception or error class name                                                                                                       |

<Note>Make sure outbound connectivity is enabled to `ingest.ryft.io` on port `443` (HTTPS).</Note>
