Skip to main content
Batches

Create Batch

POST /api/v1/forward/batches Forward validates the input file and JSONL line format, then schedules execution automatically inside the off-peak window. When the batch finishes, output.jsonl and error.jsonl are produced for download.

Headers

HeaderRequiredDescription
AuthorizationYesBearer <PAT or SAT>
Content-TypeYesapplication/json
Idempotency-KeyNoOptional idempotency key for unsafe requests.

Prerequisite: upload the input file

Creating a batch requires a JSONL input file uploaded through the CAS Files API to obtain a file_id. JSONL format — one JSON object per line, one line per independent task:
{"custom_id": "task-001", "template_id": "tmpl_example001", "identity_id": "idn_example001", "body": {"input": "hello"}}
{"custom_id": "task-002", "template_id": "tmpl_example001", "identity_id": "idn_example001", "body": {"input": "write me a short poem about summer"}}
FieldTypeRequiredDescription
custom_idstringYesCaller-defined identifier. Must be unique within a single batch and is used to map result lines.
template_idstringYesForward Template ID that drives execution.
identity_idstringYesForward Identity ID that provides the execution identity.
bodyobjectYesRequest body passed to Session. Its shape depends on the Template. Common shape: {"input": "user input"}.
Upload the file:
curl -X POST 'https://api.qoder.com.cn/api/v1/cloud/files' \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -F "file=@batch_input.jsonl" \
  -F "purpose=session_resource"
purpose=session_resource is required for Batch input files. If this field is omitted, the Files API stores the file with user_upload; CAS does not allow server-side downloads of such files, and Create Batch returns 400 invalid_input_file.
The returned id is the input_file_id for Create Batch.

Body parameters

ParameterTypeRequiredDescription
input_file_idstringYesJSONL file ID uploaded via the Files API.
completion_windowstringYesCompletion window: 24h, 48h, or 72h. The batch moves to expired when the window elapses.
metadataobjectNoCaller-supplied metadata. Up to 16 keys, any JSON value; the serialized object must be ≤ 2KB, each key ≤ 64 characters, and no NUL (U+0000) is allowed.

Example request

curl -s -X POST 'https://api.qoder.com.cn/api/v1/forward/batches' \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_batch_001" \
  -d '{
  "input_file_id": "file_input001",
  "completion_window": "24h",
  "metadata": {
    "source": "data_pipeline",
    "job_id": "12345"
  }
}'

Example response

HTTP 200 OK
{
  "id": "batch_example001",
  "object": "batch",
  "status": "validating",
  "input_file_id": "file_input001",
  "completion_window": "24h",
  "created_at": "2026-07-07T07:25:01Z",
  "expires_at": "2026-07-08T07:25:01Z",
  "request_counts": {
    "total": 0,
    "pending": 0,
    "running": 0,
    "completed": 0,
    "failed": 0,
    "cancelled": 0,
    "expired": 0
  },
  "usage": null
}
A newly created batch starts in validating and moves to queued once validation passes. output_file_id and error_file_id only appear after the batch reaches a terminal state and are omitted from the create response.

Response fields

FieldTypeDescription
idstringBatch ID with prefix batch_.
objectstringAlways batch.
statusstringBatch status. See the status table below.
input_file_idstringInput JSONL file ID.
completion_windowstringCompletion window: 24h, 48h, or 72h.
created_atstringCreation time, RFC 3339.
expires_atstringExpiration time, created_at + completion_window.
request_countsobjectAggregate task counters.
usageobject/nullnull in the create response. In subsequent batch detail, list, and cancellation responses, returns aggregate Credit usage after at least one subtask has valid CAS Session usage.
usage.total_creditsnumberSum of persisted subtask total_credits. The unit is CAS Credit, not tokens or currency. Explicit zero values are preserved.
metadataobjectCaller-supplied metadata.

Batch status

StatusDescriptionType
validatingValidating the input file and JSONL lines.Non-terminal
queuedValidated. Waiting for the off-peak window.Non-terminal
processingExecuting tasks.Non-terminal
cancellingCancellation in progress. Waiting for running tasks to finish.Non-terminal
expiringExpiration in progress. Waiting for running tasks to finish.Non-terminal
finalizingGenerating output files.Non-terminal
completedAll tasks executed. Output files generated.Terminal
failedInput validation failed or unrecoverable system error.Terminal
cancelledCancelled by the user.Terminal
expiredThe completion_window elapsed.Terminal

Request counts

FieldTypeDescription
totalintegerTotal lines, including lines that failed validation.
pendingintegerLines waiting to run.
runningintegerLines currently executing.
completedintegerLines that finished successfully.
failedintegerLines that failed permanently, including validation failures.
cancelledintegerLines terminated by cancellation.
expiredintegerLines terminated by expiration.
The invariant total = pending + running + completed + failed + cancelled + expired always holds.

Validation rules

Create Batch rejects the following errors upfront rather than enqueuing:
  • JSON parse failure → line marked failed
  • Missing required field → line marked failed
  • Duplicate custom_id → line marked failed
  • Tool permission policy set to always_ask or always_deny → line marked failed (unattended execution disallows these)
Validation failures on individual lines do not block other lines; they are written together to error.jsonl.

Error codes

HTTPTypeCodeTrigger
400invalid_request_errorinvalid_requestinput_file_id missing, invalid completion_window, or metadata too large.
400invalid_request_errorinvalid_input_fileThe input file cannot be downloaded by Batch. Upload it with purpose=session_resource.
429rate_limit_errorrate_limit_exceededThe user has reached the maximum number of unfinished batches.
401authentication_errorauthentication_requiredPAT is invalid or expired.

Notes

  • A single batch supports up to 10,000 JSONL lines.
  • Global concurrency is capped at 50 tasks.
  • Scheduling runs inside the off-peak window (default 22:00–08:00, configurable server-side).
  • After creating a batch, the client should poll GET /api/v1/forward/batches/{batch_id} until a terminal state is reached.