{"openapi":"3.1.0","info":{"title":"BatchRouter API","version":"1.0.0","summary":"Async AI batch routing - submit once, keep one batch_id, receive artifacts.","description":"Public, customer-facing BatchRouter API.\n\nThis is the curated customer surface: submit and track batch jobs, get\nquotes, manage files, API keys, webhooks, and usage. It is generated from\nthe internal master spec with operator/admin and provider-partner endpoints\nremoved. Internal operator APIs are gated behind admin authentication and\nare intentionally absent from this document.","x-spec-audience":"customer"},"servers":[{"url":"https://api.batchrouter.com","description":"Production"},{"url":"https://test.api.batchrouter.com","description":"Test / Staging"}],"tags":[{"name":"Authentication","description":"Sign up, log in, and manage sessions."},{"name":"Account","description":"Manage account profile, API keys, delivery webhooks, and workspace members."},{"name":"Catalog","description":"Public model and workflow-product catalog. No authentication required."},{"name":"Providers","description":"Public AI provider directory. No authentication required."},{"name":"Pricing","description":"Public fee schedule disclosure. No authentication required."},{"name":"Operations","description":"Health and runtime metadata used by deployment checks."},{"name":"Quotes","description":"Get a cost estimate before dispatching a batch. Estimate creation is free — credits are reserved when you create a batch and settled from actual token usage."},{"name":"Batches","description":"Submit batch jobs, inspect internal lane status, and retrieve results."},{"name":"Files","description":"Upload model input attachments for multimodal batch items."},{"name":"OpenAI Compatibility","description":"Drop-in OpenAI-Batch poll + retrieve surface under `/v1/openai/v1/*`. Point an existing `openai` SDK at this base path to poll batch status and download results with no code changes and no webhook. Serializes the native BatchRouter batch/file primitives into OpenAI shapes; the native `/v1/batches/*` and `/v1/files/*` surface is unchanged."},{"name":"Delivery","description":"Register a customer-owned, S3-compatible bucket (AWS S3, Cloudflare R2, GCS S3-interop, MinIO). When enabled, BatchRouter pushes a batch's result + error artifacts there on finalize. The secret access key is stored encrypted and is write-only (never returned)."},{"name":"Work Orders","description":"Server-side job tracking for workflow and agent-main-thread runs.","x-beta":true},{"name":"Billing","description":"Customer spending controls, alerts, and auto top-up. Configure spending limits, low-balance and threshold alerts, and automatic credit refills. See the `webhooks` section for the events these deliver."},{"name":"Usage","description":"Customer billing receipts and settlement data."},{"name":"Workflows","description":"Curated workflow-product contracts for agent-native AI tasks."}],"paths":{"/v1/health":{"get":{"tags":["Operations"],"operationId":"health","summary":"Health check","description":"Returns API health and read-only maintenance status. This endpoint remains available during `READ_ONLY=1` maintenance windows.","responses":{"200":{"description":"API health status","content":{"application/json":{"schema":{"type":"object","required":["ok","service","read_only"],"properties":{"ok":{"type":"boolean"},"service":{"type":"string"},"read_only":{"type":"boolean"}}}}}}}},"head":{"tags":["Operations"],"operationId":"healthHead","summary":"Health check headers","description":"Returns health headers without a response body.","responses":{"200":{"description":"API health headers"}}}},"/v1/content/changelog":{"get":{"tags":["Content"],"operationId":"contentChangelog","summary":"Public changelog entries","description":"Published changelog entries (newest-first) for the marketing site. Public, unauthenticated, edge-cached. Served from the dedicated marketing content store; gated by the `CONTENT_SOURCE` flag (responds 503 while disabled).","responses":{"200":{"description":"Changelog entries","content":{"application/json":{"schema":{"type":"object","required":["entries"],"properties":{"entries":{"type":"array","items":{"type":"object","required":["date","tag","title","items"],"properties":{"date":{"type":"string","description":"Pre-formatted display date, e.g. \"June 11, 2026\"."},"tag":{"type":"string"},"title":{"type":"string"},"items":{"type":"array","items":{"type":"string"}}}}}}}}}},"503":{"description":"Content store is not enabled (CONTENT_SOURCE off)."}}}},"/v1/content/posts":{"get":{"tags":["Content"],"operationId":"contentPosts","summary":"Public blog/news posts","description":"Published blog/news posts (newest-first by publish date). Public, unauthenticated, edge-cached. Gated by the `CONTENT_SOURCE` flag.","responses":{"200":{"description":"Posts","content":{"application/json":{"schema":{"type":"object","required":["posts"],"properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/ContentBlogPost"}}}}}}},"503":{"description":"Content store is not enabled (CONTENT_SOURCE off)."}}}},"/v1/content/posts/{slug}":{"get":{"tags":["Content"],"operationId":"contentPostBySlug","summary":"Public blog/news post by slug","description":"A single published post by slug. Public, unauthenticated, edge-cached. Gated by the `CONTENT_SOURCE` flag.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Post","content":{"application/json":{"schema":{"type":"object","required":["post"],"properties":{"post":{"$ref":"#/components/schemas/ContentBlogPost"}}}}}},"404":{"description":"Post not found."},"503":{"description":"Content store is not enabled (CONTENT_SOURCE off)."}}}},"/v1/auth/register":{"post":{"tags":["Authentication"],"operationId":"register","summary":"Register a new customer account","description":"Creates an org and user account for human sign-up. Sends an email verification link. Use `POST /v1/auth/agent-register` instead for programmatic / agent-first access — it issues an API key immediately without email verification.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}}},"responses":{"200":{"description":"Account created. Email verification required before full access.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/auth/agent-register":{"post":{"tags":["Authentication"],"operationId":"agentRegister","summary":"Register an agent — get an API key in one call","description":"Creates an org and issues an API key in a single unauthenticated request. No email required. Designed for AI agents and automated onboarding.\n\nThe returned `api_key` is shown **once** — store it securely.","x-payment-info":{"intent":"session","method":["stripe","card"],"currency":"USD","description":"Registration is free. Credits are required to submit batches. Purchase credits at https://batchrouter.com/app/billing after registering."},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegisterRequest"}}}},"responses":{"200":{"description":"Org and API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegisterResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/auth/login":{"post":{"tags":["Authentication"],"operationId":"login","summary":"Log in with email and password","description":"Authenticates a human user and sets a `batchrouter_ui_session` cookie. AI agents should use API key authentication instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Authenticated. Session cookie set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/auth/password/forgot":{"post":{"tags":["Authentication"],"operationId":"forgotPassword","summary":"Request a password reset email","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Reset email dispatched (identical response whether the address exists or not — prevents account enumeration)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}}}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/auth/password/reset":{"post":{"tags":["Authentication"],"operationId":"resetPassword","summary":"Confirm a password reset","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","password"],"properties":{"token":{"type":"string","description":"Token from the reset email link."},"password":{"type":"string","minLength":8}}}}}},"responses":{"200":{"description":"Password updated","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/sessions/current":{"get":{"tags":["Authentication"],"operationId":"getCurrentSession","summary":"Get current session","description":"Returns session metadata for the authenticated caller, or `{ session: null }` when no credentials are present. Useful for hydrating the frontend on load — always succeeds with `200`.","security":[{"customerApiKey":[]},{"customerSession":[]},{}],"responses":{"200":{"description":"Session envelope — `session` is null when unauthenticated.","content":{"application/json":{"schema":{"type":"object","required":["session"],"properties":{"session":{"oneOf":[{"$ref":"#/components/schemas/SessionResponse"},{"type":"null"}]}}}}}}}},"delete":{"tags":["Authentication"],"operationId":"signOut","summary":"Sign out — revoke current session","description":"Revokes the current session cookie. API key sessions are not affected.","security":[{"customerSession":[]}],"responses":{"200":{"description":"Signed out","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/auth/account":{"get":{"tags":["Account"],"operationId":"getAccount","summary":"Get account details","description":"Returns org details, plan, credit balance, and members.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Account details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/auth/account/profile":{"put":{"tags":["Account"],"operationId":"updateProfile","summary":"Update account profile","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"display_name":{"type":"string","minLength":1,"maxLength":128},"full_name":{"type":"string","maxLength":256}}}}}},"responses":{"200":{"description":"Profile updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/auth/account/delivery-webhook":{"put":{"tags":["Account"],"operationId":"setDeliveryWebhook","summary":"Set default delivery webhook","description":"Sets the org-level default webhook URL and secret for batch result delivery. Individual batch submissions can override this per-batch.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","secret"],"properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL to receive batch delivery webhooks."},"secret":{"type":"string","minLength":8,"maxLength":256,"description":"Shared secret for HMAC-SHA256 signature verification (`X-BatchRouter-Signature` header on webhook calls)."}}}}}},"responses":{"200":{"description":"Delivery webhook updated","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/auth/account/api-keys":{"post":{"tags":["Account"],"operationId":"createApiKey","summary":"Create an API key","description":"Creates a new API key for the authenticated org. The key value is shown **once** — store it securely.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128,"description":"Human-readable label for this key."},"expires_at":{"type":"string","format":"date-time","description":"Optional expiry. Omit for non-expiring keys."}}}}}},"responses":{"200":{"description":"API key created. Value shown once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreatedResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/auth/account/api-keys/{keyId}/revoke":{"post":{"tags":["Account"],"operationId":"revokeApiKey","summary":"Revoke an API key","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/KeyId"}],"responses":{"200":{"description":"Key revoked","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/catalog/models":{"get":{"tags":["Catalog"],"operationId":"listModels","summary":"List available models","description":"Returns the full model catalog with routing eligibility, context windows, and per-provider pricing.","parameters":[{"name":"operation","in":"query","schema":{"type":"string","enum":["responses","embeddings","vision"]},"description":"Filter by operation type."},{"name":"provider","in":"query","schema":{"type":"string"},"description":"Filter by provider slug (e.g. `openai`, `anthropic`)."},{"name":"hosted_tool","in":"query","schema":{"type":"string","enum":["web_search","python_execution","calculator","time","file_search","retrieval"]},"description":"Filter by first-class hosted tool metadata. This is separate from `runtime_capability`."}],"responses":{"200":{"description":"Model catalog","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CatalogModel"}},"pricing_updated_at":{"type":["string","null"],"format":"date-time"},"provider_count":{"type":"integer","minimum":0}}}}}}}}},"/v1/catalog/models/{slug}":{"get":{"tags":["Catalog"],"operationId":"getModel","summary":"Get model details","parameters":[{"$ref":"#/components/parameters/Slug"}],"responses":{"200":{"description":"Model details","content":{"application/json":{"schema":{"type":"object","properties":{"model":{"$ref":"#/components/schemas/CatalogModel"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/catalog/workflow-products":{"get":{"tags":["Catalog"],"operationId":"listWorkflowProducts","summary":"List workflow products","description":"Returns all available curated workflow products. Workflow products are predefined outcome contracts with preset manifests (input schema, output schema, SLA, route policy), not a general DAG or orchestration-step engine.","responses":{"200":{"description":"Workflow product catalog","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowProduct"}},"provider_capacity":{"type":"object","additionalProperties":true,"description":"Aggregate provider capacity snapshot at request time."}}}}}}}}},"/v1/catalog/workflow-products/{slug}":{"get":{"tags":["Catalog"],"operationId":"getWorkflowProduct","summary":"Get workflow product details","parameters":[{"$ref":"#/components/parameters/Slug"}],"responses":{"200":{"description":"Workflow product details","content":{"application/json":{"schema":{"type":"object","required":["product"],"properties":{"product":{"$ref":"#/components/schemas/WorkflowProduct"},"provider_capacity":{"type":"object","additionalProperties":true}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/providers":{"get":{"tags":["Providers"],"operationId":"listProviders","summary":"List AI providers","description":"Returns the public provider directory — slugs, display names, supported operations, and enabled status.","responses":{"200":{"description":"Provider directory","content":{"application/json":{"schema":{"type":"object","properties":{"providers":{"type":"array","items":{"$ref":"#/components/schemas/PublicProvider"}}}}}}}}}},"/v1/providers/{slug}":{"get":{"tags":["Providers"],"operationId":"getProvider","summary":"Get provider details","parameters":[{"$ref":"#/components/parameters/Slug"}],"responses":{"200":{"description":"Provider details","content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"$ref":"#/components/schemas/PublicProvider"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/pricing/fees":{"get":{"tags":["Pricing"],"operationId":"getPublicFeeSchedule","summary":"Get BatchRouter fee schedule","description":"Returns the current standard batch fee, workflow-product fee, margin-floor percentages, and per-lane control-plane fee from the active pricing policy.","responses":{"200":{"description":"Public fee schedule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeeScheduleResponse"}}}}}}},"/v1/quotes/model":{"post":{"tags":["Quotes"],"operationId":"createModelQuote","summary":"Create a model quote","x-preflight-validation":{"runs_before_provider_quote":true,"checks":["jsonl_shape","file_type","context_window","tool_support","json_schema","webhook"],"error_details_schema":"#/components/schemas/BatchPreflightResult"},"description":"Returns a cost estimate with selected provider lanes. Mixed-model JSONL is supported: BatchRouter keeps one customer batch but splits execution into model-specific lanes. Pass the `quote_id` to `POST /v1/batches` to accept it.\n\nUse `required_tools` to require provider-hosted tools such as `web_search`, `python_execution`, `calculator`, `time`, `file_search`, or `retrieval`. BatchRouter merges quote-level and item-level requirements, infers supported OpenAI-style tool declarations from items, and rejects lanes whose selected provider offering does not declare every required tool. Route explanations expose this gate as `tool_support` with required and offered tool lists.\n\nEstimate creation is **free** — credits are reserved when you create a batch and settled from actual token usage.","security":[{"customerApiKey":[]},{"customerSession":[]}],"x-payment-info":{"intent":"session","method":["stripe","card"],"currency":"USD","description":"Quote creation is free. Credits are charged at batch creation (POST /v1/batches with quote_id). Purchase credits at https://batchrouter.com/pricing"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelQuoteRequest"}}}},"responses":{"200":{"description":"Quote created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"400":{"$ref":"#/components/responses/PreflightBadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/quotes/workflow":{"post":{"tags":["Quotes"],"operationId":"createWorkflowQuote","summary":"Create a workflow-product quote","x-preflight-validation":{"runs_before_provider_quote":true,"checks":["jsonl_shape","file_type","context_window","tool_support","json_schema","webhook"],"error_details_schema":"#/components/schemas/BatchPreflightResult"},"description":"Quotes a curated workflow product: a versioned outcome contract plus preset manifest. Returns model-agnostic provider lanes that satisfy the workflow contract. Pass the `quote_id` to `POST /v1/batches` to dispatch.\n\nUse `required_tools` to require provider-hosted tools for the workflow. BatchRouter merges quote-level and input-level requirements, infers supported OpenAI-style tool declarations from inputs, and rejects lanes whose selected provider offering does not declare every required tool. Route explanations expose this gate as `tool_support` with required and offered tool lists.","security":[{"customerApiKey":[]},{"customerSession":[]}],"x-payment-info":{"intent":"session","method":["stripe","card"],"currency":"USD","description":"Quote creation is free. Credits are charged at batch creation (POST /v1/batches with quote_id). Purchase credits at https://batchrouter.com/pricing"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowQuoteRequest"}}}},"responses":{"200":{"description":"Workflow-product quote created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"400":{"$ref":"#/components/responses/PreflightBadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/batches":{"post":{"tags":["Batches"],"operationId":"createBatch","summary":"Create a batch","x-preflight-validation":{"runs_before_batch_creation":true,"checks":["jsonl_shape","file_type","context_window","tool_support","json_schema","webhook","routing"],"error_details_schema":"#/components/schemas/BatchPreflightResult"},"description":"Submits a batch job for async processing. Accepts inline items or a reference to an uploaded input file. Mixed-model JSONL/API submissions keep one customer batch and split execution into model-specific lanes.\n\nRequires an `Idempotency-Key` header. Safe to retry with the same key if the network fails.\n\nBefore creating work, BatchRouter runs authoritative preflight validation for JSONL/import shape, file support, context fit, hosted tools, JSON schema/runtime support, routing, and webhook configuration. Failures return `400` with `error.details.preflight`.\n\nIf a `quote_id` is provided the active quote snapshot is used to reserve credits. Final cost is settled from actual provider token usage.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128},"description":"Unique key per logical operation. Re-send the same key to safely retry without creating a duplicate batch."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateRequest"}}}},"responses":{"202":{"description":"Batch accepted and queued for routing. Returns the batch summary and (optionally) the associated work order. Replays of an existing Idempotency-Key return the same response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateResponse"}}}},"400":{"$ref":"#/components/responses/PreflightBadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"409":{"$ref":"#/components/responses/Conflict"}}},"get":{"tags":["Batches"],"operationId":"listBatches","summary":"List batches","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","queued","routing","dispatched","processing","completing","completed","failed","cancelled","expired"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Batch list","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BatchSummary"}},"next_cursor":{"type":["string","null"]},"workspace_total_count":{"type":"integer","minimum":0,"description":"Total number of batches in the authenticated workspace, independent of pagination."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/files":{"post":{"tags":["Files"],"operationId":"uploadModelInputFile","summary":"Upload a model input file","description":"Uploads an image, document, audio, video, JSON, XML, or text file for use by models that support file inputs. Use the returned `file_id` inside batch item content blocks such as `{ \"type\": \"input_image\", \"file_id\": \"file_...\" }` or `{ \"type\": \"input_file\", \"file_id\": \"file_...\" }`.\n\nFile upload acceptance does not mean every model can process the file. Check `GET /v1/catalog/models` for `supports_file_uploads`, `input_modalities`, `accepted_file_types`, and `max_file_size` before enabling upload UI.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"Content-Length","in":"header","required":true,"schema":{"type":"integer","minimum":1},"description":"Exact file size in bytes. Required so BatchRouter can enforce upload limits before storing the body."},{"name":"X-BatchRouter-Filename","in":"header","required":false,"schema":{"type":"string","maxLength":512},"description":"Original filename. URL-encode the value when it contains spaces or non-ASCII characters."},{"name":"X-BatchRouter-Purpose","in":"header","required":false,"schema":{"type":"string","default":"model_input"},"description":"Upload purpose. Defaults to `model_input`."},{"name":"X-Content-SHA256","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Fa-f0-9]{64}$"},"description":"Optional hex SHA-256 digest of the file body."}],"requestBody":{"required":true,"description":"Raw binary file body. Set `Content-Type` to the actual MIME type. Supported categories include image/*, audio/*, video/*, text/*, PDF, Word, PowerPoint, Excel, RTF, JSON, and XML.","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"audio/*":{"schema":{"type":"string","format":"binary"}},"video/*":{"schema":{"type":"string","format":"binary"}},"text/*":{"schema":{"type":"string","format":"binary"}},"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"string","format":"binary"}},"application/xml":{"schema":{"type":"string","format":"binary"}},"application/rtf":{"schema":{"type":"string","format":"binary"}},"application/msword":{"schema":{"type":"string","format":"binary"}},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{"schema":{"type":"string","format":"binary"}},"application/vnd.ms-powerpoint":{"schema":{"type":"string","format":"binary"}},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{"schema":{"type":"string","format":"binary"}},"application/vnd.ms-excel":{"schema":{"type":"string","format":"binary"}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"File uploaded and ready to reference from batch item JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelInputFileUploadResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"411":{"description":"Content-Length is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"File exceeds the configured upload limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Unsupported file content type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/openai/v1/batches":{"get":{"tags":["OpenAI Compatibility"],"operationId":"listOpenAiBatches","summary":"List batches (OpenAI-compatible)","description":"Lists your batches in the OpenAI `{ \"object\": \"list\", \"data\": [...], \"first_id\", \"last_id\", \"has_more\" }` envelope. Use `after=<batch_id>` for pagination, matching the `openai` SDK's `client.batches.list()`.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"after","in":"query","schema":{"type":"string"},"description":"Return batches after this batch id (OpenAI cursor pagination)."}],"responses":{"200":{"description":"OpenAI-shaped list of Batch objects.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/OpenAiBatch"}},"first_id":{"type":["string","null"]},"last_id":{"type":["string","null"]},"has_more":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["OpenAI Compatibility"],"operationId":"createOpenAiBatch","summary":"Create a batch (OpenAI-compatible)","description":"Creates a batch from an uploaded input file, matching the `openai` SDK's `client.batches.create({ input_file_id, endpoint, completion_window })`. Quote-free to the caller — BatchRouter quotes and funding-gates internally by reusing the native create pipeline (identical pricing, limits, and `billing-controls` enforcement). `Idempotency-Key` is optional (the SDK won't send one). Returns a bare OpenAI Batch object. On insufficient funds the error is OpenAI-shaped `{ error: { type: \"insufficient_quota\" } }`.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["input_file_id","endpoint"],"properties":{"input_file_id":{"type":"string","description":"A file id returned by `POST /v1/openai/v1/files` (purpose `batch`)."},"endpoint":{"type":"string","enum":["/v1/chat/completions","/v1/responses","/v1/embeddings"],"description":"The OpenAI endpoint the input rows target. chat/completions & responses route to BatchRouter's `responses` operation; embeddings to `embeddings`."},"completion_window":{"type":"string","enum":["24h"],"default":"24h"},"body_format":{"type":"string","enum":["normalized","raw"],"default":"normalized","description":"Per-batch default for how `response.body` is served on retrieval: `normalized` (BatchRouter's unified cross-provider output, the default) or `raw` (the provider's raw API response, where captured). Overridable per-download with `?body_format=`."},"metadata":{"type":["object","null"],"additionalProperties":true}}}}}},"responses":{"200":{"description":"OpenAI-shaped Batch object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAiBatch"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/openai/v1/batches/{batchId}/cancel":{"post":{"tags":["OpenAI Compatibility"],"operationId":"cancelOpenAiBatch","summary":"Cancel a batch (OpenAI-compatible)","description":"Requests cancellation of an in-flight batch, matching the `openai` SDK's `client.batches.cancel(id)`. Returns the bare OpenAI Batch object with cancellation in progress.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"responses":{"200":{"description":"OpenAI-shaped Batch object (cancellation requested).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAiBatch"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/openai/v1/batches/{batchId}":{"get":{"tags":["OpenAI Compatibility"],"operationId":"getOpenAiBatch","summary":"Retrieve a batch (OpenAI-compatible)","description":"Returns one batch as a bare OpenAI Batch object (`object: \"batch\"`, `status`, `request_counts`, `endpoint`, `completion_window`, `output_file_id`, `error_file_id`). Equivalent to the `openai` SDK's `client.batches.retrieve(id)`. Poll until `status` is `completed`, `failed`, `expired`, or `cancelled`, then download `output_file_id` / `error_file_id` via `/v1/openai/v1/files/{fileId}/content`.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"responses":{"200":{"description":"OpenAI-shaped Batch object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAiBatch"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/openai/v1/files":{"post":{"tags":["OpenAI Compatibility"],"operationId":"createOpenAiFile","summary":"Upload a batch input file (OpenAI-compatible)","description":"Uploads an OpenAI-Batch input file (`purpose: \"batch\"`), matching `client.files.create({ file, purpose: \"batch\" })`. Accepts multipart/form-data (fields `file` + `purpose`). Each JSONL row `{ custom_id, method, url, body }` is converted to a BatchRouter item (`url`→operation, `body.model`→model, `body` minus `model`→input); invalid rows are rejected with an OpenAI-shaped error. Returns the OpenAI File object; pass its `id` as `input_file_id` to `POST /v1/openai/v1/batches`.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","purpose"],"properties":{"file":{"type":"string","format":"binary","description":"OpenAI-Batch JSONL."},"purpose":{"type":"string","enum":["batch"]}}}}}},"responses":{"200":{"description":"OpenAI-shaped File object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAiFile"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/openai/v1/files/{fileId}":{"get":{"tags":["OpenAI Compatibility"],"operationId":"getOpenAiFile","summary":"Retrieve file metadata (OpenAI-compatible)","description":"Returns the OpenAI File metadata object (`object: \"file\"`, `bytes`, `filename`, `purpose`, `status`) for a batch artifact. Equivalent to `client.files.retrieve(id)`. Accepts a signed download token or customer authentication.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"fileId","in":"path","required":true,"schema":{"type":"string"},"description":"File ID (e.g. an `output_file_id` / `error_file_id` from the Batch object)."}],"responses":{"200":{"description":"OpenAI-shaped File object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAiFile"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/openai/v1/files/{fileId}/content":{"get":{"tags":["OpenAI Compatibility"],"operationId":"getOpenAiFileContent","summary":"Download file content (OpenAI-compatible)","description":"Streams the file bytes. For batch result/error artifacts the rows are projected to OpenAI's per-line shape `{ id, custom_id, response: { status_code, request_id, body }, error }`, keyed by `custom_id`. Equivalent to `client.files.content(id)`. `response.body` is BatchRouter's normalized output by default; pass `?body_format=raw` (or set the batch's `body_format`) to get the provider's raw response where captured. The effective format is echoed in the `x-batchrouter-body-format` response header.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"fileId","in":"path","required":true,"schema":{"type":"string"}},{"name":"body_format","in":"query","required":false,"schema":{"type":"string","enum":["normalized","raw"]},"description":"Override the success-line `response.body` format for this download: `normalized` (default) or `raw`. Falls back to the per-batch `body_format`, then the platform default `normalized`. (`body` is accepted as an alias.)"}],"responses":{"200":{"description":"OpenAI-shaped JSONL (one JSON object per line).","content":{"application/jsonl":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"},"410":{"description":"File expired — retention GC reclaimed the bytes. The file row persists (status `expired`), so this is distinct from a never-existed 404."}}}},"/v1/delivery-targets":{"get":{"tags":["Delivery"],"operationId":"listDeliveryTargets","summary":"List delivery targets","description":"Lists the org's configured customer-owned-bucket delivery targets. Secret access keys are never returned.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Delivery targets (no secrets).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryTarget"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Delivery"],"operationId":"createDeliveryTarget","summary":"Register a delivery target","description":"Registers a customer-owned S3-compatible bucket. The `secret_access_key` is stored encrypted and is write-only — it is never returned by any endpoint. The endpoint must be a public HTTPS URL (internal/metadata hosts are rejected).","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["endpoint","region","bucket","access_key_id","secret_access_key"],"properties":{"endpoint":{"type":"string","format":"uri","example":"https://s3.us-east-1.amazonaws.com"},"region":{"type":"string","example":"us-east-1"},"bucket":{"type":"string"},"prefix":{"type":"string"},"access_key_id":{"type":"string"},"secret_access_key":{"type":"string","description":"Write-only; never returned."},"verify_before_gc":{"type":"boolean","default":true},"is_default":{"type":"boolean","default":false}}}}}},"responses":{"201":{"description":"Created delivery target (no secret).","content":{"application/json":{"schema":{"type":"object","properties":{"delivery_target":{"$ref":"#/components/schemas/DeliveryTarget"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/delivery-targets/{id}":{"delete":{"tags":["Delivery"],"operationId":"deleteDeliveryTarget","summary":"Delete a delivery target","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/delivery-targets/{id}/test":{"post":{"tags":["Delivery"],"operationId":"testDeliveryTarget","summary":"Test a delivery target's connectivity","description":"Validates the target's credentials, endpoint, and connectivity with a tiny write+delete probe object (delivery PUTs, so a read-only credential fails). The stored secret is never returned. Returns `{ test: { ok, checked, error? } }` with a classified failure (`credential_error` / `permission_denied` / `bucket_not_found` / `bucket_error` / `unreachable`).","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Probe result (ok true/false).","content":{"application/json":{"schema":{"type":"object","properties":{"test":{"type":"object","properties":{"ok":{"type":"boolean"},"checked":{"type":"string","enum":["write"]},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/retention-settings":{"get":{"tags":["Delivery"],"operationId":"getRetentionSettings","summary":"Get result-retention policy","description":"The org's result-retention policy. Defaults to free `grace_only`.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Retention policy.","content":{"application/json":{"schema":{"type":"object","properties":{"retention_settings":{"$ref":"#/components/schemas/RetentionSettings"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Delivery"],"operationId":"updateRetentionSettings","summary":"Set result-retention policy","description":"Set the org's retention policy. `extended_fixed` requires `extended_days` and is metered (a `storage_charge` against the prepaid wallet) once storage fees are enabled; `never_charge` guarantees zero storage spend (forces free `grace_only`).","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["retention_tier"],"properties":{"retention_tier":{"type":"string","enum":["grace_only","extended_fixed","until_deleted"]},"extended_days":{"type":"integer","minimum":1,"maximum":3650},"never_charge":{"type":"boolean"},"auto_extend":{"type":"boolean"},"fee_acknowledged":{"type":"boolean"},"default_body_format":{"type":["string","null"],"enum":["normalized","raw",null],"description":"Org-level default for the OpenAI-compat `response.body` format. Omitted/null = platform default `normalized`. Overridden per-batch (`metadata.body_format`) and per-request (`?body_format=`)."}}}}}},"responses":{"200":{"description":"Updated retention policy.","content":{"application/json":{"schema":{"type":"object","properties":{"retention_settings":{"$ref":"#/components/schemas/RetentionSettings"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/batches/{batchId}":{"get":{"tags":["Batches"],"operationId":"getBatch","summary":"Get batch status","description":"Returns current status, routing metadata, internal lane statuses, and SLA deadline for one customer batch_id. Poll until `status` is `completed`, `failed`, or `cancelled`.\n\nSet `include_billing_receipt=true` to embed the billing receipt in the same response.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"},{"name":"include_billing_receipt","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Batch detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/batches/{batchId}/webhooks":{"get":{"tags":["Batches"],"operationId":"listBatchWebhookDeliveries","summary":"List batch webhook deliveries","description":"Returns customer-visible webhook delivery status, retry state, last failure details, and persisted delivery events for one batch.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"responses":{"200":{"description":"Webhook delivery status and history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchWebhooksResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/batches/{batchId}/results":{"get":{"tags":["Batches"],"operationId":"getBatchResults","summary":"Get batch results","description":"Returns assembled output for all items. Available once `status` is `completed`.\n\nFor large batches prefer `GET /v1/batches/{batchId}/artifact-url` to get a signed download URL for the full JSONL artifact.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Batch results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResultsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/batches/{batchId}/items":{"get":{"tags":["Batches"],"operationId":"listBatchItems","summary":"List batch items","description":"Returns per-item status, errors, and output previews.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","processing","completed","failed"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Batch items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchItemsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/batches/{batchId}/artifact-url":{"get":{"tags":["Batches"],"operationId":"getBatchArtifactUrl","summary":"Get signed artifact download URL","description":"Returns a short-lived signed URL for the full results JSONL artifact. Preferred over paginated `/results` for large batches.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"responses":{"200":{"description":"Signed artifact URL","content":{"application/json":{"schema":{"type":"object","required":["url","expires_at"],"properties":{"url":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/batches/{batchId}/billing-receipt":{"get":{"tags":["Batches"],"operationId":"getBatchBillingReceipt","summary":"Get batch billing receipt","description":"Returns the finalized billing receipt for a completed batch — provider subtotal, BatchRouter fee, and credit settlement.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"responses":{"200":{"description":"Billing receipt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchBillingReceipt"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/batches/{batchId}/cancel":{"post":{"tags":["Batches"],"operationId":"cancelBatch","summary":"Cancel a batch","description":"Requests cancellation. Batches already dispatched to a provider may complete before the cancellation takes effect — credits for work already in-flight are not refunded.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Cancellation requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDetail"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/batches/{batchId}/redeliver":{"post":{"tags":["Batches"],"operationId":"redeliverBatch","summary":"Re-deliver a batch to its customer bucket","description":"Re-enqueues customer-owned-bucket delivery for a batch whose delivery failed. Idempotent / guarded against double-delivery via the batch's `delivery_status` (409 if already `delivered` or `delivering`). Inert unless `CUSTOMER_BUCKET_DELIVERY` is enabled and the batch has a configured delivery target (else 409).","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"responses":{"202":{"description":"Re-delivery enqueued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/batches/{batchId}/retry":{"post":{"tags":["Batches"],"operationId":"retryBatch","summary":"Retry a failed batch","description":"Re-queues a failed or expired batch for another dispatch attempt. Only available for batches in `failed` or `expired` status.\n\n> **Beta** — behaviour may change.","x-beta":true,"security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/BatchId"}],"responses":{"200":{"description":"Batch re-queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDetail"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/work-orders":{"get":{"tags":["Work Orders"],"operationId":"listWorkOrders","summary":"List work orders","description":"Work orders are server-side job records created for workflow and agent-main-thread runs. Each links to its underlying batch and tracks the full task lifecycle.\n\n> **Beta** — behaviour may change.","x-beta":true,"security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Work order list","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrder"}},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/work-orders/{workOrderId}":{"get":{"tags":["Work Orders"],"operationId":"getWorkOrder","summary":"Get work order","x-beta":true,"security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"$ref":"#/components/parameters/WorkOrderId"}],"responses":{"200":{"description":"Work order detail","content":{"application/json":{"schema":{"type":"object","properties":{"work_order":{"$ref":"#/components/schemas/WorkOrder"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/usage":{"get":{"tags":["Usage"],"operationId":"listCustomerUsage","summary":"List usage receipts","description":"Returns quote-lane based billing receipts. Includes customer-safe provider subtotal, BatchRouter fee, and total. Raw provider cost breakdown is omitted.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"batch_id","in":"query","schema":{"type":"string"},"description":"Filter to a single batch."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Usage receipts","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UsageReceipt"}},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/billing/controls":{"get":{"tags":["Billing"],"operationId":"getBillingControls","summary":"Get spending controls","description":"Returns the org's spending-control configuration: spending limit, low-balance threshold, and alert settings.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Spending controls","content":{"application/json":{"schema":{"type":"object","required":["controls"],"properties":{"controls":{"$ref":"#/components/schemas/BillingControls"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Billing"],"operationId":"updateBillingControls","summary":"Update spending controls","description":"Updates the org's spending limit, low-balance threshold, and alert settings. Supplied fields are merged over the current configuration; nullable fields are cleared by sending `null`. An enabled limit must specify both `limit_period` and `limit_amount`. Requires a signed-in email-based user — API keys without an associated user receive `403 user_session_required`.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingControlsUpdate"}}}},"responses":{"200":{"description":"Updated spending controls","content":{"application/json":{"schema":{"type":"object","required":["controls"],"properties":{"controls":{"$ref":"#/components/schemas/BillingControls"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/billing/controls/audit":{"get":{"tags":["Billing"],"operationId":"listBillingControlsAudit","summary":"List billing-config audit log","description":"Returns recent billing-configuration change-audit entries, newest first.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Audit entries","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BillingConfigAuditEntry"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/billing/auto-topup":{"get":{"tags":["Billing"],"operationId":"getAutoTopup","summary":"Get auto top-up config","description":"Returns the org's auto top-up configuration.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Auto top-up config","content":{"application/json":{"schema":{"type":"object","required":["auto_topup"],"properties":{"auto_topup":{"$ref":"#/components/schemas/AutoTopupConfig"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Billing"],"operationId":"updateAutoTopup","summary":"Update auto top-up config","description":"Updates the org's auto top-up configuration. Supplied fields are merged over the current configuration. Enabling has hard prerequisites: a verified email, a `threshold`, a `target` greater than the threshold, a saved `payment_method_id` belonging to this org, and an environment where off-session charging is configured. Requires a signed-in email-based user — API keys without an associated user receive `403 user_session_required`.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTopupConfigUpdate"}}}},"responses":{"200":{"description":"Updated auto top-up config","content":{"application/json":{"schema":{"type":"object","required":["auto_topup"],"properties":{"auto_topup":{"$ref":"#/components/schemas/AutoTopupConfig"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"503":{"description":"Off-session charging is not configured in this environment (`auto_topup_unavailable`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/billing/auto-topup/attempts":{"get":{"tags":["Billing"],"operationId":"listAutoTopupAttempts","summary":"List auto top-up attempts","description":"Returns recent off-session auto top-up charge attempts, newest first.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Auto top-up attempts","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BillingAutotopupAttempt"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/workflows/agent-main-thread/runs":{"post":{"tags":["Workflows"],"operationId":"createAgentMainThreadRun","summary":"Create an Agent Main Thread run","description":"Submits a single agent inference step as durable async work. Returns a `job_id` immediately; the final result is delivered to the supplied webhook URL with a signed artifact.\n\nRequires an `Idempotency-Key` header.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Required for safe retries."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMainThreadRunRequest"}}}},"responses":{"202":{"description":"Run accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMainThreadRunResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"409":{"$ref":"#/components/responses/Conflict"}}}}},"webhooks":{"billingAlert":{"post":{"tags":["Billing"],"operationId":"billingAlertWebhook","summary":"Spending-alert webhook","description":"Delivered to the org's delivery webhook URL (set via `PUT /v1/auth/account/delivery-webhook`) when a spending alert fires and `alert_webhook_enabled` is true. Verify `X-BatchRouter-Signature` (HMAC-SHA256 over `{timestamp}.{body}` using the webhook secret).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingAlertEvent"}}}},"responses":{"200":{"description":"Return any 2xx to acknowledge receipt."}}}},"autoTopupOutcome":{"post":{"tags":["Billing"],"operationId":"autoTopupOutcomeWebhook","summary":"Auto top-up outcome webhook","description":"Delivered to the org's delivery webhook URL when an auto top-up succeeds, fails, or is disabled after repeated failures. Verify `X-BatchRouter-Signature` as for `billingAlert`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTopupOutcomeEvent"}}}},"responses":{"200":{"description":"Return any 2xx to acknowledge receipt."}}}}},"components":{"securitySchemes":{"customerApiKey":{"type":"http","scheme":"bearer","description":"API key from `POST /v1/auth/agent-register` or the BatchRouter dashboard. New production keys are prefixed `br_live_`; legacy `ob_live_` keys remain valid while active."},"customerSession":{"type":"apiKey","in":"cookie","name":"batchrouter_ui_session","description":"Session cookie set after `POST /v1/auth/login`. Used by the web dashboard."}},"parameters":{"BatchId":{"name":"batchId","in":"path","required":true,"schema":{"type":"string"},"description":"Batch ID (e.g. `bat_abc123`)."},"WorkOrderId":{"name":"workOrderId","in":"path","required":true,"schema":{"type":"string"}},"KeyId":{"name":"keyId","in":"path","required":true,"schema":{"type":"string"}},"Slug":{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}},"schemas":{"ContentBlogPost":{"type":"object","description":"A published blog/news post, mirroring the hub's BlogPost render contract. `body` is an array of discriminated content blocks (p, h2, h3, ul, ol, code, quote, callout, hr, img, kv) carried as raw JSON.","required":["slug","title","description","excerpt","publishedAt","authorId","tags","category","readingMinutes","body"],"properties":{"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"excerpt":{"type":"string"},"publishedAt":{"type":"string","description":"Bare YYYY-MM-DD."},"updatedAt":{"type":"string"},"authorId":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"category":{"type":"string","enum":["Engineering","Product","Routing & Economics","Industry","Company"]},"featured":{"type":"boolean"},"readingMinutes":{"type":"integer"},"coverEmoji":{"type":"string"},"coverGradient":{"type":"string"},"body":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string"}},"additionalProperties":true}}}},"OpenAiBatch":{"type":"object","description":"An OpenAI-Batch-compatible Batch object projected from a native BatchRouter batch.","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["batch"]},"endpoint":{"type":"string","example":"/v1/chat/completions"},"errors":{"type":["object","null"]},"input_file_id":{"type":["string","null"]},"completion_window":{"type":"string","example":"24h"},"status":{"type":"string","enum":["validating","in_progress","finalizing","completed","failed","expired","cancelling","cancelled"]},"output_file_id":{"type":["string","null"]},"error_file_id":{"type":["string","null"]},"created_at":{"type":["integer","null"],"description":"Unix epoch seconds."},"in_progress_at":{"type":["integer","null"]},"expires_at":{"type":["integer","null"]},"finalizing_at":{"type":["integer","null"]},"completed_at":{"type":["integer","null"]},"failed_at":{"type":["integer","null"]},"expired_at":{"type":["integer","null"]},"cancelling_at":{"type":["integer","null"]},"cancelled_at":{"type":["integer","null"]},"request_counts":{"type":"object","properties":{"total":{"type":"integer"},"completed":{"type":"integer"},"failed":{"type":"integer"}}},"metadata":{"type":["object","null"]}}},"OpenAiFile":{"type":"object","description":"An OpenAI-compatible File metadata object for a batch artifact.","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["file"]},"bytes":{"type":"integer"},"created_at":{"type":["integer","null"],"description":"Unix epoch seconds."},"filename":{"type":"string"},"purpose":{"type":"string","example":"batch_output"},"status":{"type":"string","enum":["processed","expired"],"description":"`processed` = downloadable; `expired` = retention GC reclaimed the bytes (the file row persists, so this is distinct from a never-existed file). An `expired` file returns 410 from `/content`."},"expires_at":{"type":["integer","null"]}}},"DeliveryTarget":{"type":"object","description":"A customer-owned S3-compatible bucket delivery target. The secret access key is never included.","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["s3"]},"endpoint":{"type":"string","format":"uri"},"region":{"type":"string"},"bucket":{"type":"string"},"prefix":{"type":["string","null"]},"access_key_id":{"type":"string"},"verify_before_gc":{"type":"boolean"},"is_default":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"RetentionSettings":{"type":"object","description":"Org result-retention policy. Extended tiers are metered (storage_charge) when storage fees are enabled.","properties":{"retention_tier":{"type":"string","enum":["grace_only","extended_fixed","until_deleted"]},"extended_days":{"type":["integer","null"]},"never_charge":{"type":"boolean"},"auto_extend":{"type":"boolean"},"fee_acknowledged":{"type":"boolean"},"default_body_format":{"type":["string","null"],"enum":["normalized","raw",null]},"updated_at":{"type":["string","null"]}}},"BillingAlertThreshold":{"type":"object","required":["type","value"],"properties":{"type":{"type":"string","enum":["balance_below","spend_above","pct_of_limit"]},"value":{"type":"number","minimum":0,"maximum":1000000,"description":"USD dollars for `balance_below` / `spend_above`; a whole percent (0–100) for `pct_of_limit`."}}},"BillingControls":{"type":"object","description":"An org's spending-control configuration. `configured` is `false` with default values until controls are first saved.","required":["org_id","configured","limit_enabled","limit_period","limit_amount","limit_mode","limit_timezone","low_balance_amount","alert_thresholds","alert_email_enabled","alert_webhook_enabled","created_at","updated_at"],"properties":{"org_id":{"type":"string"},"configured":{"type":"boolean","description":"`false` until the org saves controls for the first time."},"limit_enabled":{"type":"boolean"},"limit_period":{"type":["string","null"],"enum":["daily","monthly",null]},"limit_amount":{"oneOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Spending limit for the period."},"limit_mode":{"type":"string","enum":["soft","hard"],"description":"`soft` alerts only; `hard` blocks new spend once the limit is reached."},"limit_timezone":{"type":"string"},"low_balance_amount":{"oneOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Balance level that triggers the low-balance alert."},"alert_thresholds":{"type":"array","items":{"$ref":"#/components/schemas/BillingAlertThreshold"}},"alert_email_enabled":{"type":"boolean"},"alert_webhook_enabled":{"type":"boolean","description":"When `true`, billing alerts are also delivered to the org's delivery webhook (see `webhooks`)."},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"BillingControlsUpdate":{"type":"object","description":"Partial update of spending controls. All fields optional; supplied fields are merged over the current configuration. Nullable fields are cleared by sending `null`. Money fields are USD dollars (numbers).","additionalProperties":false,"properties":{"limit_enabled":{"type":"boolean"},"limit_period":{"type":["string","null"],"enum":["daily","monthly",null]},"limit_amount":{"type":["number","null"],"minimum":0,"maximum":1000000,"description":"USD dollars. Required (with `limit_period`) when `limit_enabled` is `true`."},"limit_mode":{"type":"string","enum":["soft","hard"]},"limit_timezone":{"type":"string","minLength":1,"maxLength":64},"low_balance_amount":{"type":["number","null"],"minimum":0,"maximum":1000000},"alert_thresholds":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/BillingAlertThreshold"}},"alert_email_enabled":{"type":"boolean"},"alert_webhook_enabled":{"type":"boolean"}}},"AutoTopupConfig":{"type":"object","description":"Auto top-up configuration. When enabled, a saved card is charged off-session to refill credits once the balance drops below `threshold`. `consecutive_failures` and `paused_reason` are system-managed.","required":["org_id","configured","enabled","threshold","target","payment_method_id","max_per_day","monthly_ceiling","consecutive_failures","paused_reason","oncredit_exhausted"],"properties":{"org_id":{"type":"string"},"configured":{"type":"boolean"},"enabled":{"type":"boolean"},"threshold":{"oneOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Balance that triggers a refill."},"target":{"oneOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Balance to refill up to. Must exceed `threshold`."},"payment_method_id":{"type":["string","null"]},"max_per_day":{"type":["integer","null"],"description":"Maximum auto top-ups per day; `null` means no cap."},"monthly_ceiling":{"oneOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Maximum total auto top-up spend per month; `null` means no cap."},"consecutive_failures":{"type":"integer"},"paused_reason":{"type":["string","null"]},"oncredit_exhausted":{"type":"string","enum":["block","pause"],"description":"Behaviour when credits run out: hard-block new batches, or pause gracefully."}}},"AutoTopupConfigUpdate":{"type":"object","description":"Partial update of auto top-up config. All fields optional; supplied fields are merged over the current configuration. Money fields are USD dollars (numbers). Enabling requires `threshold`, `target` (> threshold), and a saved `payment_method_id`, plus a verified email.","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"threshold":{"type":["number","null"],"minimum":0,"maximum":1000000},"target":{"type":["number","null"],"minimum":0,"maximum":1000000},"payment_method_id":{"type":["string","null"],"minLength":1,"maxLength":255},"max_per_day":{"type":["integer","null"],"minimum":1,"maximum":1000},"monthly_ceiling":{"type":["number","null"],"minimum":0,"maximum":1000000},"oncredit_exhausted":{"type":"string","enum":["block","pause"]}}},"BillingAutotopupAttempt":{"type":"object","description":"One off-session auto top-up charge attempt.","required":["id","org_id","idempotency_key","trigger_balance","amount","payment_method_id","stripe_payment_intent_id","status","failure_code","credited_transaction_id","created_at","updated_at"],"properties":{"id":{"type":"string"},"org_id":{"type":"string"},"idempotency_key":{"type":"string"},"trigger_balance":{"$ref":"#/components/schemas/Money"},"amount":{"$ref":"#/components/schemas/Money"},"payment_method_id":{"type":"string"},"stripe_payment_intent_id":{"type":["string","null"]},"status":{"type":"string","enum":["pending","succeeded","requires_action","failed"]},"failure_code":{"type":["string","null"]},"credited_transaction_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"BillingConfigAuditEntry":{"type":"object","description":"One audit entry per billing-config change. System/sweep changes have a null actor.","required":["id","org_id","actor_user_id","actor_role","action","before","after","ip_address","created_at"],"properties":{"id":{"type":"string"},"org_id":{"type":"string"},"actor_user_id":{"type":["string","null"]},"actor_role":{"type":["string","null"],"enum":["owner","admin","member","billing",null]},"action":{"type":"string","description":"e.g. `controls.update`, `auto_topup.update`."},"before":{"type":["object","null"],"additionalProperties":true},"after":{"type":["object","null"],"additionalProperties":true},"ip_address":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}},"BillingAlertEvent":{"type":"object","description":"A spending-alert event delivered to the org's delivery webhook when `alert_webhook_enabled` is true. Signed identically to batch webhooks (`X-BatchRouter-Signature` = base64url HMAC-SHA256 of `{timestamp}.{body}`; the timestamp is sent in `X-BatchRouter-Timestamp` and the event type in `X-BatchRouter-Event`).","required":["type","id","created_at","organization","billing"],"properties":{"type":{"type":"string","enum":["billing.balance_low","billing.limit_reached","billing.limit_threshold_reached"]},"id":{"type":"string","description":"Event id, prefixed `evt_`."},"created_at":{"type":"string","format":"date-time"},"organization":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"billing":{"oneOf":[{"type":"object","description":"`billing.balance_low` — available balance fell below `low_balance_amount`.","required":["org_id","status","available_usd","threshold_usd"],"properties":{"org_id":{"type":"string"},"status":{"const":"balance_low"},"available_usd":{"type":"string","description":"Decimal USD string."},"threshold_usd":{"type":"string","description":"Decimal USD string."}}},{"type":"object","description":"`billing.limit_reached` — committed spend met the period limit.","required":["org_id","status","period","spent_usd","limit_usd"],"properties":{"org_id":{"type":"string"},"status":{"const":"limit_reached"},"period":{"type":"string","enum":["daily","monthly"]},"spent_usd":{"type":"string","description":"Decimal USD string."},"limit_usd":{"type":"string","description":"Decimal USD string."}}},{"type":"object","description":"`billing.limit_threshold_reached` (percent-of-limit) — crossed a `pct_of_limit` threshold.","required":["org_id","status","period","threshold_pct","spent_usd","limit_usd"],"properties":{"org_id":{"type":"string"},"status":{"const":"limit_threshold_reached"},"period":{"type":"string","enum":["daily","monthly"]},"threshold_pct":{"type":"number","description":"The configured percent (0–100)."},"spent_usd":{"type":"string","description":"Decimal USD string."},"limit_usd":{"type":"string","description":"Decimal USD string."}}},{"type":"object","description":"`billing.limit_threshold_reached` (spend-above) — monthly spend crossed an absolute `spend_above` threshold.","required":["org_id","status","period","threshold_usd","spent_usd"],"properties":{"org_id":{"type":"string"},"status":{"const":"spend_above"},"period":{"const":"monthly"},"threshold_usd":{"type":"number","description":"The configured USD amount."},"spent_usd":{"type":"string","description":"Decimal USD string."}}}]}}},"AutoTopupOutcomeEvent":{"type":"object","description":"An auto top-up outcome event delivered to the org's delivery webhook. Signed identically to `BillingAlertEvent`.","required":["type","id","created_at","organization","billing"],"properties":{"type":{"type":"string","enum":["billing.autotopup.succeeded","billing.autotopup.failed","billing.autotopup.disabled"]},"id":{"type":"string","description":"Event id, prefixed `evt_`."},"created_at":{"type":"string","format":"date-time"},"organization":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"billing":{"type":"object","required":["outcome","amount","failure_code"],"properties":{"outcome":{"type":"string","enum":["succeeded","failed","disabled"]},"amount":{"oneOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Credited amount; `null` for failed/disabled."},"failure_code":{"type":["string","null"]}}}}},"Money":{"type":"object","required":["currency","amount"],"properties":{"currency":{"const":"usd"},"amount":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?$","description":"Decimal string (e.g. `\"1.50\"`)."}}},"CustomerPricingEstimate":{"type":"object","required":["currency","total"],"properties":{"currency":{"const":"usd"},"provider_subtotal":{"type":"string"},"batchrouter_fee":{"type":"string"},"customer_discount":{"type":"string"},"total":{"type":"string"},"control_plane_fee_total":{"type":"string"},"control_plane_fee_per_lane":{"type":["string","null"]},"control_plane_lane_count":{"type":"integer","minimum":0},"workflow_fee_total":{"type":"string"},"workflow_fees":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"FeeScheduleResponse":{"type":"object","required":["fee_schedule"],"properties":{"fee_schedule":{"type":"object","required":["default_margin_bps","workflow_margin_bps","margin_floor_bps","control_plane_fee_per_lane_usd","source","updated_at"],"properties":{"default_margin_bps":{"type":"integer","minimum":0,"description":"BatchRouter standard batch fee in basis points (e.g. 500 = 5%)."},"workflow_margin_bps":{"type":"integer","minimum":0,"description":"BatchRouter workflow-product fee in basis points."},"margin_floor_bps":{"type":"integer","minimum":0},"control_plane_fee_per_lane_usd":{"type":"string","pattern":"^\\d+(\\.\\d+)?$","description":"Minimum BatchRouter control-plane fee charged per internal provider execution lane."},"source":{"enum":["active_policy","defaults"]},"updated_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":false}},"additionalProperties":true},"RegisterRequest":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"display_name":{"type":"string","maxLength":128},"turnstile_token":{"type":"string","description":"Cloudflare Turnstile CAPTCHA token. Required for browser-based sign-up forms."}}},"RegisterResponse":{"type":"object","properties":{"org_id":{"type":"string"},"user_id":{"type":"string"},"email_verification_required":{"type":"boolean"}}},"AgentRegisterRequest":{"type":"object","properties":{"org_name":{"type":"string","maxLength":128,"description":"Optional display name for the org."},"contact_email":{"type":"string","format":"email","description":"Optional contact email for billing notifications."},"agent_name":{"type":"string","maxLength":128,"description":"Optional display name for the API key."}}},"AgentRegisterResponse":{"type":"object","required":["org_id","api_key"],"properties":{"org_id":{"type":"string"},"api_key":{"type":"string","description":"Bearer API key — shown **once**, store securely."},"api_key_id":{"type":"string"}}},"LoginRequest":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"},"turnstile_token":{"type":"string"}}},"LoginResponse":{"type":"object","properties":{"user_id":{"type":"string"},"org_id":{"type":"string"},"session_id":{"type":"string"}}},"SessionResponse":{"type":"object","properties":{"org_id":{"type":"string"},"user_id":{"type":["string","null"]},"api_key_id":{"type":["string","null"]},"auth_method":{"type":"string","enum":["api_key","session"]},"capabilities":{"type":"array","items":{"type":"string"}}}},"AccountResponse":{"type":"object","properties":{"org_id":{"type":"string"},"display_name":{"type":["string","null"]},"plan":{"type":"string"},"credit_balance":{"$ref":"#/components/schemas/Money"},"members":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"full_name":{"type":["string","null"]}}}}},"additionalProperties":true},"ApiKeyCreatedResponse":{"type":"object","required":["api_key","api_key_id"],"properties":{"api_key":{"type":"string","description":"Full API key value — shown once."},"api_key_id":{"type":"string"},"name":{"type":["string","null"]},"expires_at":{"type":["string","null"],"format":"date-time"}}},"CatalogModel":{"type":"object","properties":{"slug":{"type":"string"},"display_name":{"type":"string"},"provider":{"type":"string"},"operations":{"type":"array","items":{"type":"string","enum":["responses","embeddings","vision"]}},"context_window":{"type":["integer","null"]},"max_input_tokens":{"type":["integer","null"]},"max_output_tokens":{"type":["integer","null"]},"input_modalities":{"type":"array","items":{"type":"string","enum":["text","image","document","audio","video"]},"description":"Input modalities this model can accept through BatchRouter item payloads."},"accepted_file_types":{"type":"array","items":{"type":"string"},"description":"MIME types or MIME wildcards accepted by the model upload UX, such as `image/*` or `application/pdf`."},"max_file_size":{"type":["integer","null"],"minimum":1,"description":"Maximum accepted upload size in bytes when `supports_file_uploads` is true."},"supports_file_uploads":{"type":"boolean","description":"True when the model can reference files uploaded through `POST /v1/files`."},"hosted_tools":{"type":"array","items":{"type":"string","enum":["web_search","python_execution","calculator","time","file_search","retrieval"]},"description":"Hosted tools available with this model offering, separate from model runtime capabilities."},"capability_source":{"type":"string","enum":["provider_offering","provider_model_rate_card","static_catalog"],"description":"Source used for public capability, tool-support, and file-support metadata. Offering-backed models use `provider_offering`."},"provider_offerings":{"type":"array","description":"Provider offering snapshots that are the source of truth for capabilities, tool support, file support, context limits, and provider-declared prices.","items":{"type":"object","properties":{"source":{"type":"string","enum":["provider_offering"]},"provider":{"type":"string"},"provider_name":{"type":"string"},"provider_offering_id":{"type":"string"},"offering_version":{"type":"integer"},"task_type":{"type":"string","enum":["responses","embeddings","vision"]},"context_window":{"type":"integer"},"max_input_tokens":{"type":"integer"},"max_output_tokens":{"type":"integer"},"runtime_capabilities":{"type":"array","items":{"type":"string"}},"hosted_tools":{"type":"array","items":{"$ref":"#/components/schemas/HostedTool"}},"accepted_file_types":{"type":"array","items":{"type":"string"}},"supports_file_uploads":{"type":"boolean"},"data_collection":{"type":"string","enum":["allow","deny"]},"supports_zdr":{"type":"boolean"},"retention_days":{"type":["integer","null"]},"training_use":{"type":["string","null"],"enum":["allow","deny","unknown",null]},"privacy_terms_url":{"type":["string","null"],"format":"uri"},"artifact_handling":{"enum":["batchrouter_artifact_store"]},"privacy_tiers":{"type":"array","items":{"type":"string"}},"regions":{"type":"array","items":{"type":"string"}},"metadata_verification_status":{"enum":["verified","unverified","undeclared"]},"metadata_unverified_reasons":{"type":"array","items":{"enum":["retention_undeclared","zdr_undeclared","artifact_policy_undeclared","regions_undeclared"]}},"price":{"type":"object","additionalProperties":true},"status":{"type":"string","enum":["active","paused","deprecated","disabled"]},"capacity_status":{"type":"string","enum":["active","draining","paused"]},"available_queue_items":{"type":["integer","null"]},"available_queue_tokens":{"type":["integer","null"]},"capacity_expires_at":{"type":["string","null"],"format":"date-time"},"capacity_updated_at":{"type":["string","null"],"format":"date-time"},"heartbeat_ttl_seconds":{"type":"integer"},"last_heartbeat_at":{"type":["string","null"],"format":"date-time"},"capacity_freshness":{"type":"object","required":["state","capacity_refreshed_at","last_heartbeat_at","heartbeat_ttl_seconds","stale_after","reason"],"properties":{"state":{"type":"string","enum":["fresh","stale_heartbeat","unknown"]},"capacity_refreshed_at":{"type":["string","null"],"format":"date-time"},"last_heartbeat_at":{"type":["string","null"],"format":"date-time"},"heartbeat_ttl_seconds":{"type":"integer"},"stale_after":{"type":["string","null"],"format":"date-time"},"reason":{"type":"string"}},"additionalProperties":true,"description":"Normalized live-capacity freshness derived from provider capacity updates, heartbeat TTL, and capacity expiry. `stale_heartbeat` lanes are not treated as live routable supply."},"feedback_accept_count":{"type":"integer"},"feedback_reject_count":{"type":"integer"},"feedback_capacity_reject_count":{"type":"integer"},"feedback_throttle_reject_count":{"type":"integer"},"feedback_timeout_count":{"type":"integer"},"feedback_completed_count":{"type":"integer"},"feedback_avg_completion_seconds":{"type":["number","null"]}},"additionalProperties":true}},"is_available":{"type":"boolean"}},"additionalProperties":true},"WorkflowProduct":{"type":"object","properties":{"slug":{"type":"string"},"display_name":{"type":"string"},"description":{"type":["string","null"]},"sla_tier":{"type":"string"},"latest_version_id":{"type":["string","null"]}},"additionalProperties":true},"HostedTool":{"type":"string","enum":["web_search","python_execution","calculator","time","file_search","retrieval"],"description":"Provider-hosted tool that may be declared by a provider offering and required by quote or batch items. This is separate from model runtime capabilities such as tool calling or JSON schema support."},"RequiredHostedTools":{"type":"array","maxItems":12,"uniqueItems":true,"items":{"$ref":"#/components/schemas/HostedTool"},"description":"Provider-hosted tools that must be available on every selected lane for the scoped quote item, workflow input, or batch item. Quote-level `required_tools` apply to every planned item/input; item-level or input-level `required_tools` are merged with the quote-level list. BatchRouter also infers supported OpenAI-style tool declarations from item payloads. During routing, a lane is eligible only when the selected provider offering declares every required value in `hosted_tools`; otherwise the lane is rejected with a `tool_support` eligibility failure. If no eligible lane remains, quote creation fails rather than routing to a lane that lacks the requested tools.","examples":[["web_search"],["web_search","python_execution"]]},"BatchPreflightIssue":{"type":"object","required":["category","code","message","action"],"properties":{"category":{"type":"string","enum":["jsonl_shape","file_type","context_window","tool_support","json_schema","webhook","routing"],"description":"Preflight validation area that failed or produced a warning."},"code":{"type":"string","description":"Stable machine-readable issue code, for example `provider_hosted_tool_mismatch`, `provider_runtime_capability_mismatch`, `preflight_context_window_exceeded`, or `https_required`."},"message":{"type":"string"},"action":{"type":"string","description":"Customer-facing remediation guidance that can be shown before quote creation or batch submission."},"path":{"type":"string","description":"Optional request path or item group reference for the issue."},"details":{"type":"object","additionalProperties":true}},"additionalProperties":false},"BatchPreflightResult":{"type":"object","required":["ok","errors","warnings"],"properties":{"ok":{"type":"boolean"},"errors":{"type":"array","items":{"$ref":"#/components/schemas/BatchPreflightIssue"}},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/BatchPreflightIssue"}}},"additionalProperties":false,"description":"Preflight validation result. Quote and batch submission endpoints return this under `error.details.preflight` when JSONL shape, file support, context fit, hosted tools, JSON schema/runtime capability, routing, or webhook configuration must be fixed before spending credits or creating work."},"BatchPreflightError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","details"],"properties":{"code":{"type":"string","description":"Usually `batch_preflight_failed`; unsafe webhook and manifest/file errors may preserve their more specific code."},"message":{"type":"string"},"details":{"type":"object","required":["preflight"],"properties":{"preflight":{"$ref":"#/components/schemas/BatchPreflightResult"}},"additionalProperties":true}}}}},"PublicProvider":{"type":"object","properties":{"slug":{"type":"string"},"display_name":{"type":"string"},"description":{"type":["string","null"]},"is_enabled":{"type":"boolean"},"supported_operations":{"type":"array","items":{"type":"string"}},"models":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"ModelQuoteRequest":{"type":"object","required":["items"],"properties":{"operation":{"enum":["responses","embeddings","vision"],"description":"AI operation type. Defaults to `responses`."},"model":{"type":"string","description":"Preferred model slug (e.g. `gpt-4o`). Use `models` for a fallback list."},"models":{"type":"array","items":{"type":"string"},"description":"Ordered list of acceptable model slugs. BatchRouter selects the cheapest available."},"routing_mode":{"enum":["cheapest","sla_aware","public_only","edge_only","hybrid","privacy_constrained"],"default":"cheapest"},"required_tools":{"$ref":"#/components/schemas/RequiredHostedTools","description":"Hosted tools every item in this direct-route quote requires. BatchRouter merges this list with item-level requirements and rejects provider lanes that do not declare every requested tool."},"items":{"type":"array","minItems":1,"items":{"type":"object","additionalProperties":true},"description":"Sample batch items to price. Can be a representative subset — not all items need be sent for quoting. Items may declare different models for mixed-model execution."},"quote_id":{"type":"string","description":"Re-use a previously obtained quote ID."},"max_price":{"$ref":"#/components/schemas/Money"}}},"WorkflowQuoteRequest":{"type":"object","properties":{"workflow":{"oneOf":[{"type":"string","description":"Workflow product slug."},{"type":"object","properties":{"slug":{"type":"string"},"version_id":{"type":"string"},"version_number":{"type":"integer","minimum":1}},"additionalProperties":false}]},"input":{"type":"object","additionalProperties":true,"description":"Single item input."},"inputs":{"type":"array","items":{"type":"object","properties":{"customer_item_id":{"type":"string"},"required_tools":{"$ref":"#/components/schemas/RequiredHostedTools","description":"Hosted tools this workflow input requires. These are merged with workflow quote-level `required_tools` before lane eligibility is evaluated."},"input":{"type":"object","additionalProperties":true},"metadata":{"type":"object","additionalProperties":true}},"additionalProperties":true},"description":"Multiple inputs for batch quoting."},"required_tools":{"$ref":"#/components/schemas/RequiredHostedTools","description":"Hosted tools every workflow input requires. BatchRouter merges this list with per-input requirements and rejects provider lanes that do not declare every requested tool."},"max_price":{"$ref":"#/components/schemas/Money"}}},"LaneDataPrivacyProof":{"type":"object","required":["data_collection","supports_zdr","retention_days","artifact_handling","privacy_tiers","regions","metadata_verification_status","metadata_unverified_reasons"],"properties":{"data_collection":{"enum":["allow","deny"],"description":"`deny` means the provider declares no prompt/output collection beyond transient processing and required operational metadata."},"supports_zdr":{"type":"boolean","description":"Whether this lane supports zero data retention style routing requirements."},"retention_days":{"type":["integer","null"],"description":"Provider-declared retention window in days, or null when not published."},"training_use":{"type":["string","null"],"enum":["allow","deny","unknown",null]},"privacy_terms_url":{"type":["string","null"],"format":"uri"},"artifact_handling":{"enum":["batchrouter_artifact_store"],"description":"How BatchRouter handles output artifacts for this lane."},"privacy_tiers":{"type":"array","items":{"type":"string"}},"regions":{"type":"array","items":{"type":"string"}},"metadata_verification_status":{"enum":["verified","unverified","undeclared"],"description":"`undeclared` lanes are not routable as public supply. `unverified` means the provider or operator deliberately exposed incomplete metadata as unverified."},"metadata_unverified_reasons":{"type":"array","items":{"enum":["retention_undeclared","zdr_undeclared","artifact_policy_undeclared","regions_undeclared"]}}},"additionalProperties":false},"QuoteLane":{"type":"object","required":["id","provider","model","selected","price"],"properties":{"id":{"type":"string"},"provider":{"type":"string"},"model":{"type":"string"},"selected":{"type":"boolean"},"item_sequence_count":{"type":"integer"},"price":{"$ref":"#/components/schemas/CustomerPricingEstimate"},"data_privacy":{"oneOf":[{"$ref":"#/components/schemas/LaneDataPrivacyProof"},{"type":"null"}]},"rejection_code":{"type":["string","null"],"description":"Normalized rejection receipt code for non-selected ineligible lanes, for example `capacity_full`, `stale_heartbeat`, `missing_web_search`, `context_window_exceeded`, `privacy_tier_mismatch`, or `region_unavailable`."},"rejection_reason":{"type":["string","null"],"description":"Customer-safe explanation for why the lane was rejected or not selected."},"rejection_receipt":{"oneOf":[{"type":"object","required":["code","reason","status"],"properties":{"code":{"type":["string","null"]},"reason":{"type":["string","null"]},"status":{"type":["string","null"],"enum":["not_selected","not_eligible","fallback",null]},"raw_code":{"type":["string","null"]},"category":{"type":["string","null"]},"failed_checks":{"type":"array","items":{"type":"object","additionalProperties":true}},"details":{"type":"object","additionalProperties":true}},"additionalProperties":true},{"type":"null"}],"description":"Persisted lane rejection receipt with normalized code, raw router code, failed eligibility checks, and provider/offer details."}},"additionalProperties":true},"QuoteResponse":{"type":"object","required":["quote_id","pricing_estimate","quote_lanes"],"properties":{"quote_id":{"type":"string","description":"Pass to `POST /v1/batches` as `quote_id` to accept the estimate and reserve credits before dispatch."},"pricing_estimate":{"$ref":"#/components/schemas/CustomerPricingEstimate"},"quote_lanes":{"type":"array","items":{"$ref":"#/components/schemas/QuoteLane"}},"customer_explanation":{"type":"object","additionalProperties":true}},"additionalProperties":true},"BatchItem":{"type":"object","required":["customer_item_id","operation","model","input"],"properties":{"customer_item_id":{"type":"string","minLength":1,"maxLength":128,"description":"Your stable identifier for this item — returned verbatim in results."},"operation":{"enum":["responses","embeddings","vision"]},"model":{"type":"string","description":"Model slug (e.g. `gpt-4o`, `claude-3-5-sonnet`). Mixed-model batches can set different model values on different items."},"model_options":{"type":"array","items":{"type":"string"},"description":"Fallback model slugs in priority order."},"required_tools":{"$ref":"#/components/schemas/RequiredHostedTools","description":"Hosted tools this item requires, such as `web_search`, `python_execution`, `calculator`, `time`, `file_search`, or `retrieval`. Batch-level `required_tools` are merged with this list."},"input":{"type":"object","additionalProperties":true,"description":"OpenAI Batch API compatible input — `messages`, `input`, or embeddings `input` field."},"metadata":{"type":"object","additionalProperties":true}}},"BatchCreateRequest":{"type":"object","properties":{"items":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/BatchItem"},"description":"Inline batch items. Provide either `items` or `input_file_id`, not both. Different item models create model-specific internal lanes under one customer batch."},"input_file_id":{"type":"string","description":"ID of a previously uploaded JSONL file. Alternative to inline `items`. Mixed-model JSONL is supported."},"quote_id":{"type":"string","pattern":"^qlock_[A-Za-z0-9_-]+$","description":"Accept a cost estimate from `POST /v1/quotes/model` and reserve credits before dispatch."},"sla_tier":{"enum":["standard","flex","priority"],"default":"standard","description":"`standard` — 24h SLA. `flex` — up to 48h, lower price. `priority` — expedited."},"routing_mode":{"enum":["cheapest","sla_aware","public_only","edge_only","hybrid","privacy_constrained"],"default":"cheapest"},"privacy_tier":{"enum":["standard","confidential","restricted"],"default":"standard","description":"`confidential` routes to providers with data-retention opt-out. `restricted` routes only to private BatchProviderApi nodes."},"allowed_regions":{"type":"array","items":{"type":"string"},"default":["global"],"description":"Geographic constraints (e.g. `[\"eu\", \"us\"]`)."},"max_price":{"$ref":"#/components/schemas/Money","description":"Hard price ceiling. Batch is rejected if no eligible lane is within this."},"required_tools":{"$ref":"#/components/schemas/RequiredHostedTools","description":"Hosted tools every item in this batch requires. Item-level `required_tools` are merged with this list."},"webhook":{"type":"object","required":["url","secret"],"properties":{"url":{"type":"string","format":"uri"},"secret":{"type":"string","minLength":8,"maxLength":256,"description":"HMAC-SHA256 secret for `X-BatchRouter-Signature` on webhook delivery."}}},"metadata":{"type":"object","additionalProperties":true}}},"BatchCreateResponse":{"type":"object","properties":{"batch":{"$ref":"#/components/schemas/BatchSummary"},"work_order":{"oneOf":[{"$ref":"#/components/schemas/WorkOrder"},{"type":"null"}]},"work_order_url":{"type":["string","null"]}}},"ModelInputFile":{"type":"object","required":["id","kind","content_type","size_bytes","filename","media_kind","created_at"],"properties":{"id":{"type":"string","description":"File identifier to reference from batch item JSON."},"kind":{"type":"string","const":"input_attachment"},"content_type":{"type":"string"},"size_bytes":{"type":"integer","minimum":1},"sha256":{"type":["string","null"],"pattern":"^[A-Fa-f0-9]{64}$"},"filename":{"type":["string","null"]},"media_kind":{"type":["string","null"],"enum":["image","document","audio","video","file",null]},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":false},"ModelInputFileUsage":{"type":"object","properties":{"image_block":{"type":"object","required":["type","file_id"],"properties":{"type":{"type":"string","const":"input_image"},"file_id":{"type":"string"}},"additionalProperties":false},"file_block":{"type":"object","required":["type","file_id"],"properties":{"type":{"type":"string","const":"input_file"},"file_id":{"type":"string"},"filename":{"type":["string","null"]}},"additionalProperties":false}},"additionalProperties":false},"ModelInputFileUploadResponse":{"type":"object","required":["file_id","file","usage"],"properties":{"file_id":{"type":"string","description":"Use this in item content blocks as `file_id`."},"file":{"$ref":"#/components/schemas/ModelInputFile"},"usage":{"$ref":"#/components/schemas/ModelInputFileUsage"}},"additionalProperties":false},"BatchSummary":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","queued","routing","dispatched","processing","completing","completed","failed","cancelled","expired"]},"item_count":{"type":["integer","null"]},"created_at":{"type":"string","format":"date-time"},"sla_deadline":{"type":["string","null"],"format":"date-time"},"quote_id":{"type":["string","null"]},"routing_mode":{"type":["string","null"]},"sla_tier":{"type":["string","null"]}},"additionalProperties":true},"BatchDetail":{"allOf":[{"$ref":"#/components/schemas/BatchSummary"},{"type":"object","properties":{"error":{"type":["string","null"]},"completed_at":{"type":["string","null"],"format":"date-time"},"billing_receipt":{"oneOf":[{"$ref":"#/components/schemas/BatchBillingReceipt"},{"type":"null"}]},"lane_statuses":{"type":"array","description":"Per-lane status objects for the internal provider/model executions under this single customer batch_id.","items":{"type":"object","additionalProperties":true}}}}]},"WebhookDelivery":{"type":"object","required":["id","batch_id","url","status","attempt_count","created_at","updated_at"],"properties":{"id":{"type":"string"},"batch_id":{"type":"string"},"url":{"type":"string","format":"uri"},"status":{"type":"string","description":"Current delivery state, such as pending, delivering, succeeded, failed, or dead_lettered."},"attempt_count":{"type":"integer","minimum":0},"last_attempt_at":{"type":["string","null"],"format":"date-time"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"last_response_status":{"type":["integer","null"],"minimum":100,"maximum":599},"last_error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":false},"WebhookDeliveryEvent":{"type":"object","required":["id","event","status","webhook_id","batch_id","org_id","created_at"],"properties":{"id":{"type":"string"},"event":{"type":"string","description":"Persisted platform event, for example webhook.retry_scheduled or webhook.dead_lettered."},"status":{"type":["string","null"]},"webhook_id":{"type":["string","null"]},"batch_id":{"type":["string","null"]},"org_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":false},"BatchWebhooksResponse":{"type":"object","required":["batch_id","data","events"],"properties":{"batch_id":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryEvent"}}},"additionalProperties":false},"BatchResultsResponse":{"type":"object","required":["results","next_cursor"],"properties":{"results":{"type":"array","items":{"type":"object","properties":{"customer_item_id":{"type":"string"},"status":{"type":"string","enum":["completed","failed"]},"output":{"type":["object","null"],"additionalProperties":true},"error":{"type":["object","null"],"additionalProperties":true}}}},"next_cursor":{"type":["string","null"]}}},"BatchItemsResponse":{"type":"object","required":["items","next_cursor"],"properties":{"items":{"type":"array","items":{"type":"object","properties":{"customer_item_id":{"type":"string"},"status":{"type":"string"},"sequence_number":{"type":"integer"}},"additionalProperties":true}},"next_cursor":{"type":["string","null"]}}},"BatchBillingReceipt":{"type":"object","properties":{"batch_id":{"type":"string"},"final_settled_price":{"$ref":"#/components/schemas/Money"},"provider_subtotal":{"$ref":"#/components/schemas/Money"},"batchrouter_fee":{"$ref":"#/components/schemas/Money"},"credit_reserved":{"$ref":"#/components/schemas/Money"},"credit_charged":{"$ref":"#/components/schemas/Money"},"credit_released":{"$ref":"#/components/schemas/Money"},"settled_at":{"type":["string","null"],"format":"date-time"},"provider_lanes":{"type":"array","description":"Selected quote lanes that actually ran, including the quote-time data/privacy proof that applied to each lane.","items":{"$ref":"#/components/schemas/ReceiptQuoteLane"}},"rejected_lanes":{"type":"array","description":"Rejected or non-selected quote lanes from the accepted quote, including the quote-time data/privacy proof and rejection receipt.","items":{"$ref":"#/components/schemas/ReceiptRejectedLane"}}},"additionalProperties":true},"WorkOrder":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"batch_id":{"type":["string","null"]},"workflow_slug":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"AgentMainThreadRunRequest":{"type":"object","required":["input","webhook"],"properties":{"customer_item_id":{"type":"string"},"input":{"type":"object","additionalProperties":true,"description":"Agent inference input. Supports OpenAI Responses API format (`messages`, `input`) or plain `prompt`."},"model":{"type":"string"},"model_options":{"type":"array","items":{"type":"string"}},"privacy_tier":{"enum":["standard","confidential","restricted"]},"allowed_regions":{"type":"array","items":{"type":"string"}},"max_price":{"type":"string"},"adaptive_batching":{"type":"object","properties":{"enabled":{"type":"boolean","default":true},"latency_profile":{"enum":["interactive","balanced","cost_saver"]},"max_wait_ms":{"type":"integer","minimum":0,"maximum":30000},"max_batch_items":{"type":"integer","minimum":1,"maximum":64}},"additionalProperties":false},"webhook":{"type":"object","required":["url","secret"],"properties":{"url":{"type":"string","format":"uri"},"secret":{"type":"string","minLength":8,"maxLength":256}},"additionalProperties":false},"delivery":{"type":["object","null"],"description":"Customer-owned-bucket delivery state (poll-delivery-compat P3). Null unless a delivery target is configured for the batch. Credentials are never exposed.","properties":{"target_id":{"type":"string"},"status":{"type":["string","null"],"enum":["pending","delivering","delivered","failed",null]},"error":{"type":["string","null"]}},"additionalProperties":false}},"additionalProperties":false},"AgentMainThreadRunResponse":{"type":"object","required":["job_id","workflow_run_id","batch_id","state"],"properties":{"job_id":{"type":"string"},"workflow_run_id":{"type":"string"},"batch_id":{"type":"string"},"state":{"type":"string"},"async":{"const":true},"completion":{"type":"object","properties":{"delivery":{"const":"webhook"},"webhook_url":{"type":["string","null"]}},"additionalProperties":true},"sla":{"type":"object","additionalProperties":true},"polling":{"type":"object","additionalProperties":true}},"additionalProperties":true},"ReceiptQuoteLane":{"type":"object","properties":{"quote_lane_id":{"type":["string","null"]},"quote_option_id":{"type":["string","null"]},"quote_option_key":{"type":["string","null"]},"provider":{"type":["string","null"]},"provider_offering_id":{"type":["string","null"]},"offering_version":{"type":["integer","null"]},"model":{"type":["string","null"]},"model_family":{"type":["string","null"]},"operation":{"type":["string","null"]},"item_count":{"type":["integer","null"]},"item_sequence_numbers":{"type":"array","items":{"type":"integer"}},"item_sequence_ranges":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"integer"}}},"item_sequence_count":{"type":["integer","null"]},"item_sequence_numbers_omitted":{"type":"boolean"},"quoted_price":{"oneOf":[{"$ref":"#/components/schemas/CustomerPricingEstimate"},{"type":"null"}]},"final_settled_price":{"oneOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}]},"usage":{"type":"object","additionalProperties":true},"data_privacy":{"oneOf":[{"$ref":"#/components/schemas/LaneDataPrivacyProof"},{"type":"null"}]},"data_privacy_source":{"type":["string","null"],"description":"`quote_lane_snapshot` means the proof was persisted with the accepted quote lane."}},"additionalProperties":false},"ReceiptRejectedLane":{"type":"object","properties":{"quote_lane_id":{"type":["string","null"]},"quote_option_id":{"type":["string","null"]},"quote_option_key":{"type":["string","null"]},"grouping_key":{"type":["string","null"]},"lane_rank":{"type":["integer","null"]},"selected":{"const":false},"provider":{"type":["string","null"]},"provider_offering_id":{"type":["string","null"]},"offering_version":{"type":["integer","null"]},"model":{"type":["string","null"]},"customer_model":{"type":["string","null"]},"resolved_alias":{"type":["string","null"]},"provider_model":{"type":["string","null"]},"model_family":{"type":["string","null"]},"operation":{"type":["string","null"]},"item_sequence_numbers":{"type":"array","items":{"type":"integer"}},"item_sequence_ranges":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"integer"}}},"item_sequence_count":{"type":["integer","null"]},"item_sequence_numbers_omitted":{"type":"boolean"},"quoted_price":{"oneOf":[{"$ref":"#/components/schemas/CustomerPricingEstimate"},{"type":"null"}]},"data_privacy":{"oneOf":[{"$ref":"#/components/schemas/LaneDataPrivacyProof"},{"type":"null"}]},"data_privacy_source":{"type":["string","null"],"description":"`quote_lane_snapshot` means the proof was persisted with the accepted quote lane."},"rejection_code":{"type":["string","null"]},"rejection_reason":{"type":["string","null"]},"rejection_receipt":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}]}},"additionalProperties":false},"UsageReceipt":{"type":"object","required":["batch_id","product","pricing","credits","final_settlement","quote_lanes","rejected_lanes"],"properties":{"batch_id":{"type":"string"},"quote_id":{"type":["string","null"]},"work_order_id":{"type":["string","null"]},"activity_at":{"type":"string","format":"date-time"},"product":{"type":"object","properties":{"kind":{"enum":["model","workflow",null]},"model":{"type":["string","null"]}},"additionalProperties":false},"pricing":{"type":"object","properties":{"quoted_price":{"oneOf":[{"$ref":"#/components/schemas/CustomerPricingEstimate"},{"type":"null"}]},"final_settled_price":{"$ref":"#/components/schemas/Money"}},"additionalProperties":false},"credits":{"type":"object","required":["reserved","charged","released"],"properties":{"reserved":{"$ref":"#/components/schemas/Money"},"charged":{"$ref":"#/components/schemas/Money"},"released":{"$ref":"#/components/schemas/Money"}},"additionalProperties":false},"final_settlement":{"type":"object","properties":{"status":{"type":"string"},"settled_at":{"type":["string","null"],"format":"date-time"},"final_settled_price":{"$ref":"#/components/schemas/Money"}},"additionalProperties":false},"quote_lanes":{"type":"array","items":{"$ref":"#/components/schemas/ReceiptQuoteLane"}},"rejected_lanes":{"type":"array","items":{"$ref":"#/components/schemas/ReceiptRejectedLane"}}},"additionalProperties":false},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}},"responses":{"BadRequest":{"description":"Invalid request body or parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PreflightBadRequest":{"description":"Invalid request body or batch preflight validation failure. When `error.details.preflight` is present, clients should show the returned issues before retrying quote creation or batch submission.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/BatchPreflightError"}]}}}},"Unauthorized":{"description":"Missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Authenticated but not authorised for this resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PaymentRequired":{"description":"Insufficient credits to complete the request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Request conflicts with current state (e.g. duplicate idempotency key with different payload, batch already in terminal state)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}