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/audio

List 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

NameTypeRequiredDescription
limitqueryintegerOptionalFiles 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.
cursorquerystringOptionalThe `pagination.cursor` of the previous page. Opaque.
Response fields
FieldTypeDescription
filesarray<object>
files[].file_idstringIdentifier of the file.
files[].keystringStorage path of the file inside your account.
files[].sizeintegerSize in bytes. Allowed: -9007199254740991 to 9007199254740991.
files[].size_mbstringSize in mebibytes with two decimals.
files[].uploadedstringWhen the file was stored, as an ISO 8601 timestamp.
paginationobject
pagination.limitintegerThe page size used. Allowed: -9007199254740991 to 9007199254740991.
pagination.cursorstringPass as `cursor` to get the next page. Absent on the last page.
pagination.has_moreboolean
Errors
StatusCodeDescription
401invalid_keyMissing, malformed, unknown or revoked API key.
429rate_limit_exceededOver the account request budget. Wait for the `Retry-After` header, then retry.
503auth_unavailableTemporary 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

NameTypeRequiredDescription
fileIdpathstringRequiredThe `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
FieldTypeDescription
file_idstringIdentifier of the file.
status"trashed"
trashed_atstringWhen the file was moved to the trash, as an ISO 8601 timestamp.
purge_afterstringWhen the file is removed for good, as an ISO 8601 timestamp.
Errors
StatusCodeDescription
401invalid_keyMissing, malformed, unknown or revoked API key.
404file_not_foundNo file with this id in your account, or it is already in the trash.
429rate_limit_exceededOver the account request budget. Wait for the `Retry-After` header, then retry.
503auth_unavailableTemporary 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-url

Create 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

NameTypeRequiredDescription
fileIdpathstringRequiredThe `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

NameTypeRequiredDescription
expires_inbodyintegerOptionalSeconds the link stays valid, 60 to 86400. Defaults to 3600.
filenamebodystringOptionalFile name for the download, at most 200 characters.
Response fields
FieldTypeDescription
download_urlstringAddress to `GET` the file from. Works once.
file_idstringIdentifier of the file.
expires_inintegerSeconds the link stays valid. Allowed: -9007199254740991 to 9007199254740991.
Errors
StatusCodeDescription
400invalid_expires_in`expires_in` is not an integer in range.
401invalid_keyMissing, malformed, unknown or revoked API key.
404file_not_foundNo file with this id in your account.
413file_too_largeThe stored file is over the size limit and cannot be linked.
415invalid_audio_fileThe stored file is not audio and cannot be linked.
429rate_limit_exceededOver the account request budget. Wait for the `Retry-After` header, then retry.
503auth_unavailableTemporary 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-usage

Get 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
FieldTypeDescription
used_bytesintegerBytes your files use. Allowed: -9007199254740991 to 9007199254740991.
cap_bytesintegerBytes of storage included with the account. Allowed: -9007199254740991 to 9007199254740991.
tier"free" | "paid"The account tier the figures are for.
Errors
StatusCodeDescription
401invalid_keyMissing, malformed, unknown or revoked API key.
429rate_limit_exceededOver the account request budget. Wait for the `Retry-After` header, then retry.
503auth_unavailableTemporary 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-url

Get 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

NameTypeRequiredDescription
content_lengthbodyintegerRequiredSize 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_typebodystringOptionalContent 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`.
filenamebodystringOptionalName to show for the file, at most 255 characters. Path separators and control characters are removed.
duration_secondsbodynumberOptionalLength 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
FieldTypeDescription
upload_urlstringWhere to `PUT` the file bytes. Opaque; use it as returned.
file_idstringIdentifier of the new file.
keystringStorage path of the file inside your account.
expires_inintegerSeconds `upload_url` stays valid: 900. Allowed: -9007199254740991 to 9007199254740991.
content_typestringThe content type to send with the `PUT`.
filenamestring
directboolean`true` when `upload_url` goes straight to storage; `false` when it points back at this API.
media_urlstringPermanent address of the file once uploaded. Use it to refer to the file in other requests.
playback_urlstringSigned address for playing the file in a browser; it expires, `media_url` does not.
audio_idstring | nullLibrary identifier of the file, used to attach it as a version of another file. `null` if it could not be computed.
Errors
StatusCodeDescription
400missing_content_lengthNo positive `content_length`, or a content type that is not one of the accepted ones.
401invalid_keyMissing, malformed, unknown or revoked API key.
413file_too_largeThe declared size is over the per-file limit, or the file does not fit in your storage (`storage_quota_exceeded`).
429rate_limit_exceededOver the account request budget. Wait for the `Retry-After` header, then retry.
503upload_unavailableThe 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.wav

Parameters

NameTypeRequiredDescription
fileIdpathstringRequiredThe `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.
tquerystringOptionalOne-time upload token. Already part of the `upload_url` that points here; leave it as returned.
Response fields
FieldTypeDescription
file_idstringIdentifier of the file.
keystringStorage path of the file inside your account.
status"uploaded"
uploaded_atstringISO 8601 timestamp.
Errors
StatusCodeDescription
400invalid_file_signatureThe body is empty, the content type is not accepted, or the file is not audio.
403invalid_upload_intentThe URL has expired, was already used, or the token is missing or wrong.
413file_too_largeThe body is larger than this route accepts.
429rate_limit_exceededOver 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/upload

Upload 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

NameTypeRequiredDescription
filebodystringRequiredThe audio file, at most 100 MiB.
Response fields
FieldTypeDescription
successtrue
urlstringPublic URL of the stored file. Pass it as `audio_url`. It does not expire while the file exists.
playback_urlstringSigned variant of `url` for playing the file in a browser; it expires sooner than the file does.
file_idstringIdentifier of the stored file.
filenamestringName the file is stored under.
sizeintegerSize in bytes. Allowed: -9007199254740991 to 9007199254740991.
content_typestringContent type the upload declared, or `application/octet-stream`.
expires_inintegerSeconds the file is kept: 86400. Allowed: -9007199254740991 to 9007199254740991.
expires_atstringWhen the file is removed, as an ISO 8601 timestamp.
Errors
StatusCodeDescription
400invalid_file_signatureThe 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.
401invalid_keyMissing, malformed, unknown or revoked API key.
413file_too_largeThe file is larger than 100 MiB.
429rate_limit_exceededOver the account request budget. Wait for the `Retry-After` header, then retry.
503auth_unavailableTemporary 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.