API
Sift exposes a REST API through the Gateway service at https://api.getsift.ai. You can use it to read actions, agents, and queues, search conversations, query analytics, submit content for moderation, and set custom fields on an action - all programmatically.
At a glance
REST API at https://api.getsift.ai | ✅ |
| Read actions, agents, queues, analytics; search conversations | ✅ |
| Write: set custom fields on an action; submit moderation cases | ✅ |
| Send a reply as a customer-facing message | ❌ not available via this API today |
X-API-Key header authentication | ✅ |
| OpenAPI spec and Swagger UI | ✅ |
Filter DSL on GET /v0/action/list | ✅ |
| Per-key rate limiting | ❌ not implemented yet |
Current version v0 | ✅ |

Authentication
Every request must include your API key in the X-API-Key header:
GET /v0/action/list
X-API-Key: sk_live_your_key_hereSee the API Keys page for how to generate and manage keys, and what a key can and can't do.
Exploring the API
Sift publishes a full OpenAPI spec and an interactive Swagger UI:
- OpenAPI JSON:
https://api.getsift.ai/docs/json - Swagger UI:
https://api.getsift.ai/docs
You can import the OpenAPI spec into Postman, Insomnia, or any API client.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v0/action/list | List actions. Supports a filter DSL, date range, and sort - see Query Syntax |
GET | /v0/action/:id | Fetch a single action |
GET | /v0/actions/:actionId/custom-fields | Read an action's custom fields (requires a read-scoped key) |
PATCH | /v0/actions/:actionId/custom-fields | Set an action's custom fields (requires a write-scoped key) |
GET | /v0/agents | List agents with performance metrics |
GET | /v0/agents/:id | Fetch a single agent |
GET | /v0/queues | List queues with metrics |
GET | /v0/analytics/tags | Tag dashboard stats |
GET | /v0/analytics/tags/volume | Tag volume over time |
GET | /v0/analytics/sentiment | Daily sentiment distribution |
GET | /v0/analytics/sentiment/by-tag | Sentiment broken down by tag |
GET | /v0/conversations/search | Full-text and DSL search across conversations |
POST | /v0/moderation/cases | Submit one moderation case (requires write) |
POST | /v0/moderation/cases/batch | Submit 1–100 moderation cases in order (requires write) |
GET | /v0/moderation/cases/:caseId | Poll the exact current evaluation status (requires read) |
There is no endpoint that sends or posts a reply on a customer's behalf - the only write routes today are the custom-fields PATCH and the moderation submission.
Moderation intake
Moderation endpoints are available only when your organization is configured for Sift's
ad_policy moderation mode. Intake validates the complete request before enqueueing work into the
normal Sift ingestion and synthesis pipeline.
The externalId is immutable within your organization. Retrying the exact same submission returns
duplicate. Reusing an existing externalId with different known content returns 409 for the
single-case endpoint. In batch, every input receives an ordered accepted, duplicate, or
rejected result; a conflicting item is rejected without preventing other valid items from being
accepted.
Use the returned caseId with the GET endpoint. Polling returns only the evaluation for the
currently active policy workflow and never falls back to an older completed evaluation. A case may
report policy_not_configured, pending, running, completed, or failed. The final decision is
included only after completion.
Error Format
Errors return a consistent JSON body:
{
"success": false,
"error": "Action not found"
}Some endpoints add extra fields on specific error cases - for example, the custom-fields PATCH returns a fieldErrors object (field name → message) on a 422. An uncaught server error always returns 500 with { "success": false, "error": "Internal server error" }.
Common status codes: 400 (bad request), 401 (missing or invalid key), 403 (forbidden, e.g. a read-scoped key calling a write route), 404 (not found), 409 (immutable identifier conflict), 422 (validation failed), 500 (server error).
Versioning
The current API version is v0. Breaking changes will be introduced under a new version prefix; non-breaking additions (new fields, new endpoints) can be added at any time without a version bump.