curl -X POST 'https://api.60db.ai/deep-analytics/imports/batches/9b7e6d5c-4b3a-4291-8f0e-1d2c3b4a5968/items/c1d2e3f4-a5b6-4c7d-9e8f-7a6b5c4d3e2f/upload-slot' \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"size_bytes": 1843200, "content_type": "audio/mpeg"}'
const res = await fetch('https://api.60db.ai/deep-analytics/imports/batches/9b7e6d5c-4b3a-4291-8f0e-1d2c3b4a5968/items/c1d2e3f4-a5b6-4c7d-9e8f-7a6b5c4d3e2f/upload-slot', {
method: 'POST',
headers: {
Authorization: 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"size_bytes": 1843200,
"content_type": "audio/mpeg"
}),
});
const { success, data, message, code } = await res.json();
if (!success) throw new Error(`${code}: ${message}`);
Call Analysis
Create Upload Slot
Get a signed storage form to upload one recording
POST
/
deep-analytics
/
imports
/
batches
/
:batchId
/
items
/
:itemId
/
upload-slot
curl -X POST 'https://api.60db.ai/deep-analytics/imports/batches/9b7e6d5c-4b3a-4291-8f0e-1d2c3b4a5968/items/c1d2e3f4-a5b6-4c7d-9e8f-7a6b5c4d3e2f/upload-slot' \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"size_bytes": 1843200, "content_type": "audio/mpeg"}'
const res = await fetch('https://api.60db.ai/deep-analytics/imports/batches/9b7e6d5c-4b3a-4291-8f0e-1d2c3b4a5968/items/c1d2e3f4-a5b6-4c7d-9e8f-7a6b5c4d3e2f/upload-slot', {
method: 'POST',
headers: {
Authorization: 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"size_bytes": 1843200,
"content_type": "audio/mpeg"
}),
});
const { success, data, message, code } = await res.json();
if (!success) throw new Error(`${code}: ${message}`);
For a
Storage answers
direct_upload row in state draft. Returns a short-lived form. Upload the file to upload.url yourself, then call Confirm upload. A new slot replaces an older unused one for the same row.
Needs
manage on the analyzer.Request
Headers
Path
Batch row ID (UUID). Get it from List batch rows
Body
audio/mpeg, audio/wav, audio/x-wav, audio/mp4, audio/x-m4a, audio/ogg, audio/flac or audio/webm. The file content must matchResponse
201 Created{
"success": true,
"data": {
"upload_id": "<upload-id>",
"expires_at": "2026-11-12T09:15:00Z",
"max_size_bytes": 104857600,
"content_type": "audio/mpeg",
"upload": {
"method": "POST",
"url": "https://<storage-host>/<bucket>",
"fields": {
"key": "<value>",
"policy": "<value>"
}
}
}
}
Upload the file
Send amultipart/form-data POST to upload.url. Put every entry of upload.fields first, in order, then the file as the last field, named file. Do not send your Authorization header to storage.
curl -X POST "$UPLOAD_URL" -F "key=..." -F "policy=..." -F "[email protected];type=audio/mpeg"
403 when the slot has expired and 400 when the size or type does not match what you asked for.
Errors
Errors use{ "success": false, "message": "...", "code": "..." }. See the overview for the codes every route can return.
This endpoint
| Status | Code | When |
|---|---|---|
| 400 | INVALID_UPLOAD_REQUEST | Size or type not allowed |
| 413 | ASSET_TOO_LARGE | size_bytes is over 100 MiB |
| 409 | ITEM_NOT_VALID | The row is invalid |
| 409 | ASSET_ALREADY_VERIFIED | This row already has a verified recording |
| 409 | WRONG_SOURCE_KIND | The batch is not direct_upload |
| 501 | STORAGE_NOT_CONFIGURED | Uploads are not available |
Example
curl -X POST 'https://api.60db.ai/deep-analytics/imports/batches/9b7e6d5c-4b3a-4291-8f0e-1d2c3b4a5968/items/c1d2e3f4-a5b6-4c7d-9e8f-7a6b5c4d3e2f/upload-slot' \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"size_bytes": 1843200, "content_type": "audio/mpeg"}'
const res = await fetch('https://api.60db.ai/deep-analytics/imports/batches/9b7e6d5c-4b3a-4291-8f0e-1d2c3b4a5968/items/c1d2e3f4-a5b6-4c7d-9e8f-7a6b5c4d3e2f/upload-slot', {
method: 'POST',
headers: {
Authorization: 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"size_bytes": 1843200,
"content_type": "audio/mpeg"
}),
});
const { success, data, message, code } = await res.json();
if (!success) throw new Error(`${code}: ${message}`);