Skip to main content

Preview the cost before submitting

Creating a submission consumes credits. To see the cost first, call POST /api/pricing/estimate with the same blobPaths you intend to submit — nothing else is needed. Do this after uploading your assets and before creating the submission — it is read-only and consumes nothing. The asset type and MIME type are derived from the blobPath server-side (the same way the submission does), and the price is computed from a metric measured on the uploaded bytes (video duration, document page count) — so the estimate matches what you are charged when you submit. The measurement is cached, so the submission that follows does not re-read the file.
Each result echoes its blobPath so you can map it back to the file you sent. The response returns the cost per file plus a totalCredits for the batch:
A file with priceable: false could not be measured (for example an unreadable PDF). It costs 0 here and is excluded from totalCredits, but it will be rejected when you create the submission — re-upload it as a readable file first.

Creating a submission

A submission is a request to process one or more uploaded assets. After creating a submission, the API queues your assets for processing. Each asset object carries blobPath (the path returned by an upload) and, optionally, previousSubmissionId for versioning and a per-asset sidekickIds list (see Choosing sidekicks below). Do not send filename or contentType in asset objects — they are not part of the schema. The other top-level fields are sidekickIds (required — see below), name (an optional display name for the submission, up to 120 characters — defaults to the first asset’s filename if omitted), metadata (an optional arbitrary object), and externalReference (an optional structured {system, ref} reference to the external work item this submission originates from). Unlike metadata, externalReference is returned on the status endpoint and echoed on the asset.processing.* webhook, so an integration can correlate the completion back without keeping its own mapping. Its system is capped at 64 characters and its ref payload must serialize to under 4 KB; exceeding either is rejected with 422.

Choosing sidekicks

sidekickIds is the submission-level list of sidekicks to run for compliance checking. At least one is required — a submission with no sidekick has nothing to check, so a request that omits sidekickIds or sends an empty list is rejected with 422. To discover which sidekicks your workspace can run — and the asset types each one accepts — call List available sidekicks and use the returned id values. An asset whose type no selected sidekick supports (e.g. a PDF paired only with a video sidekick) is rejected at submit time, so make sure each asset is covered by a sidekick that handles its type. Per-asset selection (optional). Each asset may also carry its own sidekickIds to run only a subset of the sidekicks on that asset. A per-asset list must be a subset of the submission-level sidekickIds; an empty (or omitted) per-asset list means the asset inherits the full submission-level set. Use this when different assets in one submission need different checks — keep the submission-level list as the union of every asset’s selection.
Breaking change (June 2026). sidekickIds was previously optional and accepted an empty list. It is now required with at least one entry. Clients that currently send "sidekickIds": [] must be updated to pass one or more sidekick IDs (fetch them from List available sidekicks) before upgrading.
Testing with a sandbox (sk_test_) key? The asset filename must contain a scenario marker so the sandbox knows which outcome to simulate. See the Sandbox environment guide.

Single asset submission

Multiple asset submission

Submit multiple assets in a single request for batch processing:
The two videos inherit the full submission-level set, while contract.pdf narrows its checks to just the document sidekick via its own sidekickIds. The per-asset list stays a subset of the submission-level sidekickIds.
Each asset is processed independently. Batch related assets into one submission to reduce request volume.

Attaching tags and supporting context

A submission can also carry top-level tags and contextItems (both optional). Tags are key/value labels (found-or-created automatically — no pre-creation or UUID lookup needed). Context items are supporting files or links the review can use. Each entry’s applyTo is "all" (default) or a list of asset blobPaths. A context file is uploaded the same way as an asset — request an upload URL, PUT the bytes, then reference the returned blobPath:
See Tags and supporting context for the full field reference and the allowed contextType values.

Response format

A successful create returns 201 with this shape:
Read the identifier from submissionId (not id). You’ll use it to check status and retrieve results.

Asset versioning

Versioning is explicit. To create a new version of an asset, submit a new submission whose asset references the prior asset through previousSubmissionId. The new submission becomes the next version in the same version group.
1

Upload the revised file

Upload the corrected file and get its blobPath.
2

Reference the previous submission

Include previousSubmissionId on the asset so the API links it as the next version.
3

List versions

Use /submissions/{submission_id}/versions to list all versions in the group.
Example: resubmitting after fixing audio issues.
List all versions in the group:
Response:

Batch submission example

A complete example of uploading multiple files and creating a batch submission:

Status transitions

A submission moves through the statuses below. The terminal states are complete, partial, and failed. A live create returns queued, not submitted. Because assets are admitted to review a few at a time, a submission flips to processing as soon as any asset starts and stays there until every asset has settled — so part of its work may still be waiting while it reads processing. There is no created, completed, or processed status. Use complete for the all-success terminal state and partial for a mixed outcome.

Error handling

If submission creation fails, check these common cases.

Invalid blob path (403)

Ensure the file was uploaded successfully and the blobPath matches the value returned by the upload endpoint exactly.

Previous submission not found (404)

The previousSubmissionId does not resolve to a submission in your workspace.

Asset already submitted (409)

The asset at that blobPath has already been submitted. Use versioning with previousSubmissionId to create a new version.

Request validation failed (422)

Fix the listed fields and resubmit. Common causes:
  • sidekickIds missing or empty — at least one sidekick is required (see Choosing sidekicks).
  • A per-asset sidekickIds is not a subset of the submission-level sidekickIds.
  • An asset’s type has no compatible sidekick — e.g. a PDF submitted only with a video sidekick.

Best practices

  • Upload with presigned URLs — request a URL per file and PUT the bytes straight to Azure Blob Storage.
  • Batch related assets — group related files into one submission.
  • Version explicitly — use previousSubmissionId rather than re-submitting the same path.
  • Handle retries — implement exponential backoff for transient failures.
  • Log submission IDs — save the submissionId for audit trails and support.