API reference
Chat
2 operations. Base URL https://api.scarleta.ai. Select an operation to see its parameters, samples and errors.
Jump to an operation
POST/v1/chatSend a chat message
Free and paid accountsUses tokens
- API key required
- Free and paid accounts
- Uses tokens
Sends one message to the Scarleta assistant and starts a turn in the background. The call returns 202 at once; it does not contain the reply. Follow the turn with GET /v1/conversations/{conversation_id}/status until active_turn_workflow_id is null, then read the reply with GET /v1/conversations/{conversation_id}. POST /v1/conversations/{conversation_id}/cancel stops a turn that is running.
Leave out conversation_id to start a new conversation, or send the id of one of your conversations to continue it; the assistant remembers the earlier turns. Attach audio with audio_url or with media; the assistant decides which analyses to run, and those analyses are charged like any other. Only one turn can run in a conversation at a time: a second message sent while a turn is active returns 409 turn_in_progress.
Cost. Free for a message that needs no analysis. When the assistant runs an analysis on your audio, that analysis is charged per second of audio like the equivalent single call.
curl -X POST "https://api.scarleta.ai/v1/chat" \
-H "Authorization: Bearer $SCARLETA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "What key is this track in, and does it drift?",
"audio_url": "https://example.com/track-1.wav"
}'Request body
| Name | Type | Required | Description |
|---|---|---|---|
| promptbody | string | Required | Your message, at most 32768 characters. Allowed: 1 to 32768 characters. |
| audio_urlbody | string | Optional | A file to discuss. Shorthand for a single `media` item. Allowed: at most 4096 characters. |
| mediabody | array<object> | Optional | Files to attach, at most 2. Takes precedence over `audio_url`. |
| media[].urlbody | string | Required | Where to fetch the file: a public `http` or `https` URL, or a file in your own library. Allowed: at least 1 character. |
| media[].typebody | "audio" | "video" | Optional | Kind of file. Detected from the URL when absent. |
| media[].namebody | string | null | Optional | Display name shown with the file in the conversation. |
| media[].regionbody | object | null | Optional | Seconds to analyze, `{ start, end }` with `end` greater than `start`. The whole file when absent. |
| media[].region.startbody | number | Required | Allowed: at least 0. |
| media[].region.endbody | number | Required | |
| media[].mediaTypebody | string | null | Optional | MIME type of the file, for example `audio/wav`. |
| media[].durationSbody | number | null | Optional | Length in seconds, shown in the conversation. Display only: billing always uses the measured length. Allowed: at least 0. |
| conversation_idbody | string | Optional | UUID of one of your conversations to continue. A new conversation is created when absent. |
Response fields
| Field | Type | Description |
|---|---|---|
| status | "IN_PROGRESS" | |
| workflow | "turn-workflow" | |
| conversation_id | string | The conversation the message belongs to. Use it for follow-up messages and to read the reply. |
| turn_workflow_id | string | Identifier of this turn. |
| workflow_instance_id | string | Same value as `turn_workflow_id`. |
| prompt | string | Your message, echoed. |
| audio_url | string | null | The file the turn works on: the one you attached, or the file already in the conversation. |
| tenant_id | string | null | Your account identifier. Absent for free accounts. |
| created_at | string | ISO 8601 timestamp. |
| response_time_ms | integer | How long accepting the message took, in milliseconds. Allowed: -9007199254740991 to 9007199254740991. |
| message | string | Where to poll and how to cancel. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | missing_prompt | Invalid JSON, a missing `prompt`, too many `media` items, an unacceptable URL, or a `conversation_id` that is not a UUID. |
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 403 | media_not_owned | A library file in `audio_url` or `media` is owned by another account. |
| 404 | conversation_not_found | `conversation_id` belongs to another account. |
| 409 | turn_in_progress | A turn is already running in this conversation. `error.details.existing_workflow_id` names it. |
| 413 | prompt_too_long | The prompt is over 32768 characters, or the whole request body is over 1048576 bytes (`payload_too_large`: send a shorter message and attach audio by URL). |
| 429 | rate_limit_exceeded | Over the account request budget for the hour. Wait for the `Retry-After` header, then retry. |
| 500 | chat_failed | The message could not be processed. Retry. |
| 502 | turn_workflow_create_failed | The turn could not be started. Retry. |
| 503 | conversation_ownership_unavailable | Temporary condition; retry shortly. |
Example responses
{
"data": {
"status": "IN_PROGRESS",
"workflow": "turn-workflow",
"conversation_id": "3f9c1d2e-7b44-4c1a-8e0f-5a6b7c8d9e01",
"turn_workflow_id": "turn_6e0ed523-72f5-464e-974c-9ae95fdc2a99",
"workflow_instance_id": "turn_6e0ed523-72f5-464e-974c-9ae95fdc2a99",
"prompt": "What key is this track in, and does it drift?",
"audio_url": "https://example.com/track-1.wav",
"tenant_id": "8c1d0b52-3f6a-4e0d-9d7b-2a41c5e90f13",
"created_at": "2026-10-21T03:41:37.272Z",
"response_time_ms": 2736,
"message": "Turn dispatched. Poll GET /v1/conversations/3f9c1d2e-7b44-4c1a-8e0f-5a6b7c8d9e01/status for active-turn state. POST /v1/conversations/3f9c1d2e-7b44-4c1a-8e0f-5a6b7c8d9e01/cancel to abort."
},
"meta": {
"request_id": "req_0b7a3c2e-6f1d-4d9a-8e55-3a4b5c6d7e8f"
}
}- 202 Accepted. The turn is running. Carries `X-Conversation-ID` and `X-Turn-Workflow-ID` headers with the same values as the body,.
- 400 Invalid JSON, a missing `prompt`, too many `media` items, an unacceptable URL, or a `conversation_id` that is not a UUID.
- 401 Missing, malformed, unknown or revoked API key.
- 403 A library file in `audio_url` or `media` is owned by another account.
- 404 `conversation_id` belongs to another account.
- 409 A turn is already running in this conversation. `error.details.existing_workflow_id` names it.
- 413 The prompt is over 32768 characters, or the whole request body is over 1048576 bytes (`payload_too_large`: send a shorter message and attach audio by URL).
- 429 Over the account request budget for the hour. Wait for the `Retry-After` header, then retry.
- 500 The message could not be processed. Retry.
- 502 The turn could not be started. Retry.
- 503 Temporary condition; retry shortly.
Try it
Sends this request from your browser to https://api.scarleta.ai with your own key. The key stays in this page only (never saved or put in the address) and is cleared when you leave. Revoke any key you have shared.
Other error codes this operation can return: auth_unavailable, conversation_do_error, invalid_audio_url, invalid_auth_format, invalid_conversation_id, invalid_json, invalid_key_format, missing_api_key, missing_auth, payload_too_large, rate_limit_unavailable, service_misconfigured, too_many_media, turn_workflow_precondition_missing, unauthorized.
GET/v1/chat/{job_id}Get an assistant job
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Reads a background job run by the assistant service by its job_id: a recipe run (see POST /v1/recipe/execute) or a job started by an older chat. Chat messages sent with POST /v1/chat answer with a conversation, not a job id; read their replies through the conversation routes. For a recipe run prefer GET /v1/recipe/jobs/{job_id}, which also reports the steps. status is IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED or TIMEOUT; response holds the raw outcome once the job has ended. prompt and model appear only on jobs that stored them. Only your own jobs are returned.
Cost. Free of charge.
JOB_ID="YOUR_JOB_ID"
curl "https://api.scarleta.ai/v1/chat/$JOB_ID" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| job_idpath | string | Required | The id of the job, for example `recipe_9f3a1c7e52b4`. Allowed: at least 1 character. |
Response fields
| Field | Type | Description |
|---|---|---|
| job_id | string | Identifier of the job. |
| status | string | `IN_QUEUE`, `IN_PROGRESS`, `COMPLETED`, `FAILED` or `TIMEOUT`. |
| workflow | "ai-agent" | Always `ai-agent`: only jobs of the assistant service are returned here. |
| audio_url | string | null | The audio the job used. |
| prompt | string | The message the job was started with, when it stored one. |
| model | string | A model setting stored with the job, when it had one. |
| response | any | The raw outcome of the job once it has ended (an object for a recipe run); null before. |
| interpretation | string | null | A written interpretation of the outcome, or null. |
| conversation_id | string | null | The conversation the job is tied to, or null. |
| error | any | Why the job failed, or null. |
| created_at | string | ISO 8601 timestamp. |
| completed_at | string | null | ISO 8601 timestamp of the end, or null. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | invalid_job_id | `job_id` has characters outside letters, digits and `_ . : -`, or is too long. |
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 404 | job_not_found | No assistant job with this id belongs to your account. |
| 429 | rate_limit_exceeded | Over the account request budget for the hour. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"job_id": "recipe_9f3a1c7e52b4",
"status": "COMPLETED",
"workflow": "ai-agent",
"audio_url": "https://example.com/track-1.wav",
"response": {
"status": "success",
"step_count": 1
},
"interpretation": null,
"conversation_id": null,
"error": null,
"created_at": "2026-10-21T03:41:37.272Z",
"completed_at": "2026-10-21T03:41:56.630Z"
},
"meta": {
"request_id": "req_0b7a3c2e-6f1d-4d9a-8e55-3a4b5c6d7e8f"
}
}- 200 `meta.request_id` is present.
- 400 `job_id` has characters outside letters, digits and `_ . : -`, or is too long.
- 401 Missing, malformed, unknown or revoked API key.
- 404 No assistant job with this id belongs to your account.
- 429 Over the account request budget for the hour. Wait for the `Retry-After` header, then retry.
- 503 Temporary platform condition; retry shortly.
Try it
Sends this request from your browser to https://api.scarleta.ai with your own key. The key stays in this page only (never saved or put in the address) and is cleared when you leave. Revoke any key you have shared.
Other error codes this operation can return: invalid_auth_format, invalid_key_format, missing_api_key, missing_auth, missing_job_id, rate_limit_unavailable, retrieval_failed, unauthorized.