Skip to main content

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 only carries blobPath (the path returned by an upload) and, optionally, previousSubmissionId for versioning. Do not send filename or contentType in asset objects — they are not part of the schema. The optional top-level fields are sidekickIds (a list of UUIDs, empty for none) and metadata (an arbitrary object).

Single asset submission

curl -X POST https://mm-midmarket-integrations-api-preview.azurewebsites.net/api/integrations/submissions \
  -H "X-API-Key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "assets": [
      { "blobPath": "<workspace-id>/recording.mp4" }
    ],
    "sidekickIds": [],
    "metadata": { "campaign": "spring-2026" }
  }'

Multiple asset submission

Submit multiple assets in a single request for batch processing:
{
  "assets": [
    { "blobPath": "<workspace-id>/video1.mp4" },
    { "blobPath": "<workspace-id>/video2.mp4" },
    { "blobPath": "<workspace-id>/contract.pdf" }
  ],
  "sidekickIds": [],
  "metadata": { "campaign": "spring-2026" }
}
Each asset is processed independently. Batch related assets into one submission to reduce request volume.

Response format

A successful create returns 201 with this shape:
{
  "submissionId": "550e8400-e29b-41d4-a716-446655440000",
  "workflowId": "asset-processing-...",
  "ablyChannel": "submission:550e8400-...",
  "status": "submitted",
  "assets": [
    {
      "assetId": "a1b2...",
      "versionGroupId": "g1...",
      "versionNumber": 1
    }
  ]
}
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.
import requests

API_BASE = "https://mm-midmarket-integrations-api-preview.azurewebsites.net"

# The original submission whose asset you want to supersede
previous_submission_id = "550e8400-e29b-41d4-a716-446655440000"

response = requests.post(
    f"{API_BASE}/api/integrations/submissions",
    headers={"X-API-Key": "your-api-key-here"},
    json={
        "assets": [
            {
                "blobPath": "<workspace-id>/recording-fixed.mp4",
                "previousSubmissionId": previous_submission_id,
            }
        ],
        "sidekickIds": [],
    },
)

new_submission = response.json()
print(f"New version submission: {new_submission['submissionId']}")
print(f"Version number: {new_submission['assets'][0]['versionNumber']}")
List all versions in the group:
curl -H "X-API-Key: your-api-key-here" \
  https://mm-midmarket-integrations-api-preview.azurewebsites.net/api/integrations/submissions/550e8400-e29b-41d4-a716-446655440000/versions
Response:
{
  "versions": [
    {
      "assetId": "a1...",
      "submissionId": "550e8400-...",
      "versionNumber": 1,
      "name": "recording.mp4",
      "createdAt": "2026-06-03T12:00:00Z",
      "status": "complete",
      "issueCount": 3
    },
    {
      "assetId": "a2...",
      "submissionId": "660e8400-...",
      "versionNumber": 2,
      "name": "recording-fixed.mp4",
      "createdAt": "2026-06-04T10:00:00Z",
      "status": "complete",
      "issueCount": 1
    }
  ],
  "total": 2
}

Batch submission example

A complete example of uploading multiple files and creating a batch submission:
import requests
from pathlib import Path

API_KEY = "your-api-key-here"
API_BASE = "https://mm-midmarket-integrations-api-preview.azurewebsites.net"

def batch_submit_files(file_paths: list[str]) -> str:
    """Upload files via presigned URLs and create one batch submission."""

    assets = []
    for file_path in file_paths:
        file = Path(file_path)

        # Get a presigned URL
        url_response = requests.post(
            f"{API_BASE}/api/integrations/uploads/url",
            headers={"X-API-Key": API_KEY},
            json={
                "filename": file.name,
                "contentType": get_content_type(file.suffix),
            },
        )
        url_response.raise_for_status()
        data = url_response.json()

        # Upload the file to Azure
        with open(file_path, "rb") as f:
            requests.put(
                data["uploadUrl"],
                headers={"x-ms-blob-type": "BlockBlob"},
                data=f,
            ).raise_for_status()

        assets.append({"blobPath": data["blobPath"]})
        print(f"Uploaded {file.name}")

    # Create one submission with all assets
    response = requests.post(
        f"{API_BASE}/api/integrations/submissions",
        headers={"X-API-Key": API_KEY},
        json={"assets": assets, "sidekickIds": []},
    )
    response.raise_for_status()

    submission = response.json()
    print(f"Submission created: {submission['submissionId']}")
    return submission["submissionId"]

def get_content_type(suffix: str) -> str:
    types = {
        ".mp4": "video/mp4",
        ".mp3": "audio/mpeg",
        ".pdf": "application/pdf",
        ".txt": "text/plain",
    }
    return types.get(suffix.lower(), "application/octet-stream")

# Usage
files = ["video1.mp4", "video2.mp4", "notes.pdf"]
submission_id = batch_submit_files(files)

Status transitions

A submission moves through the statuses below. The terminal states are complete and failed.
StatusMeaningAction
uploadingAssets are being receivedWait
submittedSubmission registered and queuedProcessing will start shortly
processingAssets are being analyzedPoll for updates
completeAll assets finishedRetrieve results
failedOne or more assets failedCheck errorMessage / per-asset fields
There is no created, completed, or processed status. Use complete for the success terminal state.

Error handling

If submission creation fails, check these common cases.

Invalid blob path (403)

{ "detail": "..." }
Ensure the file was uploaded successfully and the blobPath matches the value returned by the upload endpoint exactly.

Previous submission not found (404)

{ "detail": "..." }
The previousSubmissionId does not resolve to a submission in your workspace.

Asset already submitted (409)

{ "detail": "..." }
The asset at that blobPath has already been submitted. Use versioning with previousSubmissionId to create a new version.

Request validation failed (422)

{
  "error": "validation_error",
  "message": "Request payload is invalid.",
  "fields": [
    { "field": "assets", "message": "..." }
  ]
}
Fix the listed fields and resubmit.

Best practices

  • Use the right upload method — direct upload for files up to 10 MB, presigned URLs for larger files.
  • 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.