API reference
Files
7 operations. Base URL https://api.scarleta.ai. Select an operation to see its parameters, samples and errors.
Jump to an operation
GET/v1/audioList stored files
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Returns the files stored under your account, 100 per page by default, in storage order. Follow pagination.cursor while pagination.has_more is true. The list shows what is in storage: a file you deleted stays listed until it is removed for good (7 days after deletion, or when you delete it forever). Counts against the hourly account request budget. Available to free and paid accounts.
Cost. Free of charge.
curl "https://api.scarleta.ai/v1/audio" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limitquery | integer | Optional | Files per page. Defaults to 100; values above 1000 are clamped to 1000, and a value below 1 or not a number falls back to the default. |
| cursorquery | string | Optional | The `pagination.cursor` of the previous page. Opaque. |
Response fields
| Field | Type | Description |
|---|---|---|
| files | array<object> | |
| files[].file_id | string | Identifier of the file. |
| files[].key | string | Storage path of the file inside your account. |
| files[].size | integer | Size in bytes. Allowed: -9007199254740991 to 9007199254740991. |
| files[].size_mb | string | Size in mebibytes with two decimals. |
| files[].uploaded | string | When the file was stored, as an ISO 8601 timestamp. |
| pagination | object | |
| pagination.limit | integer | The page size used. Allowed: -9007199254740991 to 9007199254740991. |
| pagination.cursor | string | Pass as `cursor` to get the next page. Absent on the last page. |
| pagination.has_more | boolean |
Errors
| Status | Code | Description |
|---|---|---|
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 429 | rate_limit_exceeded | Over the account request budget. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"files": [
{
"file_id": "3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b",
"key": "00000000-0000-4000-8000-000000000001/audio/3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav",
"size": 176478,
"size_mb": "0.17",
"uploaded": "2026-10-20T11:53:45.938Z"
}
],
"pagination": {
"limit": 100,
"has_more": false
}
}
}- 200 One page of files. The body is `{ data }` without `meta`.
- 401 Missing, malformed, unknown or revoked API key.
- 429 Over the account request budget. 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, rate_limit_unavailable, unauthorized.
DELETE/v1/audio/{fileId}Delete a file
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Moves one of your files to the trash. It is not erased at once: it stays recoverable for 7 days (purge_after), after which it is removed for good. Only your own files can be deleted; any other id, and a file already in the trash, returns 404. Counts against the hourly account request budget. Available to free and paid accounts.
Cost. Free of charge.
FILEID="YOUR_FILEID"
curl -X DELETE "https://api.scarleta.ai/v1/audio/$FILEID" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| fileIdpath | string | Required | The `file_id` of one of your files, as returned by the upload routes and the file list. A trailing media extension such as `.wav` is ignored. |
Response fields
| Field | Type | Description |
|---|---|---|
| file_id | string | Identifier of the file. |
| status | "trashed" | |
| trashed_at | string | When the file was moved to the trash, as an ISO 8601 timestamp. |
| purge_after | string | When the file is removed for good, as an ISO 8601 timestamp. |
Errors
| Status | Code | Description |
|---|---|---|
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 404 | file_not_found | No file with this id in your account, or it is already in the trash. |
| 429 | rate_limit_exceeded | Over the account request budget. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"file_id": "3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b",
"status": "trashed",
"trashed_at": "2026-10-21T03:40:58.310Z",
"purge_after": "2026-10-28T03:40:58.310Z"
}
}- 200 The file is in the trash. The body is `{ data }` without `meta`.
- 401 Missing, malformed, unknown or revoked API key.
- 404 No file with this id in your account, or it is already in the trash.
- 429 Over the account request budget. 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: db_unavailable, invalid_auth_format, invalid_key_format, missing_api_key, missing_auth, rate_limit_unavailable, unauthorized.
POST/v1/audio/{fileId}/download-urlCreate a download link
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Creates a link for downloading one of your files. Fetch download_url with a plain GET and no API key; the response is the file with a Content-Disposition: attachment header. The link works once, and only until expires_in seconds have passed (60 to 86400; 3600 if you send no body). A second request, or one after expiry, gets 403 invalid_download_token; create a new link instead. Only your own files can be linked: any other id returns 404.
Send filename to choose the name the download is saved under (ignored when longer than 200 characters). The body is optional; one that is not valid JSON is treated as empty. Counts against the hourly account request budget. Available to free and paid accounts.
Cost. Free of charge.
FILEID="YOUR_FILEID"
curl -X POST "https://api.scarleta.ai/v1/audio/$FILEID/download-url" \
-H "Authorization: Bearer $SCARLETA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"expires_in": 3600,
"filename": "morning-session.wav"
}'Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| fileIdpath | string | Required | The `file_id` of one of your files, as returned by the upload routes and the file list. A trailing media extension such as `.wav` is ignored. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| expires_inbody | integer | Optional | Seconds the link stays valid, 60 to 86400. Defaults to 3600. |
| filenamebody | string | Optional | File name for the download, at most 200 characters. |
Response fields
| Field | Type | Description |
|---|---|---|
| download_url | string | Address to `GET` the file from. Works once. |
| file_id | string | Identifier of the file. |
| expires_in | integer | Seconds the link stays valid. Allowed: -9007199254740991 to 9007199254740991. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | invalid_expires_in | `expires_in` is not an integer in range. |
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 404 | file_not_found | No file with this id in your account. |
| 413 | file_too_large | The stored file is over the size limit and cannot be linked. |
| 415 | invalid_audio_file | The stored file is not audio and cannot be linked. |
| 429 | rate_limit_exceeded | Over the account request budget. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"download_url": "https://api.scarleta.ai/v1/audio/download/dt_v1_859fca05-4d2f-41ce-89b7-bd1d8681adc9?sig=632d9afd5adb5160267986aa97911c50&fn=morning-session.wav",
"file_id": "3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b",
"expires_in": 3600
}
}- 200 Link created. The body is `{ data }` without `meta`.
- 400 `expires_in` is not an integer in range.
- 401 Missing, malformed, unknown or revoked API key.
- 404 No file with this id in your account.
- 413 The stored file is over the size limit and cannot be linked.
- 415 The stored file is not audio and cannot be linked.
- 429 Over the account request budget. 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, rate_limit_unavailable, unauthorized.
GET/v1/audio/storage-usageGet storage usage
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Returns how much storage your account uses. Every account includes 1 TiB; cap_bytes reports that included amount. Files in the trash still count until they are removed for good. Counts against the hourly account request budget. Available to free and paid accounts.
Cost. Free of charge.
curl "https://api.scarleta.ai/v1/audio/storage-usage" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Response fields
| Field | Type | Description |
|---|---|---|
| used_bytes | integer | Bytes your files use. Allowed: -9007199254740991 to 9007199254740991. |
| cap_bytes | integer | Bytes of storage included with the account. Allowed: -9007199254740991 to 9007199254740991. |
| tier | "free" | "paid" | The account tier the figures are for. |
Errors
| Status | Code | Description |
|---|---|---|
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 429 | rate_limit_exceeded | Over the account request budget. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"used_bytes": 208773279,
"cap_bytes": 1099511627776,
"tier": "paid"
}
}- 200 Usage figures. The body is `{ data }` without `meta`.
- 401 Missing, malformed, unknown or revoked API key.
- 429 Over the account request budget. 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, rate_limit_unavailable, unauthorized.
POST/v1/audio/upload-urlGet a presigned upload URL
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Starts an upload that goes straight to storage. Declare the file with content_length (and content_type), then send the file bytes with a PUT to the returned upload_url within 15 minutes. The file then appears in your library and the file list. A file can be up to 10 GiB for audio and 1 GiB for MP4 or MOV video.
upload_url is opaque: send the request to it exactly as returned, with the same Content-Type you declared, and do not parse it or add your API key (the URL itself is the credential). When direct is false the URL points back at this API instead of storage; the same PUT rules apply. Use media_url to refer to the stored file afterwards, and audio_id to attach it as a version.
Declaring the size reserves that much of your storage right away, so a file that would not fit is refused here with 413 storage_quota_exceeded, before any bytes are sent. An upload you never complete keeps its reservation until it is cleaned up. For files you want to resume, or for many parts in parallel, use an upload session instead. Counts against the hourly account request budget. Available to free and paid accounts.
Cost. Free of charge; the file counts toward your storage.
curl -X POST "https://api.scarleta.ai/v1/audio/upload-url" \
-H "Authorization: Bearer $SCARLETA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content_type": "audio/wav",
"filename": "morning-session.wav",
"content_length": 1920044,
"duration_seconds": 60
}'Request body
| Name | Type | Required | Description |
|---|---|---|---|
| content_lengthbody | integer | Required | Size of the file in bytes. Required. At most 10 GiB for audio and 1 GiB for video. `size` is accepted as an alias. Allowed: at most 10737418240. |
| content_typebody | string | Optional | Content type of the file. Defaults to `audio/wav`. One of: `audio/wav`, `audio/wave`, `audio/x-wav`, `audio/mpeg`, `audio/mp3`, `audio/ogg`, `audio/flac`, `audio/aac`, `audio/m4a`, `audio/mp4`, `audio/x-m4a`, `audio/aiff`, `audio/x-aiff`, `audio/webm`, `audio/opus`, `audio/x-opus+ogg`, `video/mp4`, `video/quicktime`. |
| filenamebody | string | Optional | Name to show for the file, at most 255 characters. Path separators and control characters are removed. |
| duration_secondsbody | number | Optional | Length of the audio in seconds, if you know it. Display only: it is never used for billing. Values outside 0 to 86400 are ignored. |
Response fields
| Field | Type | Description |
|---|---|---|
| upload_url | string | Where to `PUT` the file bytes. Opaque; use it as returned. |
| file_id | string | Identifier of the new file. |
| key | string | Storage path of the file inside your account. |
| expires_in | integer | Seconds `upload_url` stays valid: 900. Allowed: -9007199254740991 to 9007199254740991. |
| content_type | string | The content type to send with the `PUT`. |
| filename | string | |
| direct | boolean | `true` when `upload_url` goes straight to storage; `false` when it points back at this API. |
| media_url | string | Permanent address of the file once uploaded. Use it to refer to the file in other requests. |
| playback_url | string | Signed address for playing the file in a browser; it expires, `media_url` does not. |
| audio_id | string | null | Library identifier of the file, used to attach it as a version of another file. `null` if it could not be computed. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | missing_content_length | No positive `content_length`, or a content type that is not one of the accepted ones. |
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 413 | file_too_large | The declared size is over the per-file limit, or the file does not fit in your storage (`storage_quota_exceeded`). |
| 429 | rate_limit_exceeded | Over the account request budget. Wait for the `Retry-After` header, then retry. |
| 503 | upload_unavailable | The upload could not be registered; nothing was reserved. Retry shortly. |
Example responses
{
"data": {
"upload_url": "https://storage.example.com/uploads/3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav?signature=…",
"file_id": "3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b",
"key": "00000000-0000-4000-8000-000000000001/audio/3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav",
"expires_in": 900,
"content_type": "audio/wav",
"filename": "morning-session.wav",
"direct": true,
"media_url": "https://api.scarleta.ai/v1/audio/media/3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav",
"playback_url": "https://api.scarleta.ai/v1/audio/media/3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav?exp=1792557639&sig=9f2c1d4e8a7b6c5d",
"audio_id": "audio_bbb14949dc19"
}
}- 200 Upload prepared. The body is `{ data }` without `meta`.
- 400 No positive `content_length`, or a content type that is not one of the accepted ones.
- 401 Missing, malformed, unknown or revoked API key.
- 413 The declared size is over the per-file limit, or the file does not fit in your storage (`storage_quota_exceeded`).
- 429 Over the account request budget. Wait for the `Retry-After` header, then retry.
- 503 The upload could not be registered; nothing was reserved. 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, invalid_auth_format, invalid_content_type, invalid_key_format, missing_api_key, missing_auth, rate_limit_unavailable, storage_quota_exceeded, unauthorized.
PUT/v1/audio/upload/{fileId}Upload file bytes through the API
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Fallback target of a presigned upload. When the upload URL from the presigned upload route has direct: false, it points here: it already carries the one-time t token, so call it exactly as returned, with the file bytes as the request body and the Content-Type you declared. There is no API key on this route; the token is the credential, it works once, and a URL that is expired, used or wrong gets 403 invalid_upload_intent.
The body is read in one piece, so the limit is 100 MiB for audio. The bytes are checked: a file that is not valid audio is refused with 400 invalid_file_signature. Uploads are limited to 30 per hour per source address. Most accounts receive direct: true URLs and never call this route.
Cost. Free of charge.
FILEID="YOUR_FILEID"
curl -X PUT "https://api.scarleta.ai/v1/audio/upload/$FILEID" \
-H "Authorization: Bearer $SCARLETA_API_KEY" \
-H "Content-Type: audio/wav" \
--data-binary @./recording.wavParameters
| Name | Type | Required | Description |
|---|---|---|---|
| fileIdpath | string | Required | The `file_id` of one of your files, as returned by the upload routes and the file list. A trailing media extension such as `.wav` is ignored. |
| tquery | string | Optional | One-time upload token. Already part of the `upload_url` that points here; leave it as returned. |
Response fields
| Field | Type | Description |
|---|---|---|
| file_id | string | Identifier of the file. |
| key | string | Storage path of the file inside your account. |
| status | "uploaded" | |
| uploaded_at | string | ISO 8601 timestamp. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | invalid_file_signature | The body is empty, the content type is not accepted, or the file is not audio. |
| 403 | invalid_upload_intent | The URL has expired, was already used, or the token is missing or wrong. |
| 413 | file_too_large | The body is larger than this route accepts. |
| 429 | rate_limit_exceeded | Over the account request budget. Wait for the `Retry-After` header, then retry. |
Example responses
{
"data": {
"file_id": "3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b",
"key": "00000000-0000-4000-8000-000000000001/audio/3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav",
"status": "uploaded",
"uploaded_at": "2026-10-20T11:53:45.938Z"
}
}- 201 The file is stored. The body is `{ data }` without `meta`.
- 400 The body is empty, the content type is not accepted, or the file is not audio.
- 403 The URL has expired, was already used, or the token is missing or wrong.
- 413 The body is larger than this route accepts.
- 429 Over the account request budget. Wait for the `Retry-After` header, then retry.
Try it
This operation uploads a file or binary body, which a browser form cannot build. Use the cURL sample.
Other error codes this operation can return: invalid_content_type, missing_body, rate_limit_unavailable.
POST/v1/uploadUpload a file for one-off use
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Uploads one audio file in a single request and returns a public url you can pass as audio_url to the analysis routes. Send multipart/form-data with the audio in the file part. Audio only: video is refused here, use the presigned upload route instead. The bytes are checked, not the declared type: a file that is not valid audio is refused with 400 invalid_file_signature. The body is read in one piece, so the limit is 100 MiB; larger files, and anything you want to keep in your library, go through the presigned upload route or an upload session.
The file is temporary: it is removed 24 hours after upload. While it exists its size counts toward your storage. url never expires within that time and is the value to use as an audio_url; playback_url is a signed copy for playing the file in a browser and stops working sooner.
This route answers with a bare JSON object: there is no data wrapper, no meta on a success. Uploads are limited to 30 per hour per account and per source address. Available to free and paid accounts.
Cost. Free of charge; the file counts toward your storage while it exists.
curl -X POST "https://api.scarleta.ai/v1/upload" \
-H "Authorization: Bearer $SCARLETA_API_KEY" \
-F "file=@./recording.wav;type=audio/wav"Request body
| Name | Type | Required | Description |
|---|---|---|---|
| filebody | string | Required | The audio file, at most 100 MiB. |
Response fields
| Field | Type | Description |
|---|---|---|
| success | true | |
| url | string | Public URL of the stored file. Pass it as `audio_url`. It does not expire while the file exists. |
| playback_url | string | Signed variant of `url` for playing the file in a browser; it expires sooner than the file does. |
| file_id | string | Identifier of the stored file. |
| filename | string | Name the file is stored under. |
| size | integer | Size in bytes. Allowed: -9007199254740991 to 9007199254740991. |
| content_type | string | Content type the upload declared, or `application/octet-stream`. |
| expires_in | integer | Seconds the file is kept: 86400. Allowed: -9007199254740991 to 9007199254740991. |
| expires_at | string | When the file is removed, as an ISO 8601 timestamp. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | invalid_file_signature | The request is not `multipart/form-data`, has no `file` part, or the file is not audio (checked by its bytes, not its declared type), or is a video. |
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 413 | file_too_large | The file is larger than 100 MiB. |
| 429 | rate_limit_exceeded | Over the account request budget. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"success": true,
"url": "https://api.scarleta.ai/audio-cache/temp-3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav",
"playback_url": "https://api.scarleta.ai/audio-cache/temp-3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav?exp=1792557639&sig=9f2c1d4e8a7b6c5d",
"file_id": "3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b",
"filename": "temp-3f2b8c1e-5d4a-4e6f-9a7b-1c2d3e4f5a6b.wav",
"size": 176478,
"content_type": "audio/wav",
"expires_in": 86400,
"expires_at": "2026-10-22T03:40:39.370Z"
}- 200 The file is stored. The body is the bare object shown, without a `data` wrapper.
- 400 The request is not `multipart/form-data`, has no `file` part, or the file is not audio (checked by its bytes, not its declared type), or is a video.
- 401 Missing, malformed, unknown or revoked API key.
- 413 The file is larger than 100 MiB.
- 429 Over the account request budget. Wait for the `Retry-After` header, then retry.
- 503 Temporary platform condition; retry shortly.
Try it
This operation uploads a file or binary body, which a browser form cannot build. Use the cURL sample.
Other error codes this operation can return: invalid_auth_format, invalid_content_type, invalid_file_type, invalid_form_data, invalid_key_format, missing_api_key, missing_auth, missing_file, rate_limit_unavailable, unauthorized, video_not_supported_here.