API reference
Library
6 operations. Base URL https://api.scarleta.ai. Select an operation to see its parameters, samples and errors.
Jump to an operation
GET/v1/audio/libraryList the library
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Lists your files grouped into tracks, newest first by default. A track holds one file, or several versions of the same song that you grouped. Each version includes the analyses it already has, plus its tags and archive state. Only your own files are ever returned.
Page with limit and cursor: pass pagination.cursor from one response as cursor in the next while pagination.has_more is true. limit is 1 to 200. The analysis results make responses large; send include_summaries=false to receive only the category names. With summaries, an array inside a summary object that holds more than 2048 values in total (counting every number or string, also inside nested arrays, such as an embedding or a spectrogram; each record of a list of records counts as one, plus any array inside it) is left out of the list, and its path is named in the summary's omitted_large_arrays. A summary that is itself an array is returned whole. GET /v1/audio/:audioId/analyses returns the complete summary.
View mode. Send view (a saved view id) and/or q (a view definition as base64url JSON, {"version":2,"filters":{...}}) and the route reads the library through that view instead. The response then carries the standard { data, meta } envelope with an X-Request-ID header, data also has total_tracks, coverage and view, tracks have hidden_versions and group_keys, versions have values, details, starred and duration_seconds, and limit is at most 100. An unknown view is 404 view_not_found; an invalid q is 400 invalid_config; grouping by sound before building sound groups is 400 invalid_group.
Without view and q the route answers with the older body shape: success is { data } with no meta, errors for bad query values are { error, message }, and the older bodies have no request_id of their own.
Cost. Free of charge.
curl "https://api.scarleta.ai/v1/audio/library" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limitquery | integer | Optional | Tracks per page, 1 to 200 (at most 100 in view mode). |
| cursorquery | string | Optional | The `pagination.cursor` of the previous page. |
| sort_keyquery | "uploaded" | "name" | "size" | "last_activity" | "tags" | Optional | What to sort by. Defaults to `uploaded`. |
| sort_dirquery | "asc" | "desc" | Optional | Sort direction. Defaults to `desc`. |
| filter_tagsquery | string | Optional | Comma-separated tags to keep, at most 25. |
| filter_analysis_typequery | string | Optional | Keep files that have this analysis category. |
| filter_date_fromquery | number | Optional | Keep files uploaded at or after this time, in milliseconds since the Unix epoch. |
| filter_date_toquery | number | Optional | Keep files uploaded at or before this time, in milliseconds since the Unix epoch. |
| filter_archivedquery | "true" | Optional | `true` returns only archived files. Archived files are hidden otherwise. |
| viewquery | string | Optional | Id of one of your saved views. Switches the route to view mode; see the description. |
| qquery | string | Optional | A view definition, JSON encoded as base64url. Switches the route to view mode; see the description. |
| include_summariesquery | "true" | "false" | Optional | `false` leaves out the stored analysis results and keeps only the category names. Defaults to `true`. |
Response fields
| Field | Type | Description |
|---|---|---|
| storage | object | |
| storage.used_bytes | number | Bytes your files currently use. |
| storage.cap_bytes | number | The storage allowance shown for the account, in bytes. |
| storage.tier | "free" | "paid" | Whether the account is on the free or the paid tier. |
| storage.past_due | boolean | True when the account has an unpaid storage overage. |
| storage.enforced | boolean | True when storage locks are actually applied. |
| tracks | array<object> | |
| tracks[].id | string | Track identifier. |
| tracks[].name | string | Name of the newest version. |
| tracks[].versions | array<object> | Versions of the track, newest first. |
| tracks[].versions[].id | string | Identifier of this version of the track. Use it wherever a route asks for a file id. |
| tracks[].versions[].audio_id | string | Registry identifier of the file; it starts with `audio_`. |
| tracks[].versions[].name | string | Display name of the file. |
| tracks[].versions[].label | string | Short label shown for this version. |
| tracks[].versions[].uploaded | number | null | When the file was uploaded, in milliseconds since the Unix epoch. |
| tracks[].versions[].file_size_bytes | number | null | Size of the stored file in bytes, when known. |
| tracks[].versions[].format | string | null | File format, for example `wav`, when known. |
| tracks[].versions[].download_available | boolean | True when the original file is stored and can be downloaded. |
| tracks[].versions[].audio_url | string | null | URL to pass as `audio_url` when running an analysis on this file. Null when the original is not stored. |
| tracks[].versions[].playback_url | string | null | Short-lived URL for playing the file in a browser. Null when `audio_url` is null. |
| tracks[].versions[].analyses | array<object> | The analyses this file already has. |
| tracks[].versions[].locked | boolean | True when the file is locked because of an unpaid storage overage. Locked files stay listed. |
| tracks[].versions[].pending_categories | array<string> | Analysis categories still running on this file. |
| tracks[].versions[].failed_categories | array<string> | Analysis categories that failed and have no completed result. |
| tracks[].versions[].tags | array<string> | Tags you added to this file. |
| tracks[].versions[].is_best | boolean | True when this version is marked as the best take of its track. |
| tracks[].versions[].archived_at | string | number | null | When the file was archived, or null. |
| tracks[].versions[].last_activity | number | null | The latest of upload time, newest analysis result and newest note, in milliseconds since the Unix epoch. |
| tracks[].versions[].duration_seconds | number | null | Length of the audio. Present only when you send `view` or `q`. |
| tracks[].versions[].values | object | The searchable values of this file (`bpm`, `key_label`, ...) with `bpm_source` and `key_source`. Present only when you send `view` or `q`. |
| tracks[].versions[].details | object | File details such as title, artist and trash times. Present only when you send `view` or `q`. |
| tracks[].versions[].starred | boolean | True when the file is starred. Present only when you send `view` or `q`. |
| tracks[].versions[].similarity | number | null | Similarity to a `sounds_like` reference. Present only with that filter. |
| tracks[].hidden_versions | integer | Versions the view hides. View mode only. Allowed: -9007199254740991 to 9007199254740991. |
| tracks[].group_keys | array<string> | The group buckets of the track. View mode only. |
| pagination | object | |
| pagination.limit | integer | null | The page size used, or null when you sent no `limit`. Allowed: -9007199254740991 to 9007199254740991. |
| pagination.cursor | string | null | Pass this as `cursor` to get the next page. |
| pagination.has_more | boolean | |
| total_tracks | integer | Tracks the view matches. View mode only. Allowed: -9007199254740991 to 9007199254740991. |
| coverage | object | How many files have each searchable value. View mode only. |
| coverage.total_library_size | integer | Files in scope before any value filter. Allowed: -9007199254740991 to 9007199254740991. |
| coverage.indexed | object | For each searchable value (`bpm`, `key_label`, ...), how many files in scope have it. |
| view | object | The view that was applied. View mode only. |
| view.id | string | null | |
| view.name | string | null | |
| view.definition | object | |
| view.dropped | array<string> |
Errors
| Status | Code | Description |
|---|---|---|
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 404 | view_not_found | View mode: the saved view does not exist or is not yours. |
| 429 | rate_limit_exceeded | Over the account request budget or the per-minute cap of this route. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"storage": {
"used_bytes": 184220160,
"cap_bytes": 1099511627776,
"tier": "paid",
"past_due": false,
"enforced": true
},
"tracks": [
{
"id": "audio_3f9c1a7d2b60",
"name": "demo-mix.wav",
"versions": [
{
"id": "audio_3f9c1a7d2b60",
"audio_id": "audio_3f9c1a7d2b60",
"name": "demo-mix.wav",
"label": "demo-mix.wav",
"uploaded": 1791333870854,
"file_size_bytes": 5290044,
"format": "wav",
"download_available": true,
"audio_url": "https://api.scarleta.ai/v1/audio/media/9b2c7d1e-5a40-4f83-b6c9-0d1e2f3a4b5c.wav",
"playback_url": null,
"analyses": [
{
"category": "rhythm"
}
],
"locked": false,
"pending_categories": [],
"failed_categories": [],
"tags": [
"demo"
],
"is_best": false,
"archived_at": null,
"last_activity": 1791333870854
}
]
}
],
"pagination": {
"limit": 25,
"cursor": "1791333870854_audio_3f9c1a7d2b60",
"has_more": false
}
}
}- 200 A page of tracks. Without `view` and `q` this response has no `meta`.
- 400 A query value is not allowed: `limit` out of range, an unsupported `sort_key` or `sort_dir`, or too many `filter_tags` (body `{ error, message }`); in view mode, an invalid `q`, `view` or `group`, or a `limit` above the view cap (standard error body).
- 401 Missing, malformed, unknown or revoked API key.
- 404 View mode: the saved view does not exist or is not yours.
- 429 Over the account request budget or the per-minute cap of this route. 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_config, invalid_group, invalid_key_format, invalid_limit, invalid_sort_dir, invalid_sort_key, missing_api_key, missing_auth, rate_limit_unavailable, too_many_filter_tags, unauthorized.
POST/v1/audio/library/batchRun a recipe on a set of library files
Paid accounts onlyUses tokens
- API key required
- Paid accounts only
- Uses tokens
Runs one recipe on every library file that matches a saved view (view_id) or a set of filters, as a batch. Send exactly one of the two. Batches are available on paid accounts only; a free-account key receives 403 batch_paid_only.
Send dry_run: true first: it changes nothing, charges nothing, and returns how many files matched and what the run would cost. Without dry_run the run starts and the call returns 202 with a batch_id; follow it with the batch routes. At most 500 files may match (max_items can lower that); a bigger match is refused with 422 query_result_too_large and an empty match with 422 query_result_empty. A real run is charged and rate limited exactly like a batch submit; see the Batch reference for the cost rule.
Cost. A dry run is free. A real run is charged per file when its run finishes, like a batch submit. Use `dry_run` to see the estimate first.
curl -X POST "https://api.scarleta.ai/v1/audio/library/batch" \
-H "Authorization: Bearer $SCARLETA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipe_id": "rec_1005_cat_spectral",
"filters": {
"analyzed": [
"rhythm"
],
"name_contains": "demo"
},
"max_items": 20,
"dry_run": true
}'Request body
| Name | Type | Required | Description |
|---|---|---|---|
| recipe_idbody | string | Required | The recipe to run on every matched file. Allowed: at least 1 character. |
| view_idbody | string | Optional | Id of one of your saved views. Send this or `filters`, not both. |
| filtersbody | object | Optional | Which files to keep. Every field you send narrows the result; an empty object keeps every file. An unknown field is refused with 400 `invalid_filter`. |
| filters.bpmbody | object | object | Optional | Tempo range `{min, max}`, or `{near, tolerance}` (tolerance defaults to 3). |
| filters.bpm.minbody | number | Optional | |
| filters.bpm.maxbody | number | Optional | |
| filters.bpm.nearbody | number | Optional | |
| filters.bpm.tolerancebody | number | Optional | |
| filters.tempo_stabilitybody | object | Optional | |
| filters.tempo_stability.minbody | number | Optional | |
| filters.tempo_stability.maxbody | number | Optional | |
| filters.loudness_integratedbody | object | Optional | |
| filters.loudness_integrated.minbody | number | Optional | |
| filters.loudness_integrated.maxbody | number | Optional | |
| filters.loudness_rangebody | object | Optional | |
| filters.loudness_range.minbody | number | Optional | |
| filters.loudness_range.maxbody | number | Optional | |
| filters.true_peak_dbfsbody | object | Optional | |
| filters.true_peak_dbfs.minbody | number | Optional | |
| filters.true_peak_dbfs.maxbody | number | Optional | |
| filters.pitch_lowest_midibody | object | Optional | |
| filters.pitch_lowest_midi.minbody | number | Optional | |
| filters.pitch_lowest_midi.maxbody | number | Optional | |
| filters.pitch_highest_midibody | object | Optional | |
| filters.pitch_highest_midi.minbody | number | Optional | |
| filters.pitch_highest_midi.maxbody | number | Optional | |
| filters.notes_per_secondbody | object | Optional | |
| filters.notes_per_second.minbody | number | Optional | |
| filters.notes_per_second.maxbody | number | Optional | |
| filters.duration_secondsbody | object | Optional | |
| filters.duration_seconds.minbody | number | Optional | |
| filters.duration_seconds.maxbody | number | Optional | |
| filters.key_labelbody | string | array<string> | Optional | One key name or a list, for example `A minor`. |
| filters.key_rootbody | string | array<string> | Optional | |
| filters.key_modebody | "major" | "minor" | Optional | |
| filters.meterbody | string | array<string> | Optional | One time signature or a list, for example `4/4`. |
| filters.speech_languagebody | string | array<string> | Optional | |
| filters.formatbody | array<string> | Optional | File formats to keep, for example `["wav", "mp3"]`. |
| filters.transcript_containsbody | string | Optional | Keep files whose transcript contains this text. |
| filters.sound_descriptionbody | string | Optional | |
| filters.name_containsbody | string | Optional | Keep files whose name contains this text. |
| filters.user_tagsbody | object | Optional | Tag rules: keep files with any, with all, or with none of the listed tags. |
| filters.user_tags.anybody | array<string> | Optional | |
| filters.user_tags.allbody | array<string> | Optional | |
| filters.user_tags.nonebody | array<string> | Optional | |
| filters.auto_tagsbody | array<string> | Optional | |
| filters.analyzedbody | array<string> | Optional | Keep files that have results for every listed analysis category. |
| filters.analyzed_anybody | array<string> | Optional | Keep files that have results for at least one listed category. |
| filters.not_analyzedbody | boolean | Optional | True keeps only files with no analysis results. |
| filters.missingbody | array<string> | Optional | Keep files that lack a value, for example `["bpm"]`. |
| filters.uploaded_afterbody | number | Optional | Milliseconds since the Unix epoch. |
| filters.uploaded_beforebody | number | Optional | Milliseconds since the Unix epoch. |
| filters.starredbody | boolean | Optional | |
| filters.archivedbody | "hide" | "include" | "only" | Optional | Archived files: hidden (default), included, or the only ones shown. |
| filters.include_derivedbody | boolean | Optional | True also returns files made from other files, such as stems. |
| filters.sounds_likebody | object | Optional | Keep files that sound like the given file. |
| filters.sounds_like.audio_idbody | string | Required | |
| filters.sounds_like.min_scorebody | number | Optional | |
| filters.sound_groupbody | object | Optional | Keep the files of one sound group from a grouping job. |
| filters.sound_group.job_idbody | string | Required | |
| filters.sound_group.group_idbody | integer | Required | Allowed: -9007199254740991 to 9007199254740991. |
| filters.trashbody | "hide" | "include" | "only" | Optional | Trashed files: hidden (default), included, or the only ones shown. |
| filters.duplicatesbody | boolean | Optional | True keeps only files that have an identical copy. |
| filters.artistbody | array<string> | Optional | |
| filters.projectbody | array<string> | Optional | |
| filters.albumbody | array<string> | Optional | |
| filters.title_containsbody | string | Optional | |
| filters.credits_containsbody | string | Optional | |
| max_itemsbody | integer | Optional | Refuse the run when more files than this match. 1 to 500; defaults to 500. |
| dry_runbody | boolean | Optional | True returns the estimate and starts nothing. Defaults to false. |
| namebody | string | Optional | A label for the batch (real runs only). |
| webhook_urlbody | string | Optional | Where to POST the `batch_completed` event (real runs only). At most 4096 bytes. |
| metadatabody | object | Optional | Free-form JSON kept with the batch (real runs only), at most 8192 bytes when serialized. |
Response fields
| Field | Type | Description |
|---|---|---|
| matched_count | integer | Files the view or filters matched. Allowed: -9007199254740991 to 9007199254740991. |
| recipe_id | string | |
| total_cost | number | Tokens the run would cost. |
| total_duration_seconds | number | Audio length the estimate covers, in seconds. |
| unknown_duration_count | integer | Files whose length could not be read; they add nothing to `total_cost`. Allowed: -9007199254740991 to 9007199254740991. |
| approximate | boolean | True when some lengths were reported by the uploader or unknown, so the real charge can differ. |
| per_file | array<object> | |
| per_file[].audio_id | string | |
| per_file[].audio_url | string | |
| per_file[].duration_seconds | number | null | Length of the file, or null when it could not be read. |
| per_file[].cost | number | Tokens this file would cost. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | invalid_config | The body is not a JSON object, has an unknown field, lacks `recipe_id`, names both or neither of `view_id` and `filters`, or a value such as `max_items` or `dry_run` is not valid. |
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 402 | insufficient_balance | A real run needs a token balance or auto-recharge. |
| 403 | batch_paid_only | The key belongs to a free account. |
| 404 | view_not_found | The saved view or the recipe does not exist or is not visible to your account. |
| 422 | query_result_empty | No file matches, or more than `max_items` files match. `error.details.matched_count` says how many matched. |
| 429 | rate_limit_exceeded | Over the account request budget or the per-minute cap of this route. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"matched_count": 2,
"recipe_id": "rec_1005_cat_spectral",
"total_cost": 40,
"total_duration_seconds": 7.2,
"unknown_duration_count": 0,
"approximate": false,
"per_file": [
{
"audio_id": "audio_3f9c1a7d2b60",
"audio_url": "https://api.scarleta.ai/v1/audio/media/9b2c7d1e-5a40-4f83-b6c9-0d1e2f3a4b5c.wav",
"duration_seconds": 4,
"cost": 20
},
{
"audio_id": "audio_a81e5c40d7f2",
"audio_url": "https://api.scarleta.ai/v1/audio/media/2c4e6a80-1b3d-4f57-8a9c-0e1d2c3b4a59.wav",
"duration_seconds": 3.2,
"cost": 20
}
]
},
"meta": {
"request_id": "req_0b7a3c2e-6f1d-4d9a-8e55-3a4b5c6d7e8f"
}
}- 200 Dry run: the estimate. Nothing was started.
- 202 Accepted. The batch is queued.
- 400 The body is not a JSON object, has an unknown field, lacks `recipe_id`, names both or neither of `view_id` and `filters`, or a value such as `max_items` or `dry_run` is not valid.
- 401 Missing, malformed, unknown or revoked API key.
- 402 A real run needs a token balance or auto-recharge.
- 403 The key belongs to a free account.
- 404 The saved view or the recipe does not exist or is not visible to your account.
- 422 No file matches, or more than `max_items` files match. `error.details.matched_count` says how many matched.
- 429 Over the account request budget or the per-minute cap of this route. 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_dry_run, invalid_filter, invalid_json, invalid_key_format, invalid_max_items, missing_api_key, missing_auth, missing_recipe_id, query_result_too_large, rate_limit_unavailable, recipe_not_found, unauthorized.
GET/v1/audio/library/builtin-countsCount files in the standard views
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Returns one count per standard library view: everything, recently added, starred, not yet analyzed, duplicates and trash. Use it for a quick header without paging through the library. Only your own files are ever returned.
Cost. Free of charge.
curl "https://api.scarleta.ai/v1/audio/library/builtin-counts" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Response fields
| Field | Type | Description |
|---|---|---|
| all | integer | Files in the library, not counting trash and archive. Allowed: -9007199254740991 to 9007199254740991. |
| recent_30d | integer | Files added recently; the key name states the window. Allowed: -9007199254740991 to 9007199254740991. |
| starred | integer | Starred files. Allowed: -9007199254740991 to 9007199254740991. |
| not_analyzed | integer | Files with no analysis results yet. Allowed: -9007199254740991 to 9007199254740991. |
| duplicates | integer | Files that have an identical copy. Allowed: -9007199254740991 to 9007199254740991. |
| trash | integer | Files in the trash. Allowed: -9007199254740991 to 9007199254740991. |
| library_files_total | integer | Every file in your library, including archived and derived ones, but not files in the trash. Allowed: -9007199254740991 to 9007199254740991. |
| unverified_hash_count | integer | Files whose content fingerprint has not been checked yet. Allowed: -9007199254740991 to 9007199254740991. |
Errors
| Status | Code | Description |
|---|---|---|
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 429 | rate_limit_exceeded | Over the account request budget or the per-minute cap of this route. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"all": 42,
"recent_30d": 7,
"starred": 3,
"not_analyzed": 11,
"duplicates": 2,
"trash": 1,
"library_files_total": 50,
"unverified_hash_count": 0
},
"meta": {
"request_id": "req_0b7a3c2e-6f1d-4d9a-8e55-3a4b5c6d7e8f"
}
}- 200 Success
- 401 Missing, malformed, unknown or revoked API key.
- 429 Over the account request budget or the per-minute cap of this route. 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.
GET/v1/audio/library/overviewGet a library overview
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Summarises the whole library in one call: file and track counts, how many files each analysis category covers, your most used tags, your saved views, and when sound groups were last built. Only your own files are ever returned.
Cost. Free of charge.
curl "https://api.scarleta.ai/v1/audio/library/overview" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Response fields
| Field | Type | Description |
|---|---|---|
| file_count | integer | Files in the library. Allowed: -9007199254740991 to 9007199254740991. |
| track_count | integer | Tracks in the library; versions of one song count once. Allowed: -9007199254740991 to 9007199254740991. |
| analyzed_count | integer | Files with at least one analysis result. Allowed: -9007199254740991 to 9007199254740991. |
| analyzed_by_category | object | Number of files with a result in each analysis category. |
| tags | array<object> | Your most used tags. |
| tags[].tag | string | |
| tags[].count | integer | Allowed: -9007199254740991 to 9007199254740991. |
| saved_views | array<object> | |
| saved_views[].id | string | Saved view id. |
| saved_views[].name | string | |
| sound_groups | object | null | The latest sound grouping, or null when you never built one. |
| sound_groups.count | integer | Groups found. Allowed: -9007199254740991 to 9007199254740991. |
| sound_groups.built_at | number | When the grouping finished, in milliseconds since the Unix epoch. |
Errors
| Status | Code | Description |
|---|---|---|
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 429 | rate_limit_exceeded | Over the account request budget or the per-minute cap of this route. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"file_count": 42,
"track_count": 40,
"analyzed_count": 31,
"analyzed_by_category": {
"rhythm": 22,
"spectral": 18
},
"tags": [
{
"tag": "demo",
"count": 5
}
],
"saved_views": [
{
"id": "7d2c9e1a-4b3f-4c68-9a5d-1e0f8b7c6a52",
"name": "Slow tracks"
}
],
"sound_groups": null
},
"meta": {
"request_id": "req_0b7a3c2e-6f1d-4d9a-8e55-3a4b5c6d7e8f"
}
}- 200 Success
- 401 Missing, malformed, unknown or revoked API key.
- 429 Over the account request budget or the per-minute cap of this route. 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/library/queryQuery the library
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Finds files by what the analyses found in them: tempo, key, loudness, tags, names, upload time and more. Send filters, optionally sort and limit, and read the matches from items. Only your own files are ever returned.
limit is 50 unless you send it, and at most 100. While has_more is true, send next_cursor back as cursor with the same filters and sort to get the next page. total_matches counts every match; coverage shows how many files have each searchable value, so you can tell "no match" from "not analyzed yet". Reading does not spend tokens.
Cost. Free of charge.
curl -X POST "https://api.scarleta.ai/v1/audio/library/query" \
-H "Authorization: Bearer $SCARLETA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"bpm": {
"min": 90,
"max": 130
},
"analyzed": [
"rhythm"
]
},
"sort": [
{
"key": "uploaded",
"dir": "desc"
}
],
"limit": 25
}'Request body
| Name | Type | Required | Description |
|---|---|---|---|
| filtersbody | object | Optional | Which files to keep. Every field you send narrows the result; an empty object keeps every file. An unknown field is refused with 400 `invalid_filter`. |
| filters.bpmbody | object | object | Optional | Tempo range `{min, max}`, or `{near, tolerance}` (tolerance defaults to 3). |
| filters.bpm.minbody | number | Optional | |
| filters.bpm.maxbody | number | Optional | |
| filters.bpm.nearbody | number | Optional | |
| filters.bpm.tolerancebody | number | Optional | |
| filters.tempo_stabilitybody | object | Optional | |
| filters.tempo_stability.minbody | number | Optional | |
| filters.tempo_stability.maxbody | number | Optional | |
| filters.loudness_integratedbody | object | Optional | |
| filters.loudness_integrated.minbody | number | Optional | |
| filters.loudness_integrated.maxbody | number | Optional | |
| filters.loudness_rangebody | object | Optional | |
| filters.loudness_range.minbody | number | Optional | |
| filters.loudness_range.maxbody | number | Optional | |
| filters.true_peak_dbfsbody | object | Optional | |
| filters.true_peak_dbfs.minbody | number | Optional | |
| filters.true_peak_dbfs.maxbody | number | Optional | |
| filters.pitch_lowest_midibody | object | Optional | |
| filters.pitch_lowest_midi.minbody | number | Optional | |
| filters.pitch_lowest_midi.maxbody | number | Optional | |
| filters.pitch_highest_midibody | object | Optional | |
| filters.pitch_highest_midi.minbody | number | Optional | |
| filters.pitch_highest_midi.maxbody | number | Optional | |
| filters.notes_per_secondbody | object | Optional | |
| filters.notes_per_second.minbody | number | Optional | |
| filters.notes_per_second.maxbody | number | Optional | |
| filters.duration_secondsbody | object | Optional | |
| filters.duration_seconds.minbody | number | Optional | |
| filters.duration_seconds.maxbody | number | Optional | |
| filters.key_labelbody | string | array<string> | Optional | One key name or a list, for example `A minor`. |
| filters.key_rootbody | string | array<string> | Optional | |
| filters.key_modebody | "major" | "minor" | Optional | |
| filters.meterbody | string | array<string> | Optional | One time signature or a list, for example `4/4`. |
| filters.speech_languagebody | string | array<string> | Optional | |
| filters.formatbody | array<string> | Optional | File formats to keep, for example `["wav", "mp3"]`. |
| filters.transcript_containsbody | string | Optional | Keep files whose transcript contains this text. |
| filters.sound_descriptionbody | string | Optional | |
| filters.name_containsbody | string | Optional | Keep files whose name contains this text. |
| filters.user_tagsbody | object | Optional | Tag rules: keep files with any, with all, or with none of the listed tags. |
| filters.user_tags.anybody | array<string> | Optional | |
| filters.user_tags.allbody | array<string> | Optional | |
| filters.user_tags.nonebody | array<string> | Optional | |
| filters.auto_tagsbody | array<string> | Optional | |
| filters.analyzedbody | array<string> | Optional | Keep files that have results for every listed analysis category. |
| filters.analyzed_anybody | array<string> | Optional | Keep files that have results for at least one listed category. |
| filters.not_analyzedbody | boolean | Optional | True keeps only files with no analysis results. |
| filters.missingbody | array<string> | Optional | Keep files that lack a value, for example `["bpm"]`. |
| filters.uploaded_afterbody | number | Optional | Milliseconds since the Unix epoch. |
| filters.uploaded_beforebody | number | Optional | Milliseconds since the Unix epoch. |
| filters.starredbody | boolean | Optional | |
| filters.archivedbody | "hide" | "include" | "only" | Optional | Archived files: hidden (default), included, or the only ones shown. |
| filters.include_derivedbody | boolean | Optional | True also returns files made from other files, such as stems. |
| filters.sounds_likebody | object | Optional | Keep files that sound like the given file. |
| filters.sounds_like.audio_idbody | string | Required | |
| filters.sounds_like.min_scorebody | number | Optional | |
| filters.sound_groupbody | object | Optional | Keep the files of one sound group from a grouping job. |
| filters.sound_group.job_idbody | string | Required | |
| filters.sound_group.group_idbody | integer | Required | Allowed: -9007199254740991 to 9007199254740991. |
| filters.trashbody | "hide" | "include" | "only" | Optional | Trashed files: hidden (default), included, or the only ones shown. |
| filters.duplicatesbody | boolean | Optional | True keeps only files that have an identical copy. |
| filters.artistbody | array<string> | Optional | |
| filters.projectbody | array<string> | Optional | |
| filters.albumbody | array<string> | Optional | |
| filters.title_containsbody | string | Optional | |
| filters.credits_containsbody | string | Optional | |
| sortbody | "uploaded_at_desc" | "uploaded_at_asc" | "bpm_asc" | "bpm_desc" | "loudness_asc" | "loudness_desc" | "name_asc" | array<object> | Optional | Either one of the short names (`uploaded_at_desc`, `bpm_asc`, ...) or a list of `{ key, dir }`. Defaults to newest first. |
| limitbody | integer | Optional | Matches per page, 1 to 100. Defaults to 50. |
| cursorbody | string | Optional | The `next_cursor` of the previous page. |
Response fields
| Field | Type | Description |
|---|---|---|
| items | array<object> | The matching files. |
| items[].audio_id | string | |
| items[].original_filename | string | |
| items[].display_name | string | null | |
| items[].audio_url | string | URL to pass as `audio_url` when running an analysis on this file. |
| items[].playback_url | string | null | |
| items[].duration_seconds | number | null | |
| items[].format | string | null | |
| items[].uploaded_at | number | Milliseconds since the Unix epoch. |
| items[].starred | boolean | |
| items[].user_tags | array<string> | |
| items[].analyzed_categories | array<string> | Analysis categories this file has results for. |
| items[].bpm | number | null | |
| items[].tempo_stability | number | null | |
| items[].key_label | string | null | |
| items[].key_root | string | null | |
| items[].key_mode | string | null | |
| items[].meter | string | null | |
| items[].loudness_integrated | number | null | |
| items[].loudness_range | number | null | |
| items[].true_peak_dbfs | number | null | |
| items[].pitch_lowest_midi | number | null | |
| items[].pitch_highest_midi | number | null | |
| items[].notes_per_second | number | null | |
| items[].speech_language | string | null | |
| items[].transcript_text | string | null | |
| items[].sound_description | string | null | |
| items[].auto_tags | array<string> | null | |
| items[].bpm_source | string | null | Where the tempo came from: your own value or the analysis. |
| items[].key_source | string | null | Where the key came from: your own value or the analysis. |
| items[].details | object | |
| items[].details.title | string | null | |
| items[].details.artist | string | null | |
| items[].details.album | string | null | |
| items[].details.project | string | null | |
| items[].details.credits | string | null | |
| items[].details.has_cover | boolean | True when the file has cover art. |
| items[].details.content_sha256 | string | null | Fingerprint of the file content; equal values mean identical files. |
| items[].details.trashed_at | number | null | When the file was moved to the trash, in milliseconds since the Unix epoch, or null. |
| items[].details.purge_at | number | null | When a trashed file is removed for good, or null. |
| items[].similarity | number | null | Similarity to the `sounds_like` reference. Present only when the query uses `sounds_like`. |
| count | integer | Number of items in this page. Allowed: -9007199254740991 to 9007199254740991. |
| total_matches | integer | Number of files that match the filters. Allowed: -9007199254740991 to 9007199254740991. |
| has_more | boolean | |
| next_cursor | string | null | Pass this as `cursor` to get the next page. |
| coverage | object | |
| coverage.total_library_size | integer | Files in scope before any value filter. Allowed: -9007199254740991 to 9007199254740991. |
| coverage.indexed | object | For each searchable value (`bpm`, `key_label`, ...), how many files in scope have it. |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | invalid_filter | The body is not a JSON object, has an unknown field, or a filter, sort, `limit` or `cursor` is not valid. `error.details.field` names the field. |
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 404 | audio_not_found | A `sounds_like` reference file does not exist in your library. |
| 409 | embedding_missing | The `sounds_like` reference file has no sound fingerprint yet. |
| 429 | rate_limit_exceeded | Over the account request budget or the per-minute cap of this route. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"items": [
{
"audio_id": "audio_3f9c1a7d2b60",
"original_filename": "demo-mix.wav",
"display_name": "Demo mix",
"audio_url": "https://api.scarleta.ai/v1/audio/media/9b2c7d1e-5a40-4f83-b6c9-0d1e2f3a4b5c.wav",
"playback_url": null,
"duration_seconds": 184.2,
"format": "wav",
"uploaded_at": 1791333870854,
"starred": false,
"user_tags": [
"demo"
],
"analyzed_categories": [
"rhythm"
],
"bpm": 118.5,
"tempo_stability": null,
"key_label": null,
"key_root": null,
"key_mode": null,
"meter": null,
"loudness_integrated": null,
"loudness_range": null,
"true_peak_dbfs": null,
"pitch_lowest_midi": null,
"pitch_highest_midi": null,
"notes_per_second": null,
"speech_language": null,
"transcript_text": null,
"sound_description": null,
"auto_tags": null,
"bpm_source": "analysis",
"key_source": null,
"details": {
"title": null,
"artist": null,
"album": null,
"project": null,
"credits": null,
"has_cover": false,
"content_sha256": null,
"trashed_at": null,
"purge_at": null
}
}
],
"count": 1,
"total_matches": 1,
"has_more": false,
"next_cursor": null,
"coverage": {
"total_library_size": 42,
"indexed": {
"bpm": 17,
"key_label": 9,
"meter": 12
}
}
},
"meta": {
"request_id": "req_0b7a3c2e-6f1d-4d9a-8e55-3a4b5c6d7e8f"
}
}- 200 Success
- 400 The body is not a JSON object, has an unknown field, or a filter, sort, `limit` or `cursor` is not valid. `error.details.field` names the field.
- 401 Missing, malformed, unknown or revoked API key.
- 404 A `sounds_like` reference file does not exist in your library.
- 409 The `sounds_like` reference file has no sound fingerprint yet.
- 429 Over the account request budget or the per-minute cap of this route. 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: cluster_job_not_found, db_unavailable, invalid_auth_format, invalid_config, invalid_cursor, invalid_json, invalid_key_format, invalid_limit, invalid_sort, missing_api_key, missing_auth, rate_limit_unavailable, unauthorized.
GET/v1/audio/library/view-countsCount tracks in each saved view
Free and paid accounts
- API key required
- Free and paid accounts
- No token cost
Returns an object that maps the id of each of your saved views to the number of tracks it currently matches. The object is empty when you have no saved views. Only your own files are ever returned.
Cost. Free of charge.
curl "https://api.scarleta.ai/v1/audio/library/view-counts" \
-H "Authorization: Bearer $SCARLETA_API_KEY"Errors
| Status | Code | Description |
|---|---|---|
| 401 | invalid_key | Missing, malformed, unknown or revoked API key. |
| 429 | rate_limit_exceeded | Over the account request budget or the per-minute cap of this route. Wait for the `Retry-After` header, then retry. |
| 503 | auth_unavailable | Temporary platform condition; retry shortly. |
Example responses
{
"data": {
"7d2c9e1a-4b3f-4c68-9a5d-1e0f8b7c6a52": 12
},
"meta": {
"request_id": "req_0b7a3c2e-6f1d-4d9a-8e55-3a4b5c6d7e8f"
}
}- 200 Success
- 401 Missing, malformed, unknown or revoked API key.
- 429 Over the account request budget or the per-minute cap of this route. 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.