Compute
Run one Compute job
The exact shape of a Lithi Compute task submission — the four steps, the identifiers, the idempotency rule, and the limits your request must respect.
On this page
On this page
What works today
Read this section before you build anything against this page.
Task submission is not open yet. The write path is built and its contract is settled, but no customer can authenticate, request a quote, or submit a job today. Six operations answer, and all six only read records that already exist:
- read one job
- read one batch
- read a job result
- list job events
- list batch results
- list agent events
Everything else — creating a quote, creating a job, creating a batch, listing capabilities, and preparing or completing an input file — returns 503 UNAVAILABLE with the next action extend_shared_operation_schema.
The rest of this page describes the contract those operations will accept. It is accurate about the shape your request must have. It is not a claim that you can send one yet. When the write path opens, this page changes only by removing this section.
The four steps
A submission is four calls, in order. Each one depends on the one before it.
- Prepare an input file.
POST /v1/artifacts/preparereserves an artifact and returns an upload target and chunk size. - Complete the upload.
POST /v1/artifacts/completeseals it and gives you a stableartifact_id. - Get a quote.
POST /v1/quotesprices exactly one bounded operation and returns a signed quote with an expiry. - Submit the job.
POST /v1/jobsreferences that quote byquote_idand returns202with a job identifier.
You cannot skip step 3. A job carries a quote_id, and the service re-reads that quote and checks it against your job before accepting anything. A job whose quote has expired, or whose quote priced different work, is rejected rather than repriced.
The three identifiers
Every submission carries three correlation identifiers, and the rules between them are enforced, not conventional:
task_idandworkflow_run_idmust be equal.trace_idmust be different from both.
All three are UUIDs. Getting this wrong is the most common structural rejection, and it is silent in the sense that nothing about the field names suggests the constraint. Generate one UUID for the task, use it twice, and generate a second one for the trace.
Your account_id must match the account the API key belongs to. It is checked against the key, not taken on trust, and every nested account_id anywhere in the request body must match too.
Idempotency is required, not optional
Every write carries an Idempotency-Key header. It is rejected unless it is:
- 8 to 128 characters
- ASCII only
- starting with a letter or digit, then letters, digits, and
. _ : - - free of commas
The same key must also appear as idempotency_key in the job body, and it must match the key recorded on the quote. Three places, one value. A mismatch is a validation failure, not a duplicate-detection event.
Limits your request must respect
The request body is capped at 64 KiB. This is a hard server-side ceiling and cannot be raised per call. It applies to the JSON you send, not to your input file — files travel as artifacts, not inline.
Duplicate JSON keys are rejected. So are byte-order marks, control characters in strings, and trailing content after the closing brace. The parser is deliberately strict; it is not a normal JSON.parse.
Every object is closed. Unknown fields are rejected rather than ignored, everywhere in the request. If you send a field this page does not describe, the request fails. That is intentional: it means a typo becomes an error instead of a silently dropped value.
Your bounds must be inside the capability's declared bounds. Each capability declares its own maximum file count, ciphertext size, input tokens, and output tokens. See Capabilities for how to read them and where they currently sit.
Before you send
Check these in order. They account for most first-attempt failures:
task_idequalsworkflow_run_id, andtrace_iddiffers from both.account_idmatches your key's account, everywhere it appears.Idempotency-Keyheader, bodyidempotency_key, and the quote's key are the same string.deadline_atis at or before the quote'sexpires_at.- The body is under 64 KiB and contains no field this documentation does not describe.
- Your declared bounds are within the capability's declared maximums.
Related
- Capabilities — what you can ask for, and the limits each one declares
- Input files — how a file reaches Compute, and what must never travel with it
- Batches and chains — many independent items, and multi-step work
- Errors — the full refusal vocabulary and what each one means
- MCP tools — the same contract, for an AI agent