Integrations
APIComfyUIManager
Roto · Depth · Upscale · For pipelines and post houses

Batch API.
Wire it in.

A REST API that connects your scripts, render farms and pipeline tools to Batch. Quote a job, submit it, upload the footage, track it and download the results.

Same workspace, same credits and same engine as Batch Portal. API jobs show up in Portal with everything else.

Base URL https://backend.batch.film/api/public/v1 · OpenAPI 3.1
One shot, six calls
POST
/pricing/estimate
Quote
POST
/jobs
Submit
POST
/jobs/{job_id}/upload-artifacts
Upload
POST
/jobs/{job_id}/confirm-upload
Confirm
GET
/jobs/{job_id}
Track
GET
/jobs/{job_id}/artifacts
Download
One account

One Batch workspace and one pool of credits across Portal, the API and ComfyUI.

Same engine

Batch Roto V3.2, Batch Depth V3 and Batch Upres, the same as Batch Portal.

Quoted first

Every job is quoted before it runs. Set a ceiling and nothing is submitted above it.

What it does

Start with one handoff.

Pick one thing your pipeline already does and hand that step to Batch. A finished VFX pull. A watch folder. A Send to Batch button for your artists. A shot marked ready in your tracker.

You write the bridge. Batch does the roto, depth and upscale, and hands back files your pipeline can check and publish.

Roto
Send the subjects to isolate, like people or red car. Get back a grayscale ProRes matte per clip, the same size and frame count as the source: one combined matte, or combined plus one per subject Batch finds.
Depth
Nothing extra to send. Get back a ProRes depth movie for the whole picture.
Upscale
Send 2x or 4x. Get back the upscaled video as ProRes.

Combine services in one job. Send video files (ProRes MOV, H.264 MP4 or DNxHD MXF). Results come back as ProRes movies.

Quickstart

Eight steps. One shot.

Run one small job end to end. Everything lives under one base URL: https://backend.batch.film/api/public/v1

01

Get a key

A workspace admin opens Batch Portal, then Integrations, API keys, Create key from the account menu at the top right (in Portal 1.1.6 and earlier, API keys sit under Settings). Name the key after the tool that will use it, tick the permissions it needs, and set an expiry if you want one.

The key is shown once. Copy it straight into your secret manager. Keys belong to the workspace, not the person, so a key keeps working if whoever made it leaves.

Read pricing
pricing:read. Quote jobs and read the rate table.
Submit jobs
jobs:submit. Create and cancel jobs, create projects. Spends credits.
Write artifacts
artifacts:write. Get upload links and confirm uploads.
Read jobs
jobs:read. List and read jobs, status history, clip metrics and projects.
Read artifacts
artifacts:read. Download results.
Read billing
billing:read. Read the credit balance and any owed credits.

A key that runs the whole flow needs the first five. Read billing is optional. The ComfyUI preset ticks the five job permissions; the Read-only preset ticks Read jobs and Read artifacts. Permissions can't be changed on an existing key: make a new one and revoke the old. No Portal yet? Download Batch Portal for Mac or Windows.

02

Send it with every request

Every request carries the key as a Bearer token. Load it from your secret manager, never from a script or your shell history. Check the wiring with GET /me: it needs no permission, uses no credits, and shows the key's name, permissions, rate limit and daily cap.

export BATCH_API_URL="https://backend.batch.film/api/public/v1"
# BATCH_API_KEY comes from your secret manager

curl -s "$BATCH_API_URL/me" \
  -H "Authorization: Bearer $BATCH_API_KEY"
03

Get an estimate

A job is a set of services applied to a set of clips. Write it once as job.json, quote it, then submit the same file.

{
  "services": ["roto"],
  "subjects": ["people"],
  "individual_mattes": false,
  "clips": [
    {"name": "SH010/plate.mov", "duration_seconds": 4.2, "size_bytes": 104857600}
  ],
  "max_credits": 20,
  "job_name": "SH010 roto"
}
curl -s -X POST "$BATCH_API_URL/pricing/estimate" \
  -H "Authorization: Bearer $BATCH_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @job.json

The estimate creates nothing and charges nothing. It returns credits (a whole number), an exact breakdown and the pricing version it used.

services
roto, depth, upscale. Combine them in one job.
subjects
What roto isolates, one item per subject. "red car" stays together.
prompt
Extra keywords for roto, split on commas and spaces. Prefer subjects.
individual_mattes
false: one combined matte. true: combined plus one per subject found (the default, and it can cost more on busy shots). Always set it.
upscale_factor
2x or 4x. Required with upscale, refused without it.
clips
One entry per file. name can carry a folder path. duration_seconds and size_bytes are required and drive the quote. resolution, codec, frame_rate, color_space and timecode are optional.
max_credits
Your ceiling. Batch quotes again at submission and creates no job if the quote is above it.
project_name · job_name
Optional. Shown with the job in Batch Portal. project_id works too.
04

Create the job

curl -s -X POST "$BATCH_API_URL/jobs" \
  -H "Authorization: Bearer $BATCH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: show42-SH010-v1" \
  --data-binary @job.json

Idempotency-Key is required. Use an ID from your own system. If a response gets lost, retry with the same key, the same body and the same API key, and Batch hands back the original job instead of making a second one. Keys are honored for 24 hours.

The job comes back as awaiting_upload with its id. Save the id right away.

05

Upload the footage

curl -s -X POST "$BATCH_API_URL/jobs/$JOB_ID/upload-artifacts" \
  -H "Authorization: Bearer $BATCH_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"artifact_names": []}'

curl -s -X PUT --upload-file /footage/SH010/plate.mov "$UPLOAD_URL"

You get one temporary upload link per clip, named in the order you submitted them (0/plate.mov, 1/plate.mov). Match links to files by position, not by file name. PUT each file straight to its link, without your API key.

Files over 5 GB must use multipart upload with POST /jobs/{job_id}/upload-artifacts/multipart; it is recommended above 100 MB. Interrupted? POST /jobs/{job_id}/resume-upload returns fresh links for whatever is still missing.

06

Confirm the upload

curl -s -X POST "$BATCH_API_URL/jobs/$JOB_ID/confirm-upload" \
  -H "Authorization: Bearer $BATCH_API_KEY"

Confirming seals the footage and starts the security check. Confirming twice is safe.

07

Poll the status

curl -s "$BATCH_API_URL/jobs/$JOB_ID" \
  -H "Authorization: Bearer $BATCH_API_KEY"

Poll every 10 seconds or slower, back off toward 30, and honor Retry-After. Stop at completed or failed. status is the source of truth; progress is a rough signal, not an estimate of time left.

08

Download the results

curl -s "$BATCH_API_URL/jobs/$JOB_ID/artifacts" \
  -H "Authorization: Bearer $BATCH_API_KEY"

Each result comes with a name, a delivery_path and a temporary url. Write each file to its delivery_path under your staging folder, which restores your submitted folders, or to its name when delivery_path is empty. Check the files, then publish.

Links are temporary and carry expires_in_seconds. Ask again for fresh ones, and never write them to a log. A job that failed partway may have output at GET /jobs/{job_id}/artifacts/partial: treat it as review material, never as a delivery.

Endpoints

Every call.

Base URL https://backend.batch.film/api/public/v1. The OpenAPI 3.1 spec is at /openapi.json, and the full interactive reference is at backend.batch.film/api/public/v1/docs.

GET
/me
Which key this is: name, permissions, limits
POST
/pricing/estimate
Quote a job. Creates nothing, charges nothing.
GET
/pricing/config
The current rate table, for reference
POST
/jobs
Submit a job. Idempotency-Key required.
GET
/jobs
List jobs, newest first (page, page_size)
GET
/jobs/{job_id}
One job: status, estimate, error
GET
/jobs/{job_id}/status-history
Every status change with its time
GET
/jobs/{job_id}/clips
Per-clip processing metrics
POST
/jobs/{job_id}/cancel
Cancel a job before it finishes
POST
/jobs/{job_id}/upload-artifacts
Upload links, one per clip
POST
/jobs/{job_id}/upload-artifacts/multipart
Multipart upload for large files
POST
/jobs/{job_id}/resume-upload
Fresh links for files still missing
POST
/jobs/{job_id}/confirm-upload
Seal the upload and start the security check
GET
/jobs/{job_id}/artifacts
Download links for a completed job
GET
/jobs/{job_id}/artifacts/partial
Partial output from a failed job
GET
/billing/balance
Credit balance and any owed credits
GET
/projects
List projects
POST
/projects
Create a project

GET /jobs takes page and page_size and nothing else. Filter by status on your side.

Job states

Six states. One waits on you.

1
awaiting_upload
Waiting for your footage. Upload, then confirm.
2
scanning
Footage received and clearing the security check. Don't upload again.
3
queued
Accepted and waiting to start. Keep polling.
4
processing
Running. Keep polling.
5
completed
Done. Download the results.
6
failed
Stopped, including a cancelled job. Read terminal_reason.

When a job fails

A failed job carries a terminal_reason. Branch on it, and treat anything unfamiliar as processing_failed. A cancelled job reads failed with the message "This job was cancelled." There is no separate cancelled status.

cancelled_by_user
Someone cancelled the job. Nothing to do.
upload_not_confirmed
The upload never completed. Submit again and upload again.
processing_failed
Processing didn't succeed. Keep the error and the job ID, and write to support@batch.film if it repeats.
Credits

Quoted before it runs. Billed on what it uses.

API jobs use the same rates as Batch Portal, from the same workspace credits. There is no separate API price.

Estimate
POST /pricing/estimate is a quote, not a receipt.
Ceiling
Send max_credits with the job. If the quote at submission is above it, no job is created. It caps the quote, not the final charge.
Hold
Nothing is held when you submit. When processing starts, Batch holds the estimate.
Settle
When the job finishes, Batch charges for the footage actually processed and returns the rest of the hold. If the footage runs longer than you declared, the charge can be higher. Anything your balance can't cover shows as owed_credits on GET /billing/balance and comes out of your next credits.
Final charge
Batch Portal shows it under Usage and Metrics.
Buying credits
Keys can't buy credits. Add plans and credit packs in Batch Portal.
Limits

The limits.

Requests per key
60 a minute
Credits per key
1,000 a day, counted on estimates. The day is UTC and resets at 00:00 UTC.
Ceiling per job
max_credits, optional. No job is created if the quote is above it.
Clips per job
500
Open uploads
50 jobs in upload or intake at once, per account
Per file, roto or depth
50 GiB and 120 minutes
Per file, upscale or several services
100 GB and 90 minutes
Multipart
Required over 5 GB. Parts from 5 MiB, up to 10,000 parts.
Polling
Every 10 seconds or slower
Idempotency keys
Honored for 24 hours

Limits are per file, not per job, so a big delivery splits across clips and jobs. GET /me shows a key's current limits. Need more? Write to support@batch.film.

Errors

When it says no.

Every failure uses one envelope. Branch on the HTTP status, then on error_code.

{"error": {"status_code": 422, "detail": "...", "error_code": "..."}}
401
Key missing, wrong, revoked or expired. Check how your secret is injected, or make a new key.
402
Not enough credits (INSUFFICIENT_CREDITS, no job created), or the job is held for spend approval (SPEND_APPROVAL_REQUIRED). Don't retry in a loop. Add credits in Batch Portal, then resubmit the same body with the same Idempotency-Key. For a held job, keep spend_approval.job_id and get the approval.
403
Missing permission, an account gate or the daily cap. Check GET /me, then ask a workspace admin.
404
Not found, or not in this key's account. Check the ID.
409
A state or idempotency conflict, a security hold, or a quote above max_credits (no job created). Read detail and the job's state. For max_credits, quote again, then raise the ceiling or change the job.
422
Invalid body, or a file over its limit. Fix the body or split the file.
429
Rate limit, or too many jobs waiting on uploads. Honor Retry-After. Finish or cancel open uploads.
5xx
Temporary. Back off, then retry a submission with the same body, Idempotency-Key and API key.

For support, send the job ID, the endpoint, the time and the error_code. Never send a key or a download link.

Keys

Keys are credentials.

Store
Keep keys and temporary links in a secret manager, out of source control, logs, tickets, chat and email.
Scope
One key per tool, with just the permissions it needs.
Rotate
Make a new key, check it with GET /me, switch over, then revoke the old one.
People leave
Removing a person doesn't revoke the keys they made. Review keys when someone leaves.
A leaked key
Revoke it in Batch Portal under Integrations, API keys, and make a new one.
Questions

Questions.

Who can make keys?

Workspace admins, in Batch Portal under Integrations, API keys.

Do API jobs show up in Portal?

Yes. In Processing and History with everything else, marked as sent by API key.

Can I cancel a job?

Yes, with POST /jobs/{job_id}/cancel and the Submit jobs permission, until the job is completed or failed. Credits are held once processing starts, so a job cancelled before then leaves your balance as it was. Its estimate still counts toward the key's daily cap.

Can a key buy credits?

No. Add credits in Batch Portal.

How do I know a job is done?

Poll GET /jobs/{job_id} until it reads completed or failed.

Image sequences?

Send video files. Results are ProRes movies.

Where do I get help?

Support and technical questions go to support@batch.film. Sales, studios and anything else go to lets@batch.film.

Batch API

Get a key.
Send a shot.

Make a key in Batch Portal, quote one shot, and run it. Running a whole show through it? Write to lets@batch.film.