{"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."},{"name":"Feedback","description":"Submit product feedback from the dashboard feedback widget."},{"name":"Presets","description":"Saved batch-composer presets for the customer console."},{"name":"Routing","description":"Read the active route policy the customer's org is served by."},{"name":"Recurring Schedules","description":"Recurring batch schedules, their versions, and golden-set regression benchmarks."}],"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/runtime":{"get":{"tags":["Operations"],"operationId":"getRuntime","summary":"Get runtime metadata","description":"Returns public runtime metadata and capability flags for client bootstrapping and deployment smoke tests. Anonymous callers receive public-safe metadata; authenticated callers may receive additional workspace or operator capability details.","security":[{"customerApiKey":[]},{"customerSession":[]},{}],"responses":{"200":{"description":"Runtime metadata and capability flags","content":{"application/json":{"schema":{"type":"object","required":["environment","read_only","capabilities"],"additionalProperties":true,"properties":{"environment":{"type":"string","description":"Resolved deployment environment, such as `production`, `test`, `dev`, or `local`."},"read_only":{"type":"boolean","description":"Whether the API is in read-only maintenance mode."},"provider_simulation":{"type":"boolean","description":"Present for authenticated callers when provider simulation mode is reported."},"routing":{"type":"object","additionalProperties":true,"properties":{"provider_allowlist":{"type":"array","items":{"type":"string"}},"launch_provider_guard":{"type":"boolean"}}},"capabilities":{"type":"object","required":["turnstile_login","email_delivery"],"additionalProperties":true,"properties":{"turnstile_login":{"$ref":"#/components/schemas/RuntimeCapabilityStatus"},"email_delivery":{"$ref":"#/components/schemas/RuntimeCapabilityStatus"},"billing_checkout":{"$ref":"#/components/schemas/RuntimeCapabilityStatus"},"internal_signing":{"$ref":"#/components/schemas/RuntimeCapabilityStatus"},"operator_alerts":{"$ref":"#/components/schemas/RuntimeCapabilityStatus"}}}}}}}}}}},"/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 account/workspace and issues an API key in a single unauthenticated request. The request includes an email/password so the owner can later sign in to the dashboard; BatchRouter also sends a verification email.\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. Requires an email-based customer session with API-key management permissions. The key value is shown **once** — store it securely.","security":[{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["label"],"properties":{"label":{"type":"string","minLength":1,"maxLength":120,"description":"Human-readable label for this key."},"role":{"type":"string","enum":["owner","admin","member","billing"],"default":"member","description":"Workspace role/capability set granted to this key."}}}}}},"responses":{"201":{"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"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/auth/account/api-keys/{keyId}/revoke":{"post":{"tags":["Account"],"operationId":"revokeApiKey","summary":"Revoke an API key","security":[{"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":"privacy_tier","in":"query","schema":{"type":"string","enum":["standard","confidential","restricted"]},"description":"Filter by supported privacy tier."},{"name":"sla_tier","in":"query","schema":{"type":"string","enum":["flex","standard","priority"]},"description":"Filter by suggested SLA tier."},{"name":"runtime_capability","in":"query","schema":{"type":"string","enum":["tool_calling","structured_outputs","json_schema","vision","documents","audio","reasoning"]},"description":"Filter by model runtime capability metadata."},{"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`."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Case-insensitive search across title, summary, model id, description, and tags."}],"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","required":["model"],"properties":{"model":{"$ref":"#/components/schemas/CatalogModel"},"pricing_updated_at":{"type":["string","null"],"format":"date-time"}}}}}},"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}/rotate-credentials":{"post":{"tags":["Delivery"],"operationId":"rotateDeliveryTargetCredentials","summary":"Rotate a delivery target's bucket credential","description":"Replaces the target's stored secret access key (and optionally the access key id), re-encrypting it under the same envelope. **Owner-only** (stricter than create/delete). The secret is never read back or returned. An unknown/foreign target is a 404 (org-scoped).","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["secret_access_key"],"properties":{"access_key_id":{"type":"string","minLength":1,"maxLength":256},"secret_access_key":{"type":"string","minLength":1,"maxLength":2048}}}}}},"responses":{"200":{"description":"Credential rotated.","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"},"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}/retention":{"get":{"tags":["Delivery"],"operationId":"getBatchRetention","summary":"Get a batch's retention","description":"The effective retention for one finalized batch's result artifacts (per-batch override or the org default materialized at finalize).","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"batchId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Batch retention.","content":{"application/json":{"schema":{"type":"object","properties":{"retention":{"$ref":"#/components/schemas/BatchRetention"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"tags":["Delivery"],"operationId":"updateBatchRetention","summary":"Set a batch's retention (editable while live)","description":"Override the org-default retention for one finalized batch, editable while its artifacts are still live. `extended_fixed` requires `extended_days`. Upgrading into a paid tier bills forward from the edit (never retroactively for the free grace period); billing only accrues once storage fees are enabled. Rejected (`extended_window_elapsed`) if the requested `extended_fixed` window has already fully elapsed for this batch.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"batchId","in":"path","required":true,"schema":{"type":"string"}}],"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}}}}}},"responses":{"200":{"description":"Updated batch retention.","content":{"application/json":{"schema":{"type":"object","properties":{"retention":{"$ref":"#/components/schemas/BatchRetention"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/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"}}}},"/v1/feedback":{"post":{"tags":["Feedback"],"operationId":"createFeedback","summary":"Submit product feedback","description":"Records a feedback report from the dashboard feedback widget. Public + rate-limited; protected by Cloudflare Turnstile where configured. Stores a row and (in configured environments) notifies the operator inbox.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackCreateRequest"}}}},"responses":{"202":{"description":"Feedback recorded.","content":{"application/json":{"schema":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string","description":"Feedback id, prefixed `fbk_`."},"status":{"type":"string","enum":["received"]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"503":{"description":"Turnstile verification temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/files/{id}":{"get":{"tags":["Files"],"operationId":"downloadFile","summary":"Download a file","description":"Streams the bytes of a stored file (uploaded input or generated artifact). Authenticated with a customer session/API key (requires the `artifacts.read` capability) OR a short-lived signed URL via the `expires` + `signature` query parameters.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"File id."},{"name":"expires","in":"query","required":false,"schema":{"type":"string"},"description":"Signed-URL expiry (unix seconds). Present on signed download links."},{"name":"signature","in":"query","required":false,"schema":{"type":"string"},"description":"Signed-URL HMAC signature. Present on signed download links."}],"responses":{"200":{"description":"File bytes.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"410":{"description":"File has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/presets":{"get":{"tags":["Presets"],"operationId":"listBatchPresets","summary":"List batch presets","description":"Lists the org's saved batch-composer presets. Requires the `console.read` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Presets.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BatchPreset"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Presets"],"operationId":"createBatchPreset","summary":"Create a batch preset","description":"Saves a new batch-composer preset. Requires the `console.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchPresetCreate"}}}},"responses":{"201":{"description":"Preset created.","content":{"application/json":{"schema":{"type":"object","required":["preset"],"properties":{"preset":{"$ref":"#/components/schemas/BatchPreset"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/presets/{id}":{"put":{"tags":["Presets"],"operationId":"updateBatchPreset","summary":"Update a batch preset","description":"Updates a saved preset. Supplied fields are merged. Requires the `console.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Preset id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchPresetUpdate"}}}},"responses":{"200":{"description":"Preset updated.","content":{"application/json":{"schema":{"type":"object","required":["preset"],"properties":{"preset":{"$ref":"#/components/schemas/BatchPreset"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Presets"],"operationId":"deleteBatchPreset","summary":"Delete a batch preset","description":"Deletes a saved preset. Requires the `console.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Preset id."}],"responses":{"200":{"description":"Preset deleted.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/route-policies":{"get":{"tags":["Routing"],"operationId":"getRoutePolicies","summary":"Get active route policies","description":"Returns the active route version, its policy rows, and current provider capacity — the routing configuration the org's batches are served by. Requires the `console.read` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Active route policies.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"route_version":{"type":"object","additionalProperties":true,"description":"The active route version metadata."},"data":{"type":"array","items":{"type":"object","additionalProperties":true,"description":"A route policy row."}},"provider_capacity":{"type":"object","additionalProperties":true,"description":"Per-provider capacity snapshot."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/batches/{id}/recurring-schedules":{"post":{"tags":["Recurring Schedules"],"operationId":"createRecurringBatchSchedule","summary":"Create a recurring schedule from a batch","description":"Creates a recurring batch schedule that re-runs a completed batch on a cadence. Requires the `console.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Source batch id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringBatchScheduleCreate"}}}},"responses":{"200":{"description":"Idempotent: a schedule with this source batch and cadence already exists; it is returned with `created: false`.","content":{"application/json":{"schema":{"type":"object","required":["schedule"],"properties":{"created":{"type":"boolean"},"schedule":{"$ref":"#/components/schemas/RecurringBatchSchedule"}}}}}},"201":{"description":"Schedule created.","content":{"application/json":{"schema":{"type":"object","required":["schedule"],"properties":{"created":{"type":"boolean"},"schedule":{"$ref":"#/components/schemas/RecurringBatchSchedule"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"get":{"tags":["Recurring Schedules"],"operationId":"listRecurringBatchSchedulesForBatch","summary":"List recurring schedules for a batch","description":"Lists recurring schedules sourced from the given batch. Requires the `console.read` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Source batch id."}],"responses":{"200":{"description":"Schedules.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RecurringBatchSchedule"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/recurring-batch-schedules/{id}":{"put":{"tags":["Recurring Schedules"],"operationId":"updateRecurringBatchSchedule","summary":"Update a recurring schedule","description":"Updates a recurring schedule's cadence, routing, delivery, or approval settings. Requires the `console.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Schedule id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringBatchScheduleUpdate"}}}},"responses":{"200":{"description":"Schedule updated.","content":{"application/json":{"schema":{"type":"object","required":["schedule"],"properties":{"schedule":{"$ref":"#/components/schemas/RecurringBatchSchedule"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/recurring-batch-schedules/{id}/versions":{"get":{"tags":["Recurring Schedules"],"operationId":"listRecurringBatchScheduleVersions","summary":"List recurring schedule versions","description":"Lists the immutable versions captured for a recurring schedule. Requires the `console.read` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Schedule id."}],"responses":{"200":{"description":"Schedule versions.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"schedule":{"$ref":"#/components/schemas/RecurringBatchSchedule"},"current_version_id":{"type":"string","nullable":true},"last_run_version_id":{"type":"string","nullable":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/RecurringBatchScheduleVersion"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/recurring-batch-schedules/{id}/golden-set":{"get":{"tags":["Recurring Schedules"],"operationId":"getRecurringBatchScheduleGoldenSet","summary":"Get a schedule's golden set","description":"Returns the golden-set regression suite for a recurring schedule (or `null` if none is configured). Requires the `console.read` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Schedule id."}],"responses":{"200":{"description":"Golden set.","content":{"application/json":{"schema":{"type":"object","required":["schedule"],"properties":{"schedule":{"$ref":"#/components/schemas/RecurringBatchSchedule"},"golden_set":{"$ref":"#/components/schemas/GoldenSet","nullable":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"tags":["Recurring Schedules"],"operationId":"upsertRecurringBatchScheduleGoldenSet","summary":"Create or replace a schedule's golden set","description":"Uploads golden-set items or derives them from a prior batch to build the regression suite. Requires the `console.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Schedule id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoldenSetUpsert"}}}},"responses":{"201":{"description":"Golden set saved.","content":{"application/json":{"schema":{"type":"object","required":["schedule","golden_set"],"properties":{"schedule":{"$ref":"#/components/schemas/RecurringBatchSchedule"},"golden_set":{"$ref":"#/components/schemas/GoldenSet"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/recurring-batch-schedules/{id}/golden-set/benchmark-results":{"post":{"tags":["Recurring Schedules"],"operationId":"recordGoldenSetBenchmarkResult","summary":"Record a golden-set benchmark result","description":"Records a provider/model benchmark result against the schedule's golden set (used for admission, regression, and promotion decisions). Requires the `console.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Schedule id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoldenSetBenchmarkResultCreate"}}}},"responses":{"201":{"description":"Benchmark result recorded.","content":{"application/json":{"schema":{"type":"object","required":["golden_set","benchmark_result"],"properties":{"golden_set":{"$ref":"#/components/schemas/GoldenSet"},"benchmark_result":{"$ref":"#/components/schemas/GoldenSetBenchmarkResult"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/billing/credits":{"get":{"tags":["Billing"],"operationId":"getBillingCredits","summary":"Get credit balance & billing summary","description":"Returns the org's billing profile, credit-balance summary, top-up capability, recent transactions/reservations/top-ups, and lifetime storage spend. Requires the `billing.read` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Billing summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCreditsSummary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/billing/storage-spend":{"get":{"tags":["Billing"],"operationId":"getBillingStorageSpend","summary":"Get storage-spend history & period totals","description":"Returns the org's dedicated storage-fee spend history: the lifetime grand total, per-calendar-month totals (UTC `YYYY-MM`, newest first) covering the full history, and a capped list of the most recent `storage_charge` line items. A read-only companion to the recent-window `storage_spend` line on `GET /v1/billing/credits`. Requires the `billing.read` capability. Storage-fee metering is inert until enabled, so totals are zero and the lists empty until then.","parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of recent `storage_charge` line items to return (default 100, max 500). Does not affect the per-period totals, which always cover the full history.","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Storage-spend history and per-period totals.","content":{"application/json":{"schema":{"type":"object","required":["total","period_totals","transactions"],"properties":{"total":{"type":"object","description":"Lifetime storage-fee spend across all time.","required":["total_micro_usd","transaction_count"],"properties":{"total_micro_usd":{"type":"integer","description":"Lifetime storage-fee spend in micro-USD (positive)."},"transaction_count":{"type":"integer","description":"Total number of storage_charge transactions."}}},"period_totals":{"type":"array","description":"Per-calendar-month totals over the full history, newest first.","items":{"type":"object","required":["period","total_micro_usd","transaction_count"],"properties":{"period":{"type":"string","description":"UTC calendar month, `YYYY-MM`.","example":"2026-07"},"total_micro_usd":{"type":"integer","description":"Storage-fee spend for the month in micro-USD (positive)."},"transaction_count":{"type":"integer","description":"Number of storage_charge transactions in the month."}}}},"transactions":{"type":"array","description":"Most recent storage_charge line items (capped by `limit`), newest first.","items":{"type":"object","description":"A single credit-ledger storage_charge transaction.","properties":{"id":{"type":"string"},"org_id":{"type":"string"},"kind":{"type":"string","example":"storage_charge"},"amount":{"type":"object","description":"Signed money amount for the transaction."},"balance_after":{"type":"object","description":"Wallet balance after the transaction."},"batch_id":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/billing/profile":{"put":{"tags":["Billing"],"operationId":"updateBillingProfile","summary":"Update billing profile","description":"Updates the org's billing email. Requires the `billing.write` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingProfileUpdate"}}}},"responses":{"200":{"description":"Updated billing profile.","content":{"application/json":{"schema":{"type":"object","required":["profile"],"properties":{"profile":{"type":"object","additionalProperties":true,"description":"The updated billing profile."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/billing/setup-intent":{"post":{"tags":["Billing"],"operationId":"createBillingSetupIntent","summary":"Create a Stripe SetupIntent","description":"Creates a Stripe SetupIntent so the customer can save a card for off-session top-ups. Requires the `billing.write` capability and a signed-in, email-verified user session (API keys without an associated verified user receive `403`). A billing email must be set.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"SetupIntent created.","content":{"application/json":{"schema":{"type":"object","required":["setup_intent"],"properties":{"setup_intent":{"$ref":"#/components/schemas/SetupIntent"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"description":"Stripe off-session charging is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/billing/payment-methods":{"get":{"tags":["Billing"],"operationId":"listBillingPaymentMethods","summary":"List saved payment methods","description":"Lists the org's saved Stripe payment methods. Requires the `billing.read` capability.","security":[{"customerApiKey":[]},{"customerSession":[]}],"responses":{"200":{"description":"Payment methods.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PaymentMethod"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}}},"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"]}}},"BatchRetention":{"type":"object","description":"Effective retention for one batch's result artifacts. Null fields when the batch is not finalized / has no retained artifacts.","properties":{"finalized":{"type":"boolean"},"retention_tier":{"type":["string","null"],"enum":["grace_only","extended_fixed","until_deleted",null]},"grace_until":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time","description":"Null for `until_deleted` (never auto-collected)."},"billable_from":{"type":["string","null"],"format":"date-time","description":"When storage metering begins; null for free `grace_only`."},"extended_days":{"type":["integer","null"],"description":"Derived from the stamped window for `extended_fixed`."}}},"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","required":["ok","email","verification_sent"],"properties":{"ok":{"type":"boolean"},"email":{"type":"string","format":"email"},"verification_sent":{"type":"boolean"},"session":{"type":["object","null"],"description":"Authenticated dashboard session issued after successful registration, when session creation succeeds.","additionalProperties":true},"session_token":{"type":"string","description":"Bearer session token for non-cookie clients, when session creation succeeds."}}},"AgentRegisterRequest":{"type":"object","required":["email","password","agent_name"],"properties":{"email":{"type":"string","format":"email","description":"Email address for the customer account that owns the issued API key."},"password":{"type":"string","minLength":8,"description":"Password for future dashboard sign-in."},"org_name":{"type":"string","maxLength":200,"description":"Optional display name for the org."},"agent_name":{"type":"string","maxLength":200,"description":"Display name for the agent account and generated API key."},"invitation_id":{"type":"string","maxLength":128,"description":"Optional workspace invitation id. When supplied, the agent joins that workspace instead of creating a personal workspace."}}},"AgentRegisterResponse":{"type":"object","required":["ok","email","user_id","org_id","email_verification_required","api_key","api_key_id","api_key_record"],"properties":{"ok":{"type":"boolean","const":true},"email":{"type":"string","format":"email"},"user_id":{"type":"string"},"org_id":{"type":"string"},"email_verification_required":{"type":"boolean"},"api_key":{"type":"string","description":"Bearer API key — shown **once**, store securely."},"api_key_id":{"type":"string"},"api_key_record":{"$ref":"#/components/schemas/CustomerApiKey"}}},"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"}}}},"RuntimeCapabilityStatus":{"type":"object","required":["enabled"],"additionalProperties":true,"properties":{"enabled":{"type":"boolean"},"reason":{"type":["string","null"]},"site_key":{"type":"string","description":"Public Turnstile site key when the Turnstile login capability is enabled."}}},"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},"CustomerApiKey":{"type":"object","required":["id","role","label","status","created_at"],"properties":{"id":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member","billing"]},"label":{"type":["string","null"]},"status":{"type":"string","enum":["active","revoked"]},"request_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"},"last_used_endpoint":{"type":["string","null"]},"last_used_ip_address":{"type":["string","null"]},"last_used_ip_summary":{"type":["string","null"]},"last_used_location_summary":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"capabilities":{"type":"array","items":{"type":"string"}},"rotation_age_days":{"type":["integer","null"]},"last_used_age_days":{"type":["integer","null"]},"stale":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"label":{"type":"string"},"severity":{"type":"string","enum":["info","warning","critical"]}}}}}},"ApiKeyCreatedResponse":{"type":"object","required":["api_key","value","api_keys"],"properties":{"api_key":{"$ref":"#/components/schemas/CustomerApiKey"},"value":{"type":"string","description":"Full API key value — shown once."},"api_keys":{"type":"array","items":{"$ref":"#/components/schemas/CustomerApiKey"}}}},"CatalogModel":{"type":"object","required":["slug","model","title","summary","description","operations","providers","privacy_tiers","suggested_routing_modes","suggested_sla_tiers","price_hint","latency_hint","context_window","input_modalities","accepted_file_types","max_file_size","supports_file_uploads","example_batch","tags"],"properties":{"slug":{"type":"string"},"model":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"description":{"type":"string"},"operations":{"type":"array","items":{"type":"string","enum":["responses","embeddings","vision"]}},"providers":{"type":"array","items":{"type":"string"},"description":"Provider slugs that can currently quote this catalog model."},"privacy_tiers":{"type":"array","items":{"type":"string","enum":["standard","confidential","restricted"]}},"suggested_routing_modes":{"type":"array","items":{"type":"string","enum":["cheapest","sla_aware","public_only","edge_only","hybrid","privacy_constrained"]}},"suggested_sla_tiers":{"type":"array","items":{"type":"string","enum":["flex","standard","priority"]}},"price_hint":{"type":"string"},"latency_hint":{"type":"string"},"context_window":{"type":"string","description":"Human-readable context window, such as `128k`."},"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`."},"runtime_capabilities":{"type":"array","items":{"type":"string","enum":["tool_calling","structured_outputs","json_schema","vision","documents","audio","reasoning"]},"description":"Runtime capabilities available on this model across its current provider offerings."},"hosted_tools":{"type":"array","items":{"$ref":"#/components/schemas/HostedTool"},"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","required":["source","provider","provider_name","provider_offering_id","offering_version","status","task_type","model_slug","model_name","model_family","context_window","max_input_tokens","max_output_tokens","input_modalities","runtime_capabilities","hosted_tools","accepted_file_types","max_file_size","supports_file_uploads","data_collection","supports_zdr","retention_days","training_use","privacy_terms_url","artifact_handling","privacy_tiers","regions","metadata_verification_status","metadata_unverified_reasons","price","rate_limits","capacity_status","available_queue_items","available_queue_tokens","capacity_expires_at","capacity_updated_at","heartbeat_ttl_seconds","last_heartbeat_at","capacity_freshness","feedback_accept_count","feedback_reject_count","feedback_capacity_reject_count","feedback_throttle_reject_count","feedback_timeout_count","feedback_completed_count","feedback_avg_completion_seconds","declared_sla_window_seconds"],"properties":{"source":{"type":"string","enum":["provider_offering"]},"provider":{"type":"string"},"provider_name":{"type":"string"},"provider_offering_id":{"type":"string"},"offering_version":{"type":"integer"},"status":{"type":"string","enum":["active","paused","deprecated","disabled"]},"task_type":{"type":"string","enum":["responses","embeddings","vision"]},"model_slug":{"type":"string"},"model_name":{"type":"string"},"model_family":{"type":"string"},"context_window":{"type":"integer"},"max_input_tokens":{"type":"integer"},"max_output_tokens":{"type":"integer"},"input_modalities":{"type":"array","items":{"type":"string","enum":["text","image","document","audio","video"]}},"runtime_capabilities":{"type":"array","items":{"type":"string","enum":["tool_calling","structured_outputs","json_schema","vision","documents","audio","reasoning"]}},"hosted_tools":{"type":"array","items":{"$ref":"#/components/schemas/HostedTool"}},"accepted_file_types":{"type":"array","items":{"type":"string"}},"max_file_size":{"type":["integer","null"],"minimum":1},"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},"rate_limits":{"type":"object","additionalProperties":true},"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"]},"declared_sla_window_seconds":{"type":["integer","null"]}},"additionalProperties":true}},"example_batch":{"type":"object","additionalProperties":true,"description":"Example batch payload for this model."},"tags":{"type":"array","items":{"type":"string"}},"pricing":{"type":"object","required":["unit","entries","lowest_provider_cost","lowest_customer_charge","updated_at"],"properties":{"unit":{"type":"string","enum":["per_1m_input_tokens","per_1m_input_and_1m_output_tokens"]},"entries":{"type":"array","items":{"type":"object","required":["provider","model","operation","unit","billing_mode","input_tokens","output_tokens","provider_charge","customer_charge","expected_completion_seconds","reliability_score","pricing_source","updated_at"],"properties":{"provider":{"type":"string"},"model":{"type":"string"},"operation":{"type":"string","enum":["responses","embeddings","vision"]},"unit":{"type":"string","enum":["per_1m_input_tokens","per_1m_input_and_1m_output_tokens"]},"billing_mode":{"type":"string"},"batch_discount_percent":{"type":"number"},"customer_discount_percent":{"type":"number"},"price_basis":{"type":"string"},"provider_input_per_1m":{"$ref":"#/components/schemas/Money"},"provider_cached_input_per_1m":{"$ref":"#/components/schemas/Money"},"provider_cache_write_5m_per_1m":{"$ref":"#/components/schemas/Money"},"provider_cache_write_1h_per_1m":{"$ref":"#/components/schemas/Money"},"provider_output_per_1m":{"$ref":"#/components/schemas/Money"},"provider_embeddings_input_per_1m":{"$ref":"#/components/schemas/Money"},"customer_input_per_1m":{"$ref":"#/components/schemas/Money"},"customer_cached_input_per_1m":{"$ref":"#/components/schemas/Money"},"customer_cache_write_5m_per_1m":{"$ref":"#/components/schemas/Money"},"customer_cache_write_1h_per_1m":{"$ref":"#/components/schemas/Money"},"customer_output_per_1m":{"$ref":"#/components/schemas/Money"},"customer_embeddings_input_per_1m":{"$ref":"#/components/schemas/Money"},"input_tokens":{"type":"integer","minimum":0},"output_tokens":{"type":"integer","minimum":0},"provider_charge":{"$ref":"#/components/schemas/Money"},"customer_subtotal":{"$ref":"#/components/schemas/Money"},"customer_discount":{"$ref":"#/components/schemas/Money"},"customer_charge":{"$ref":"#/components/schemas/Money"},"expected_completion_seconds":{"type":"number"},"reliability_score":{"type":"number"},"pricing_source":{"type":"string","enum":["default_rate_card","env_rate_card","provider_quote"]},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}},"lowest_provider_cost":{"$ref":"#/components/schemas/Money"},"lowest_customer_charge":{"$ref":"#/components/schemas/Money"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"pricing_updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"WorkflowProduct":{"type":"object","required":["slug","name","tagline","audience","operations","customer_outcome","summary","value_points","default_route_policy","success_sla","expected_artifacts","webhook_contract","preset_manifest","builder_prefill","workflow_definition_id","workflow_version_id","workflow_version_number","input_schema","output_schema","quality_policy","allowed_model_families","fallback_policy","golden_set_benchmark_gates","availability"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"tagline":{"type":"string"},"audience":{"type":"string"},"operations":{"type":"array","items":{"type":"string","enum":["responses","embeddings","vision"]}},"customer_outcome":{"type":"string"},"summary":{"type":"string"},"value_points":{"type":"array","items":{"type":"string"}},"default_route_policy":{"type":"object","required":["key","label","description"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"}},"additionalProperties":true},"success_sla":{"type":"object","required":["tier","target","success_definition"],"properties":{"tier":{"type":"string","enum":["flex","standard","priority"]},"target":{"type":"string"},"success_definition":{"type":"string"}},"additionalProperties":true},"expected_artifacts":{"type":"array","items":{"type":"object","required":["key","label","platform_file_kind","format","content_type","description","fields"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"platform_file_kind":{"type":"string","enum":["result_jsonl","review_jsonl","error_jsonl","retry_manifest"]},"format":{"type":"string","enum":["jsonl","json"]},"content_type":{"type":"string"},"description":{"type":"string"},"fields":{"type":"array","items":{"type":"object","required":["path","type","description"],"properties":{"path":{"type":"string"},"type":{"type":"string"},"description":{"type":"string"}},"additionalProperties":true}}},"additionalProperties":true}},"webhook_contract":{"type":"object","required":["event","headers","payload_fields","notes"],"properties":{"event":{"type":"string"},"headers":{"type":"array","items":{"type":"object","required":["name","description"],"properties":{"name":{"type":"string"},"description":{"type":"string"}},"additionalProperties":true}},"payload_fields":{"type":"array","items":{"type":"object","required":["path","description"],"properties":{"path":{"type":"string"},"description":{"type":"string"}},"additionalProperties":true}},"notes":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"preset_manifest":{"$ref":"#/components/schemas/BatchCreateRequest"},"builder_prefill":{"type":"object","required":["mode","customer_item_id","operation","model","prompt","image_urls","route_policy_key","sla_tier","routing_mode","privacy_tier"],"properties":{"mode":{"type":"string","enum":["simple"]},"customer_item_id":{"type":"string"},"operation":{"type":"string","enum":["responses","embeddings","vision"]},"model":{"type":"string"},"prompt":{"type":"string"},"image_urls":{"type":"array","items":{"type":"string"}},"route_policy_key":{"type":"string"},"sla_tier":{"type":"string","enum":["flex","standard","priority"]},"routing_mode":{"type":"string","enum":["cheapest","sla_aware","public_only","edge_only","hybrid","privacy_constrained"]},"privacy_tier":{"type":"string","enum":["standard","confidential","restricted"]}},"additionalProperties":true},"workflow_definition_id":{"type":"string"},"workflow_version_id":{"type":"string"},"workflow_version_number":{"type":"integer"},"input_schema":{"type":"object","additionalProperties":true},"output_schema":{"type":"object","additionalProperties":true},"quality_policy":{"type":"object","additionalProperties":true},"allowed_model_families":{"type":"array","items":{"type":"string"}},"fallback_policy":{"type":"object","additionalProperties":true},"golden_set_benchmark_gates":{"type":"object","additionalProperties":true},"availability":{"type":"object","required":["status","label","reason","provider","provider_capacity"],"properties":{"status":{"type":"string","enum":["available"]},"label":{"type":"string"},"reason":{"type":["string","null"]},"provider":{"type":["string","null"]},"provider_capacity":{"type":"null"}},"additionalProperties":true}},"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}}}}},"FeedbackCreateRequest":{"type":"object","required":["type","message"],"properties":{"type":{"type":"string","enum":["bug","idea","other"],"description":"Feedback category."},"message":{"type":"string","minLength":1,"maxLength":5000,"description":"Free-text feedback body."},"email":{"type":"string","format":"email","maxLength":320,"description":"Optional reply-to email."},"page_url":{"type":"string","maxLength":2048,"description":"URL the feedback was submitted from."},"app_version":{"type":"string","maxLength":120},"user_agent":{"type":"string","maxLength":1024},"context":{"type":"object","properties":{"browser":{"type":"string","maxLength":120},"os":{"type":"string","maxLength":120},"language":{"type":"string","maxLength":35},"screen":{"type":"string","maxLength":40},"viewport":{"type":"string","maxLength":40},"referrer":{"type":"string","maxLength":2048},"console_errors":{"type":"array","items":{"type":"string","maxLength":2000}}}},"screenshot":{"type":"string","maxLength":450000,"description":"Optional base64 data-URL screenshot (image/png, image/jpeg, or image/webp)."},"turnstile_token":{"type":"string","maxLength":4096,"description":"Cloudflare Turnstile token. Required only where Turnstile is configured (enforced server-side; missing/invalid tokens are rejected with 400). Verification is skipped where Turnstile is unconfigured (e.g. the test environment)."}},"additionalProperties":false},"BatchPreset":{"type":"object","required":["id","name","description","mode","summary","payload","simple_draft","created_by_user_id","created_at","updated_at"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"mode":{"type":"string","description":"Composer mode, e.g. `raw` or `simple`."},"summary":{"type":"string"},"payload":{"type":"object","additionalProperties":true,"description":"The stored batch-create payload (shape of BatchCreateRequest)."},"simple_draft":{"type":"object","additionalProperties":true,"nullable":true},"created_by_user_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"BatchPresetCreate":{"type":"object","required":["name","summary","payload"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":280},"mode":{"type":"string","description":"Composer mode. Defaults to `raw`."},"summary":{"type":"string","minLength":1,"maxLength":240},"payload":{"$ref":"#/components/schemas/BatchCreateRequest"},"simple_draft":{"type":"object","additionalProperties":true}},"additionalProperties":false},"BatchPresetUpdate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":280},"mode":{"type":"string"},"summary":{"type":"string","minLength":1,"maxLength":240},"payload":{"$ref":"#/components/schemas/BatchCreateRequest"},"simple_draft":{"type":"object","additionalProperties":true}},"additionalProperties":false,"description":"All fields optional; supplied fields are merged over the stored preset."},"RecurringBatchSchedule":{"type":"object","required":["id","org_id","source_batch_id"],"properties":{"id":{"type":"string"},"org_id":{"type":"string"},"source_batch_id":{"type":"string"},"name":{"type":"string"},"cadence":{"type":"string","description":"Cadence: `daily` or `weekly`."},"status":{"type":"string","description":"Schedule lifecycle status, e.g. `active`, `paused`."},"current_version_id":{"type":"string","nullable":true},"next_run_at":{"type":"string","format":"date-time","nullable":true},"last_run_at":{"type":"string","format":"date-time","nullable":true},"last_batch_id":{"type":"string","nullable":true},"last_run_version_id":{"type":"string","nullable":true},"versioning":{"type":"object","properties":{"current_version_id":{"type":"string","nullable":true},"last_run_version_id":{"type":"string","nullable":true}}},"failure_count":{"type":"integer"},"last_error":{"type":"string","nullable":true},"item_count":{"type":"integer"},"delivery":{"type":"object","properties":{"url":{"type":"string","nullable":true},"destination_kind":{"type":"string","nullable":true},"email_to":{"type":"string","nullable":true}},"nullable":true},"control_plane":{"type":"object","properties":{"routing_mode":{"type":"string"},"sla_tier":{"type":"string"},"privacy_tier":{"type":"string"},"route_policy_key":{"type":"string","nullable":true},"auto_delivery_threshold":{"type":"number"},"approval_rule":{"type":"object","additionalProperties":true}}},"workload":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string","nullable":true},"workflow_product_slug":{"type":"string","nullable":true}},"nullable":true},"created_by_user_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"RecurringBatchScheduleCreate":{"type":"object","required":["cadence"],"properties":{"cadence":{"type":"string","enum":["daily","weekly"]},"name":{"type":"string","minLength":1,"maxLength":160}},"additionalProperties":false},"RecurringBatchScheduleUpdate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":160},"cadence":{"type":"string","enum":["daily","weekly"]},"status":{"type":"string","enum":["active","paused"]},"routing_mode":{"type":"string"},"sla_tier":{"type":"string"},"privacy_tier":{"type":"string"},"delivery":{"type":"object","properties":{"kind":{"type":"string","enum":["none","webhook","slack_webhook","email_digest"]},"url":{"type":"string","format":"uri"},"secret":{"type":"string","minLength":8,"maxLength":256},"email_to":{"type":"string","format":"email"}}},"auto_delivery_threshold":{"type":"number","minimum":0,"maximum":1},"approval_rule":{"type":"object","additionalProperties":true,"description":"confidenceApprovalRuleSchema"}},"additionalProperties":false},"RecurringBatchScheduleVersion":{"type":"object","required":["id","schedule_id","version_number"],"properties":{"id":{"type":"string"},"org_id":{"type":"string"},"schedule_id":{"type":"string"},"version_number":{"type":"integer"},"payload_hash":{"type":"string"},"schema":{"type":"object","additionalProperties":true},"route":{"type":"object","additionalProperties":true},"verification_gate":{"type":"object","additionalProperties":true},"delivery_contract":{"type":"object","additionalProperties":true},"settlement":{"type":"object","additionalProperties":true},"payload":{"type":"object","additionalProperties":true,"description":"Stored batch payload with any webhook secret redacted."},"created_by_user_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"GoldenSetAcceptanceCheck":{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["json_valid","schema","required_field","min_items","max_items","custom"]},"description":{"type":"string","minLength":1,"maxLength":300},"field_path":{"type":"string","minLength":1,"maxLength":180},"severity":{"type":"string","enum":["warn","block"],"description":"Defaults to `block`."},"expected":{"description":"Expected value for the check (any JSON value)."}}},"GoldenSetItem":{"type":"object","required":["id","sequence_no"],"properties":{"id":{"type":"string"},"sequence_no":{"type":"integer"},"customer_item_id":{"type":"string","nullable":true},"input":{"type":"object","additionalProperties":true},"expected_output":{"type":"object","additionalProperties":true,"nullable":true},"acceptance_checks":{"type":"array","items":{"$ref":"#/components/schemas/GoldenSetAcceptanceCheck"}},"metadata":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"}}},"GoldenSetItemInput":{"type":"object","required":["input"],"properties":{"customer_item_id":{"type":"string","minLength":1,"maxLength":128},"input":{"type":"object","additionalProperties":true},"expected_output":{"type":"object","additionalProperties":true},"acceptance_checks":{"type":"array","items":{"$ref":"#/components/schemas/GoldenSetAcceptanceCheck"},"maxItems":20},"metadata":{"type":"object","additionalProperties":true}},"additionalProperties":false},"GoldenSetBenchmarkResult":{"type":"object","required":["id","provider","model","status","pass_rate"],"properties":{"id":{"type":"string"},"provider":{"type":"string"},"model":{"type":"string"},"operation":{"type":"string"},"route_version_id":{"type":"string","nullable":true},"status":{"type":"string","enum":["passed","failed","needs_review"]},"pass_rate":{"type":"number","minimum":0,"maximum":1},"quality_score":{"type":"number","minimum":0,"maximum":1,"nullable":true},"latency_seconds":{"type":"integer","nullable":true},"estimated_cost":{"$ref":"#/components/schemas/Money","nullable":true},"regression_delta":{"type":"number","nullable":true},"premium_fallback_threshold":{"type":"number","nullable":true},"notes":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"GoldenSet":{"type":"object","required":["id","schedule_id"],"properties":{"id":{"type":"string"},"org_id":{"type":"string"},"schedule_id":{"type":"string"},"version_id":{"type":"string","nullable":true},"name":{"type":"string"},"description":{"type":"string","nullable":true},"source":{"type":"string","enum":["upload","derive_from_batch"]},"status":{"type":"string"},"benchmark_policy":{"type":"object","additionalProperties":true},"item_count":{"type":"integer"},"benchmark_uses":{"type":"array","items":{"type":"string"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/GoldenSetItem"}},"benchmark_results":{"type":"array","items":{"$ref":"#/components/schemas/GoldenSetBenchmarkResult"}},"created_by_user_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"GoldenSetUpsert":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":1000},"source":{"type":"string","enum":["upload","derive_from_batch"],"description":"Defaults to `upload`."},"version_id":{"type":"string","minLength":1,"maxLength":96},"derive_from_batch_id":{"type":"string","minLength":1,"maxLength":96,"description":"Required when `source` is `derive_from_batch`."},"limit":{"type":"integer","minimum":1,"maximum":50},"benchmark_policy":{"type":"object","additionalProperties":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/GoldenSetItemInput"},"maxItems":50,"description":"Required when `source` is `upload`."}},"additionalProperties":false},"GoldenSetBenchmarkResultCreate":{"type":"object","required":["provider","model","operation","status","pass_rate"],"properties":{"provider":{"type":"string","minLength":1,"maxLength":80},"model":{"type":"string","minLength":1,"maxLength":200},"operation":{"type":"string","description":"operationSchema, e.g. `responses` or `embeddings`."},"route_version_id":{"type":"string","minLength":1,"maxLength":96},"status":{"type":"string","enum":["passed","failed","needs_review"]},"pass_rate":{"type":"number","minimum":0,"maximum":1},"quality_score":{"type":"number","minimum":0,"maximum":1},"latency_seconds":{"type":"integer","minimum":0},"estimated_cost":{"type":"string","pattern":"^\\d+(\\.\\d{1,4})?$","description":"Decimal USD amount string, up to 4 decimal places."},"regression_delta":{"type":"number","minimum":0,"maximum":1},"premium_fallback_threshold":{"type":"number","minimum":0,"maximum":1},"notes":{"type":"string","maxLength":1000}},"additionalProperties":false},"BillingProfileUpdate":{"type":"object","required":["billing_email"],"properties":{"billing_email":{"type":"string","format":"email","maxLength":320}},"additionalProperties":false},"PaymentMethod":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"brand":{"type":"string","nullable":true},"last4":{"type":"string","nullable":true},"exp_month":{"type":"integer","nullable":true},"exp_year":{"type":"integer","nullable":true}}},"BillingCreditsSummary":{"type":"object","properties":{"profile":{"type":"object","additionalProperties":true,"description":"Billing profile (billing email, Stripe customer linkage, auto-topup state)."},"topup_capability":{"type":"object","additionalProperties":true,"description":"Whether the org can top up and under what constraints."},"balance_summary":{"type":"object","additionalProperties":true,"description":"Current credit balance and reserved/available breakdown."},"recent_transactions":{"type":"array","items":{"type":"object","additionalProperties":true}},"recent_reservations":{"type":"array","items":{"type":"object","additionalProperties":true}},"recent_topups":{"type":"array","items":{"type":"object","additionalProperties":true}},"storage_spend":{"type":"object","additionalProperties":true,"description":"Lifetime storage-billing spend line."}}},"SetupIntent":{"type":"object","required":["id","client_secret"],"properties":{"id":{"type":"string"},"client_secret":{"type":"string"},"customer_id":{"type":"string"}}}},"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"}}}}}}}