// Tools

xeroctl batches

Submit a JSONL file, get a batch id, poll to completion, pull the output. --input-prefix fans one batch out per pre-uploaded file under a stored path. Endpoint slug is non-negotiable; chat completions only today.

Overview

The xeroctl batches command wraps the Batch API for use from the command line. Every operation requires the --endpoint <slug> flag.

The typical workflow is:

  1. Prepare a JSONL file where each line is a single inference request.
  2. Run xeroctl batches --endpoint <slug> --input requests.jsonl to upload the file and create the batch in one step.
  3. Poll status with --wait, or check manually using xeroctl batches <id> --endpoint <slug>.
  4. Download the output JSONL once the batch completes.

Back to xeroctl CLI overview or the Batch API reference.

JSONL Format

Each line in the input file is a self-contained JSON object representing one inference request. The format mirrors the OpenAI Batch API JSONL specification.

Required Fields

Field Type Description
custom_id string Unique identifier for this request. Echoed back in the output file to correlate results.
method string HTTP method. Must be "POST".
url string Target API path, e.g. "/v1/chat/completions" or "/v1/embeddings".
body object The full request body for the target endpoint. Must include model and the required body fields for that endpoint.

Example, Chat Completions Batch

JSONL
{"custom_id": "req-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "my-model", "messages": [{"role": "user", "content": "What is the capital of France?"}], "max_tokens": 64}} {"custom_id": "req-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "my-model", "messages": [{"role": "user", "content": "Summarize the Pythagorean theorem."}], "max_tokens": 128}} {"custom_id": "req-3", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "my-model", "messages": [{"role": "user", "content": "Write a haiku about the ocean."}], "max_tokens": 64}}

xeroctl scope: The xeroctl batches command today only targets /v1/chat/completions. The CLI hardcodes that endpoint on the batch row regardless of the url values inside the JSONL, so embeddings or responses batches submitted via xeroctl will be routed as chat completions and fail. For non-chat batches, submit the batch directly via the Batch API.

Note: Each line must be a complete, valid JSON object. Blank lines are not permitted. The custom_id must be unique within the file. The input file must not exceed 100 MB after upload; larger files upload successfully but fail at batch validation.

Create Batch

Provide an --input path to upload the JSONL file and submit the batch in a single command. The CLI uploads the file first (printing the file ID), then creates the batch job.

bash
# Create and return immediately xeroctl batches --endpoint my-llm --input requests.jsonl # Create and wait for completion xeroctl batches --endpoint my-llm --input requests.jsonl --wait # Attach metadata, one flag per pair xeroctl batches --endpoint my-llm \ --input requests.jsonl \ --metadata project=finance \ --metadata run_id=batch-2026-04-09 # Attach metadata, multiple pairs after a single --metadata flag xeroctl batches --endpoint my-llm \ --input requests.jsonl \ --metadata project=finance run_id=batch-2026-04-09 # Preview without uploading or creating xeroctl batches --endpoint my-llm --input requests.jsonl --dry-run

Create Options

Option Description
--input <file.jsonl> Path to the JSONL input file. Triggers batch creation.
--input-prefix <path> Resolve already-uploaded files under this relative_path prefix and create one batch per match. See the next section.
--metadata <k=v> [<k=v> ...] Attach metadata. Either repeat the flag once per pair, or pass multiple key=value tokens after a single --metadata (parsed up to the next flag). Serialized metadata must not exceed 16 KB; oversized values return HTTP 400 "Metadata exceeds maximum size of 16KB".
--wait After creating, poll until the batch reaches a terminal state. Can also be combined with an existing batch ID.

Create Batches From Prefix

Use --input-prefix <path> to fan out one batch per already-uploaded file whose relative_path begins with the given prefix. The CLI queries the Files API for files with purpose=batch matching the prefix and submits a batch for each. This avoids re-uploading inputs that were staged earlier through xeroctl files upload.

bash
# Submit one batch per file under prefix "experiments/2026-05/" xeroctl batches --endpoint my-llm --input-prefix experiments/2026-05/ # Combine with metadata and wait for terminal state on each batch xeroctl batches --endpoint my-llm \ --input-prefix experiments/2026-05/ \ --metadata run_id=may-sweep \ --wait # Preview which files would be submitted xeroctl batches --endpoint my-llm --input-prefix experiments/2026-05/ --dry-run

The Files API list call caps at 100 results per page, so chunk the prefix if more files need to be submitted in a single invocation. --input-prefix cannot be combined with a positional batch ID, and is mutually exclusive with --input, --cancel, --download, and --errors. Each per-file submission prints [OK] <relative_path> -> <batch_id> or [FAIL] <relative_path> (<error>); the command exits non-zero if any submission failed.

List Batches

List all batch jobs for the specified endpoint. The table shows ID, Status, Total requests, Completed, Failed, and Created time.

bash
# List batches for an endpoint xeroctl batches --endpoint my-llm # Limit results xeroctl batches --endpoint my-llm --limit 20 # Paginate using a cursor (batch ID to start after) xeroctl batches --endpoint my-llm --after batch_abc123 # JSON output xeroctl batches --endpoint my-llm -o json

When more results exist beyond the current page, a hint is printed showing the last batch ID to use as the --after cursor. List sort order is not guaranteed by this page; do not assume .data[0] is the most-recent batch, match by id or created_at in callers.

Get Batch

Show full details for a specific batch job.

bash
xeroctl batches batch_abc123 --endpoint my-llm # JSON output xeroctl batches batch_abc123 --endpoint my-llm -o json

The detail view includes: ID, Status, Endpoint, Input File ID, Output File ID, Error File ID, Completion Window, Total / Completed / Failed request counts, Created, Started At, Expires, Completed At, Cancelled At, and any metadata.

Cancel Batch

Cancel an in-progress batch. The batch transitions to cancelling and then cancelled. Requests that were already processed will have results in the partial output file.

bash
# Cancel with confirmation xeroctl batches batch_abc123 --endpoint my-llm --cancel # Preview without cancelling xeroctl batches batch_abc123 --endpoint my-llm --cancel --dry-run

Download Output

Download the output JSONL file from a completed batch. The output file contains one result object per successful request, keyed by custom_id.

bash
# Download to default filename (<batch-id>-output.jsonl) xeroctl batches batch_abc123 --endpoint my-llm --download # Specify output path (long-only flag; -o is the global format selector) xeroctl batches batch_abc123 --endpoint my-llm --download --output-file results.jsonl

If no output file is available (the batch has not yet completed, or all requests failed), an error message is printed along with the current batch status.

Download Errors

Download the error JSONL file for a batch. The error file contains one entry per failed request, including the custom_id and error details.

bash
# Download error file to default filename (<batch-id>-errors.jsonl) xeroctl batches batch_abc123 --endpoint my-llm --errors # Specify output path (long-only flag; -o is the global format selector) xeroctl batches batch_abc123 --endpoint my-llm --errors --output-file batch-errors.jsonl

Wait for Completion

Poll a batch every 2 seconds until it reaches a terminal state: completed, failed, cancelled, or expired. An inline progress bar is printed when request counts are available.

bash
# Wait on an existing batch xeroctl batches batch_abc123 --endpoint my-llm --wait # Create and immediately wait xeroctl batches --endpoint my-llm --input requests.jsonl --wait

On completion, the terminal status, request counts, and file IDs are printed. Use -o json to receive a machine-readable summary on completion.

Options Reference

Every flag xeroctl batches accepts, role-grouped. The Role column tells you why it exists; the Requires Batch ID column tells you when it applies.

Mutual exclusivity: --input, --input-prefix, --cancel, --download, and --errors are action flags. Pass exactly one per invocation. --input-prefix additionally cannot be combined with a positional batch ID. --wait is the only action flag that composes (with --input or with a batch ID).

Option Role Requires Batch ID Description
--endpoint <slug> required n/a Endpoint slug. Required for every batch operation.
--input <file.jsonl> action No Upload and create a new batch from the given JSONL file.
--input-prefix <path> action No (cannot be combined with a batch ID) Resolve already-uploaded files under the given relative_path prefix and submit one batch per match.
--cancel action Yes Cancel a running batch.
--download action Yes Download the output JSONL file.
--errors action Yes Download the error JSONL file.
--wait action Yes (or use with --input) Poll until the batch reaches a terminal state. Composes with --input.
--dry-run modifier Depends on action Preview the action without uploading, creating, or cancelling.
--output-file <path> modifier Yes Destination file path for --download or --errors. Defaults to <batch-id>-output.jsonl or <batch-id>-errors.jsonl. Long-only; -o is reserved for the global format selector (-o json, -o table, ...).
--metadata <k=v> [<k=v> ...] modifier No (creates only) Metadata to attach when creating a batch. Repeat once per pair, or pass multiple key=value tokens after a single --metadata (parsed up to the next flag). Serialized metadata must not exceed 16 KB.
--limit <n> modifier No (list only) Maximum number of results when listing.
--after <id> modifier No (list only) Pagination cursor: batch ID to start results after.

Common Errors

Real messages the CLI surfaces, what they mean, and what to change.

Message Meaning Fix
HTTP 400 Metadata exceeds maximum size of 16KB Serialized JSON of all --metadata key=value pairs exceeds the 16 KB cap. Drop the largest value, or move bulky context into the request body inside the JSONL.
HTTP 413 Input file exceeds 100 MB Upload succeeded but batch validation rejects files larger than 100 MB. Split the JSONL and submit multiple batches; combine results with --output-file + jq.
[FAIL] <relative_path> (no files found for prefix) --input-prefix matched zero files with purpose=batch. Run xeroctl files --purpose batch to confirm the prefix; the Files list call caps at 100 results per page.
Output file not yet available Batch is not in a terminal state, or every request failed and only the error file exists. Use --wait first, then --download; pull failed-request detail with --errors.
--input-prefix cannot be combined with --input / --cancel / --download / --errors Two action flags passed in one invocation. Pick exactly one; see the mutual-exclusivity callout above.

Examples

End-to-End Batch Workflow

bash
#!/bin/bash ENDPOINT="my-llm" INPUT="requests.jsonl" # Create batch and wait for it to finish xeroctl batches --endpoint "$ENDPOINT" --input "$INPUT" --wait # Retrieve the batch ID from the list BATCH_ID=$(xeroctl batches --endpoint "$ENDPOINT" -o json \ | jq -r '.data[0].id') # Download output xeroctl batches "$BATCH_ID" --endpoint "$ENDPOINT" --download --output-file output.jsonl # Download any errors xeroctl batches "$BATCH_ID" --endpoint "$ENDPOINT" --errors --output-file errors.jsonl

Monitor an Existing Batch

bash
# Check current status xeroctl batches batch_abc123 --endpoint my-llm # Block until done xeroctl batches batch_abc123 --endpoint my-llm --wait

Create with Metadata Tags

bash
xeroctl batches \ --endpoint my-llm \ --input prompts.jsonl \ --metadata env=production \ --metadata team=data-science \ --metadata version=1.2.0