What is a submission?
A submission is a container for one or more media assets that you want to process. When you create a submission, the API queues the assets for processing and begins analysis.
Each submission has:
- A unique
submissionId for tracking and polling
- A workspace context (derived from your API key)
- One or more assets to process
- A lifecycle status (
uploading, submitted, processing, complete, failed)
Submission lifecycle
States explained
| Status | Meaning | Next step |
|---|
uploading | Assets are being uploaded to blob storage | Finish uploads, then create the submission |
submitted | Submission registered, queued for processing | Wait for processing to begin |
processing | Workflows are actively analyzing assets | Poll for completion |
complete | All assets successfully analyzed | Retrieve results |
failed | One or more assets failed to process | Check error details and retry if retryable |
Terminal states for polling are complete and failed.
Creating a submission
POST /api/integrations/submissions
Each asset object needs a blobPath. The optional previousSubmissionId links an asset to a prior submission for versioning. The submission-level sidekickIds (a list of UUIDs) is required — at least one sidekick must run, or there is nothing to check; an empty or omitted list is rejected with 422. Each asset may also carry its own sidekickIds (a subset of the submission-level set) to run only those sidekicks on that asset; an empty per-asset list inherits the full set. You may also pass a free-form metadata object. To label assets or give the review extra material to work with, attach tags and contextItems — see Tags and supporting context.
{
"assets": [
{ "blobPath": "<workspace-id>/campaign-video.mp4" }
],
"sidekickIds": ["<sidekick-id>"],
"metadata": { "campaign": "spring-2026" }
}
Response 201 Created:
{
"submissionId": "550e8400-e29b-41d4-a716-446655440000",
"workflowId": "asset-processing-...",
"ablyChannel": "submission:550e8400-...",
"status": "submitted",
"assets": [
{ "assetId": "a1b2...", "versionGroupId": "g1...", "versionNumber": 1 }
]
}
The submission identifier is submissionId, not id.
Tags and supporting context
Beyond the assets themselves, a submission can carry two optional, top-level kinds of extra input:
- Tags — key/value labels applied to assets (e.g.
Campaign: Summer). Tags are referenced by key/value, not by id: the matching workspace tag is found-or-created automatically, so you never need to pre-create tags or look up their UUIDs.
- Context items — supporting files or links that give the compliance review more to work with (substantiation documents, brand guidelines, transcripts, legal copy, and so on). A context file is uploaded exactly like an asset (see the File upload guide) and referenced by its
blobPath; a context link carries an external url instead.
applyTo
Every tag and context item has an applyTo field that selects which assets it attaches to:
"all" (the default) — every asset in the submission.
- a list of asset blobPaths — only the listed assets.
Example
{
"assets": [
{ "blobPath": "<workspace-id>/campaign-video.mp4" }
],
"tags": [
{ "key": "Campaign", "value": "Summer", "applyTo": "all" }
],
"contextItems": [
{
"kind": "file",
"contextType": "substantiation",
"blobPath": "<workspace-id>/evidence.pdf",
"name": "evidence.pdf",
"mimeType": "application/pdf",
"applyTo": "all"
},
{
"kind": "link",
"contextType": "legal",
"url": "https://example.com/brand-guidelines",
"linkName": "Brand guidelines",
"applyTo": "all"
}
]
}
contextType must be one of: substantiation, product_info, brand_guidelines_evidence, legal, transcript_script, talent_licensing, brand_guidelines_publishing, platform_metadata, other.
Tags are echoed back on each asset in the status response; both tags and context items are returned on the asset result.
Checking submission status
GET /api/integrations/submissions/{submission_id}
Returns the current state of the submission and all of its assets. There is no /status suffix.
{
"submissionId": "550e8400-...",
"workflowId": "asset-processing-...",
"workspaceId": "660e8400-...",
"status": "processing",
"progressPercent": 40,
"createdAt": "2026-06-03T12:00:00Z",
"completedAt": null,
"errorMessage": null,
"assets": [
{
"assetId": "a1b2...",
"versionGroupId": "g1...",
"versionNumber": 1,
"issueCount": null,
"errorMessage": null,
"errorType": null,
"isRetryable": false,
"retryCount": 0
}
],
"isRetryable": false
}
Use progressPercent to track progress. A 404 is returned if the submission does not exist in the authenticated workspace. Each asset object also carries a tags array ([{ "key": "...", "value": "..." }]) reflecting any tags applied at submit time.
Polling recommendations
Poll GET /api/integrations/submissions/{submission_id} every few seconds and back off over time. Stop polling once the top-level status is complete or failed.
For large-scale operations, prefer webhooks over tight polling — they are more efficient and deliver near real-time updates.
Multiple assets per submission
You can submit multiple assets in a single submission. Batching assets into one submission is also the recommended way to stay within rate limits.
{
"assets": [
{ "blobPath": "<workspace-id>/video1.mp4" },
{ "blobPath": "<workspace-id>/video2.mp4" },
{ "blobPath": "<workspace-id>/doc.pdf" }
],
"sidekickIds": ["<sidekick-id>"],
"metadata": {}
}
Each asset is processed independently and has its own per-asset status fields.
Error handling
If an asset fails, its failure details appear as flat fields on the asset object in the status response — there is no nested error object.
{
"submissionId": "550e8400-...",
"status": "failed",
"assets": [
{
"assetId": "a1b2...",
"versionGroupId": "g1...",
"versionNumber": 1,
"issueCount": null,
"errorMessage": "Source media could not be decoded.",
"errorType": "unsupported_codec",
"isRetryable": true,
"retryCount": 0
}
],
"isRetryable": true
}
When isRetryable is true, you can retry the asset:
POST /api/integrations/submissions/{submission_id}/assets/{asset_id}/retry
This returns 202 Accepted with the same shape as creating a submission. A 409 is returned if the asset is not in a failed state, the error is not retryable, the maximum attempts have been reached, or a retry is already in flight.
See Error codes for the full list of status codes and error envelopes.
Versioning and resubmission
To create a new version of an asset, create a new submission whose asset references the original via previousSubmissionId. Each version is tracked by versionGroupId and versionNumber. List all versions with:
GET /api/integrations/submissions/{submission_id}/versions
See Assets for details.