{"openapi":"3.1.0","info":{"title":"AIO Server","description":"FastAPI application with inference endpoint and API key authentication","version":"1.0.0"},"paths":{"/v1/extract":{"post":{"tags":["Public API"],"summary":"Extract structured data from a document","description":"Single-call extraction: upload a document file and a JSON schema, get structured data back. No presign dance, no SDK required.","operationId":"extract_v1_extract_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_extract_v1_extract_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicExtractResponse"}}}},"400":{"description":"Bad request (missing/invalid schema or file)"},"401":{"description":"Invalid or missing API key"},"403":{"description":"Insufficient credits"},"500":{"description":"Extraction failed"},"502":{"description":"Storage failure"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/to-markdown":{"post":{"tags":["Public API"],"summary":"Convert a document to markdown","description":"Single-call document-to-markdown conversion. Upload a file, get markdown back.","operationId":"to_markdown_endpoint_v1_to_markdown_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_to_markdown_endpoint_v1_to_markdown_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicToMarkdownResponse"}}}},"400":{"description":"Bad request (empty file or unsupported type)"},"401":{"description":"Invalid or missing API key"},"500":{"description":"Conversion failed"},"502":{"description":"Storage failure"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/inference/deployments":{"post":{"summary":"Activate artifact for inference","operationId":"activate_deployment_v1_inference_deployments_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateDeploymentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/inference/deployments/current":{"get":{"summary":"Resolve current active deployment","operationId":"get_current_deployment_v1_inference_deployments_current_get","parameters":[{"name":"tenant_id","in":"query","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"project_id","in":"query","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"environment","in":"query","required":false,"schema":{"type":"string","default":"prod","title":"Environment"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolvedDeployment"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/training/jobs":{"post":{"summary":"Create training job","description":"Create a training job.\n\nOptional ``Idempotency-Key`` header makes worker-crash retries safe:\nre-submitting the same key with the same body replays the cached\n202 response with ``Idempotent-Replayed: true`` instead of starting\na duplicate (billable) training job. TTL is 7 days — long enough to\ncover queued jobs that legitimately wait through a workday for\ncapacity. See README's *Idempotency* section for behaviour details.","operationId":"create_training_job_v1_training_jobs_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTrainingJobRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTrainingJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/training/jobs/{job_id}":{"get":{"summary":"Get training job status","operationId":"get_training_job_v1_training_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrainingJobStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/training/jobs/{job_id}/cancel":{"post":{"summary":"Cancel training job","operationId":"cancel_training_job_v1_training_jobs__job_id__cancel_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pricing":{"post":{"summary":"Upsert model pricing in Postgres","operationId":"upsert_pricing_v1_pricing_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingUpsertRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pricing/{model_name}":{"get":{"summary":"Get model pricing from Postgres","operationId":"get_pricing_v1_pricing__model_name__get","parameters":[{"name":"model_name","in":"path","required":true,"schema":{"type":"string","title":"Model Name"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ocr/to-markdown":{"post":{"summary":"Convert a document to markdown (OCR / parser pipeline)","description":"Convert a document to markdown via VLM (fast) or full parser pipeline (default).\n\nOptional ``Idempotency-Key`` header. The fingerprint covers the\nnormalized request body (including ``file_uri``, ``mode``, etc.) so\nretries that point at the same S3 object with the same options replay\nthe cached markdown instead of re-running OCR. 24 h TTL.","operationId":"ocr_to_markdown_v1_ocr_to_markdown_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToMarkdownRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToMarkdownResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/uploads/presign":{"post":{"summary":"Generate a presigned URL for file upload","description":"Generate a presigned PUT URL so the SDK can upload a file directly to S3.\n\nOptional ``Idempotency-Key`` header. Replay returns the *same* URL\n(and ``document_id`` / ``dataset_id``) so a client retrying after a\nnetwork blip can still complete its upload to the original S3 path.\nNote: presigned URLs expire after ~1 h regardless of the 24 h\nidempotency TTL — clients whose cached URL has expired should retry\nwith a fresh key.","operationId":"presign_upload_v1_uploads_presign_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignUploadRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/api-keys":{"post":{"summary":"Create API key for a tenant (admin only)","operationId":"admin_create_api_key_v1_api_keys_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/api-keys/{tenant_id}":{"get":{"summary":"List API keys for a tenant (admin only)","operationId":"admin_list_api_keys_v1_api_keys__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/api-keys/{key}":{"delete":{"summary":"Revoke an API key (admin only)","operationId":"admin_revoke_api_key_v1_api_keys__key__delete","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/api-keys/rotate":{"post":{"summary":"Rotate an API key (admin only)","operationId":"admin_rotate_api_key_v1_api_keys_rotate_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRotateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/configs":{"post":{"summary":"Publish or update a saved extraction config (admin only)","description":"Upsert a saved config pushed from Emio when a user enables REST API access.\n\nConfigs carrying a BYOK key require ``FIELD_ENCRYPTION_KEY`` to be configured\nso the secret can be encrypted at rest; without it we fail closed (503).","operationId":"admin_upsert_config_v1_configs_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigUpsertRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/configs/{config_id}":{"delete":{"summary":"Revoke a saved config (admin only)","operationId":"admin_revoke_config_v1_configs__config_id__delete","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"string","title":"Config Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/api-keys/cache/flush":{"post":{"summary":"Flush the local API-key cache on this worker (admin only)","description":"Drop every cached API-key lookup on the worker that handles this request.\n\nNote: in-process cache is per-uvicorn-worker. With multiple workers a single\ncall only flushes the worker that happens to receive it; other workers\nrefresh naturally after their TTL expires.","operationId":"admin_flush_api_key_cache_v1_admin_api_keys_cache_flush_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/balance/{tenant_id}":{"get":{"summary":"Get tenant credit balance","operationId":"get_billing_balance_v1_billing_balance__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/credits":{"post":{"summary":"Add credits to a tenant (admin only)","description":"Issue credits to a tenant and record the sale.\n\nThis is the currency boundary of the whole system: everything downstream of\nit is credits, which have no currency.\n\n**Validate, don't derive.** The caller sends the credit count the customer\nwas shown at checkout, and this endpoint confirms it against the active\nprice list. It does not compute a second count of its own — that is how a\ncustomer ends up shown one number and granted another when a price publish\nlands mid-checkout, or when a cached pricing scalar goes stale.\n\nIdempotent on ``provider_txn_id``: a webhook retry returns the original\ngrant rather than crediting the tenant twice. That is not a nicety — the\nDjango webhook deletes its own idempotency row when a call to this endpoint\ntimes out, so a grant that committed but whose response was lost gets\nretried, and only this side can tell the difference.","operationId":"add_billing_credits_v1_billing_credits_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCreditsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCreditsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/refunds":{"post":{"summary":"Refund all or part of a sale (admin only)","description":"Record a Paddle refund or an invoice credit note (dobropis).\n\nWrites a negative ``credit_grants`` row linked to the sale it reverses: the\nbalance and ``total_credits_purchased`` go down, revenue reporting nets the\nmoney off, and ``total_credits_used`` is untouched because nothing was\nconsumed. An admin clawback cannot do this — it books as consumption.\n\nIdempotent on ``(provider, provider_txn_id)`` like ``/v1/billing/credits``:\na retry returns the original refund with ``credited: false``.\n\nRejections: ``404 original_grant_not_found``; ``422 refund_mismatch``\n(other tenant or currency), ``refund_exceeds_original`` (cumulative\nrefunds would pass the sale's credits or money), ``idempotency_key_reused``;\n``409 insufficient_balance`` when the tenant has already burned the credits\n— resend with fewer ``credits`` and refund the rest as money only.","operationId":"refund_billing_credits_v1_billing_refunds_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefundRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefundResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/usage/{tenant_id}":{"get":{"summary":"Get usage history for a tenant","operationId":"get_billing_usage_v1_billing_usage__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start"}},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"End"}},{"name":"include_adjustments","in":"query","required":false,"schema":{"type":"boolean","description":"Include admin_adjustment rows. Off by default: this is per-page metering, and a top-up or comp is not usage. Purchases are at GET /v1/billing/grants/{tenant_id}.","default":false,"title":"Include Adjustments"},"description":"Include admin_adjustment rows. Off by default: this is per-page metering, and a top-up or comp is not usage. Purchases are at GET /v1/billing/grants/{tenant_id}."},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/rates":{"get":{"summary":"Get current billing rates","operationId":"get_billing_rates_v1_billing_rates_get","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingRatesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Upsert a billing rate (admin only)","operationId":"upsert_billing_rate_v1_billing_rates_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertRateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingRateItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/tenant-info/{tenant_id}":{"get":{"summary":"Get full billing state for a tenant","operationId":"get_tenant_info_v1_billing_tenant_info__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantInfoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/quote":{"get":{"summary":"Get a cost estimate for an operation","operationId":"get_billing_quote_v1_billing_quote_get","parameters":[{"name":"operation","in":"query","required":true,"schema":{"type":"string","title":"Operation"}},{"name":"billing_type","in":"query","required":true,"schema":{"type":"string","title":"Billing Type"}},{"name":"pages","in":"query","required":true,"schema":{"type":"integer","minimum":0,"title":"Pages"}},{"name":"tenant_id","in":"query","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"extraction_mode","in":"query","required":false,"schema":{"type":"string","default":"balanced","title":"Extraction Mode"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/training-quote":{"get":{"summary":"Get a cost estimate for a training job","operationId":"get_training_quote_v1_billing_training_quote_get","parameters":[{"name":"tenant_id","in":"query","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"billing_type","in":"query","required":false,"schema":{"type":"string","default":"full_service","title":"Billing Type"}},{"name":"optimizer_tier","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optimizer Tier"}},{"name":"total_examples","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Total Examples"}},{"name":"max_metric_calls","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Metric Calls"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrainingQuoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/dspy-examples-charge":{"post":{"summary":"Charge the flat DSPy examples export fee (paid plans only, idempotent)","description":"Deduct the flat DSPy-examples export fee from a tenant's credit balance.\n\nIdempotent on ``idempotency_key``: a retried call replays the original\ncharge (``charged=False``) instead of double-billing. Free-tier tenants are\nrejected with 403 — purchasing the export bundle requires a paid plan, the\nsame gate as training. Insufficient balance returns 403 with a detail shape\nmatching the training rejection so existing Emio parsing applies.","operationId":"charge_dspy_examples_v1_billing_dspy_examples_charge_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DspyExamplesChargeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DspyExamplesChargeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/config":{"get":{"summary":"Get active billing config (admin only)","operationId":"get_billing_config_v1_billing_config_get","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Create new billing config (admin only, append-only)","operationId":"create_billing_config_v1_billing_config_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingConfigCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/billing-config":{"get":{"summary":"Get active billing config + full history (admin only)","operationId":"admin_get_billing_config_v1_admin_billing_config_get","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBillingConfigHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Create new billing config (admin only, append-only)","operationId":"admin_create_billing_config_v1_admin_billing_config_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingConfigCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/usage-stats":{"get":{"summary":"Get aggregated usage stats (admin only). group_by: operation, billing_type, extraction_mode, tenant_id, category (consumption taxonomy: extraction, AI prefill, training, OCR), trigger (deprecated alias for category), day, week, month, day_category (daily × category for stacked charts). Consumption only unless include_adjustments=true.","operationId":"admin_usage_stats_v1_admin_usage_stats_get","parameters":[{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Date"}},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","default":"operation","title":"Group By"}},{"name":"include_adjustments","in":"query","required":false,"schema":{"type":"boolean","description":"Include admin_adjustment rows (audit view). Off by default: credit sales and comps are not consumption, and their imputed USD value would swamp metered usage and read as 100% margin.","default":false,"title":"Include Adjustments"},"description":"Include admin_adjustment rows (audit view). Off by default: credit sales and comps are not consumption, and their imputed USD value would swamp metered usage and read as 100% margin."},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUsageStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tenants":{"get":{"summary":"List all tenants with balances (admin only)","operationId":"admin_list_tenants_v1_admin_tenants_get","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTenantListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tenants/{tenant_id}/ledger":{"get":{"summary":"Get paginated ledger for a tenant (admin only)","operationId":"admin_tenant_ledger_v1_admin_tenants__tenant_id__ledger_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Date"}},{"name":"operation","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTenantLedgerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tenants/{tenant_id}/adjust-credits":{"post":{"summary":"Manual credit adjustment (admin only)","description":"Manually grant (positive) or claw back (negative) credits.\n\nCallers should always send ``Idempotency-Key``. Without it, a request that\ncommits here but whose response is lost — an 8-second client read timeout\nis enough — cannot be told apart from one that never arrived, and a retry\ngrants twice. Two layers use the key: the shared HTTP idempotency cache\n(concurrent retries get 409, completed ones replay byte-for-byte) and a\nguard stored on the grant or ledger row itself, which shares the balance\nchange's transaction and outlives the cache's TTL.","operationId":"admin_adjust_credits_v1_admin_tenants__tenant_id__adjust_credits_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"Makes a retry after a lost response safe. Reuse the same key for the same adjustment; a repeat replays the original response (or, after the 24h cache, returns it with credited=false) instead of moving credits twice.","title":"Idempotency-Key"},"description":"Makes a retry after a lost response safe. Reuse the same key for the same adjustment; a repeat replays the original response (or, after the 24h cache, returns it with credited=false) instead of moving credits twice."},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCreditAdjustRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCreditAdjustResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tenants/{tenant_id}/set-plan":{"post":{"summary":"Directly set a tenant's plan type (admin only)","operationId":"admin_set_plan_v1_admin_tenants__tenant_id__set_plan_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSetPlanRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSetPlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tenants/{tenant_id}/rate-limits":{"get":{"summary":"Get effective rate limits + override row for a tenant (admin only)","operationId":"admin_get_tenant_rate_limits_v1_admin_tenants__tenant_id__rate_limits_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantRateLimitsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"summary":"Upsert per-tenant rate-limit overrides (admin only)","description":"Upsert the override row, then evict the local override-cache entry.\n\nOther replicas on the load balancer pick up the change after their 60 s\ncache TTL — see :class:`TenantOverrideCache` for the rationale.","operationId":"admin_upsert_tenant_rate_limits_v1_admin_tenants__tenant_id__rate_limits_put","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantRateLimitsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantRateLimitsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Drop per-tenant rate-limit overrides (admin only)","description":"Delete the override row entirely so the tenant inherits all defaults.\n\nReturning 200 rather than 204 because the body carries the post-delete\neffective spec — useful for the admin UI to refresh the panel without\na follow-up GET. Idempotent: deleting an absent row returns\n``deleted: false`` but is otherwise a no-op (no 404).","operationId":"admin_delete_tenant_rate_limits_v1_admin_tenants__tenant_id__rate_limits_delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tenants/rate-limits/cache/flush":{"post":{"summary":"Flush the local rate-limit override cache on this worker (admin only)","description":"Drop every cached override on the worker that handles this request.\n\nSame per-worker caveat as the API-key cache flush: with multiple uvicorn\nworkers a single call only flushes one of them. Other workers refresh\nnaturally after their 60 s TTL.","operationId":"admin_flush_rate_limit_cache_v1_admin_tenants_rate_limits_cache_flush_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/llm-cost":{"post":{"summary":"Log LLM cost entry (internal, server-to-server)","operationId":"internal_log_llm_cost_v1_internal_llm_cost_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LlmCostLogRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/llm-costs":{"get":{"summary":"Get aggregated LLM costs (admin only)","operationId":"admin_get_llm_costs_v1_admin_llm_costs_get","parameters":[{"name":"tenant_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Id"}},{"name":"job_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"}},{"name":"operation","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation"}},{"name":"provider","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"}},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Date"}},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","default":"provider","title":"Group By"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LlmCostAggregateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/llm-costs/{job_id}":{"get":{"summary":"Get all LLM cost entries for a specific job (admin only)","operationId":"admin_get_job_llm_costs_v1_admin_llm_costs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LlmCostLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/provider-pricing":{"get":{"summary":"Get current and historical provider pricing (admin only)","operationId":"admin_get_provider_pricing_v1_admin_provider_pricing_get","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPricingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Create new provider pricing row (admin only, append-only)","operationId":"admin_create_provider_pricing_v1_admin_provider_pricing_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProviderPricingRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPricingItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/costs/by-task":{"get":{"summary":"Get per-task cost aggregates from usage_ledger (admin only)","operationId":"admin_costs_by_task_v1_admin_costs_by_task_get","parameters":[{"name":"tenant_id","in":"query","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Date"}},{"name":"operation","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation"}},{"name":"include_adjustments","in":"query","required":false,"schema":{"type":"boolean","description":"Include admin_adjustment rows. Ignored when operation is set.","default":false,"title":"Include Adjustments"},"description":"Include admin_adjustment rows. Ignored when operation is set."},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CostByTaskResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/costs/by-document":{"get":{"summary":"Get paginated ledger rows for a document or task scope (admin only)","operationId":"admin_costs_by_document_v1_admin_costs_by_document_get","parameters":[{"name":"document_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id"}},{"name":"tenant_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Id"}},{"name":"task_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CostByDocumentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/llm/missing-pricing":{"get":{"summary":"List (provider, model_name) pairs seen in llm_cost_log but not in llm_provider_pricing — silent margin killers. Admin only.","operationId":"admin_llm_missing_pricing_v1_admin_llm_missing_pricing_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingPricingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/free-tier-subsidy":{"get":{"summary":"Daily totals of LLM cost paid by the platform for free-tier extractions (total_cost_usd=0, credits_delta=0). Admin only.","operationId":"admin_free_tier_subsidy_v1_admin_free_tier_subsidy_get","parameters":[{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Date"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreeTierSubsidyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents/page-count":{"post":{"summary":"Get page counts for a list of documents","operationId":"get_document_page_counts_v1_documents_page_count_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageCountRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageCountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/documents":{"get":{"summary":"List documents for a tenant","operationId":"list_documents_v1_documents_get","parameters":[{"name":"tenant_id","in":"query","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"project_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id"}},{"name":"task_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Id"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"created_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created After"}},{"name":"exclude_default_scope","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Exclude Default Scope"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/canonical":{"post":{"summary":"Canonical envelope ingress","description":"Accept a canonical envelope (schema_version, operation, scope, resource, payload), normalize, validate payload, and dispatch by operation (inference, training, deployment, artifact).","operationId":"canonical_endpoint_v1_canonical_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanonicalEnvelope"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/credit-prices":{"get":{"summary":"The active credit price-list version and its entries (admin only)","description":"What checkout should quote, and which currencies we will accept.\n\nThe entries are the currency allow-list. A currency missing here is\nrejected by `POST /v1/billing/credits` rather than priced from a default.","operationId":"list_credit_prices_v1_admin_credit_prices_get","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditPriceListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Publish a new credit price-list version (admin only)","description":"Publish a new price-list version, atomic across every currency.\n\nThe sticky pricing rate is deliberately a human action. Nobody prices a\nSaaS product at spot — we would end up with EUR 18.37 price points that\nmove weekly. A spot move raises an alert; a person decides.\n\n`entries` is the complete set for the new version, not a patch: omitting a\ncurrency retires it. Publishing per currency is what lets two currencies\ndrift apart across a repricing announcement, so it is not offered.\n\nVersions are published, never mutated, so an old grant still points at the\nexact price set that priced it.","operationId":"publish_credit_prices_v1_admin_credit_prices_post","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPriceListRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditPriceListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/credit-prices":{"get":{"summary":"The active credit price list (any authenticated caller)","description":"Read side of the price list, for rendering checkout.\n\nSame payload as the admin endpoint. Prices are not a secret and the Django\napp needs them on a normal request path, not an admin one.","operationId":"get_credit_prices_v1_billing_credit_prices_get","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditPriceListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/fx-rate":{"get":{"summary":"Look up a booking FX rate, with last-known-good fallback (admin only)","description":"Rate to convert 1 ``base`` into ``quote`` on a given date.\n\n``rate_date`` in the response is the date of the rate actually used, which\nmay be earlier than ``requested_date``: the ECB does not publish on\nweekends or TARGET holidays, so a Sunday resolves to Friday.","operationId":"get_fx_rate_v1_admin_fx_rate_get","parameters":[{"name":"base","in":"query","required":false,"schema":{"type":"string","default":"EUR","title":"Base"}},{"name":"quote","in":"query","required":false,"schema":{"type":"string","default":"USD","title":"Quote"}},{"name":"on","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date; defaults to today (UTC).","title":"On"},"description":"ISO date; defaults to today (UTC)."},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FxRateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/grants/{tenant_id}":{"get":{"summary":"Credit purchase history for a tenant","operationId":"get_tenant_grants_v1_billing_grants__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/reconciliation":{"get":{"summary":"Check the credit ledger invariant across all tenants (admin only)","description":"``sum(grants) - sum(burns) == balance_credits``, per tenant.\n\nIntended to run nightly. It catches every class of bug in this subsystem:\na burn that never landed, a grant written without a balance update, a\ndouble-credited webhook. A non-empty ``drifted`` list is an alert, not a\nreport — investigate before the next billing close.","operationId":"get_reconciliation_v1_admin_reconciliation_get","parameters":[{"name":"include_ok","in":"query","required":false,"schema":{"type":"boolean","description":"Include tenants with no drift.","default":false,"title":"Include Ok"},"description":"Include tenants with no drift."},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReconciliationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/margin-report":{"get":{"summary":"Unit margin, realized margin, and FX effect as three lines (admin only)","description":"The three margins of §6, computed separately and never mixed.\n\nUnit margin is product economics at a frozen price — it moves when a model\ngets pricier or a prompt gets fatter. Realized margin is the accounting\nnumber, at booking rates, net of VAT and provider fees. FX effect is the\ngap. Folded together, a pricing problem and a currency problem look\nidentical.","operationId":"get_margin_report_v1_admin_margin_report_get","parameters":[{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO datetime, inclusive.","title":"Start"},"description":"ISO datetime, inclusive."},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO datetime, inclusive.","title":"End"},"description":"ISO datetime, inclusive."},{"name":"X-API-KEY","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarginReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health check","description":"Health check endpoint to verify the API is running. No authentication required.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}}},"components":{"schemas":{"ActivateDeploymentRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"project_id":{"type":"string","title":"Project Id"},"task_id":{"type":"string","title":"Task Id","default":"default"},"environment":{"type":"string","title":"Environment","default":"prod"},"artifact_id":{"type":"string","title":"Artifact Id"},"artifact_uri":{"type":"string","title":"Artifact Uri"},"rollout":{"$ref":"#/components/schemas/DeploymentRollout"}},"type":"object","required":["tenant_id","project_id","artifact_id","artifact_uri"],"title":"ActivateDeploymentRequest"},"AddCreditsRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credits","description":"Credits to issue. Derived from the amount when omitted."},"currency":{"type":"string","title":"Currency","description":"ISO-4217 code. EUR or USD.","default":"USD"},"gross_amount_minor":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Gross Amount Minor","description":"What the customer paid, incl. tax, in minor units."},"tax_amount_minor":{"type":"integer","minimum":0.0,"title":"Tax Amount Minor","default":0},"net_amount_minor":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Net Amount Minor","description":"Ex-tax, ex-provider-fee. Defaults to gross - tax."},"provider":{"type":"string","title":"Provider","description":"'paddle' | 'invoice' | 'admin' | 'migration'","default":"admin"},"provider_txn_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Txn Id","description":"Payment-provider transaction id; the idempotency key. Required for provider='invoice', where it is the invoice number."},"provider_net_minor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Provider Net Minor","description":"The provider's own reported earnings, if known."},"provider_settle_ccy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Settle Ccy"},"credit_price_list_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credit Price List Id"},"reason":{"type":"string","title":"Reason","default":""},"amount_usd":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Amount Usd","deprecated":true}},"type":"object","required":["tenant_id"],"title":"AddCreditsRequest","description":"Credit a tenant, in any supported currency.\n\nTwo accepted shapes. The modern one names the credits and the money\nexplicitly::\n\n    {\"tenant_id\": \"...\", \"credits\": 9500, \"currency\": \"EUR\",\n     \"gross_amount_minor\": 1900, \"tax_amount_minor\": 342,\n     \"provider\": \"paddle\", \"provider_txn_id\": \"txn_01h...\"}\n\nThe legacy one passes ``amount_usd`` and lets the server derive credits at\nthe USD issue price. It is deprecated but still supported so the Django app\ndoes not have to ship in lockstep with this change.\n\n``provider_txn_id`` is the webhook idempotency key: a Paddle retry with the\nsame id returns the original grant instead of crediting twice."},"AddCreditsResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"credits_added":{"type":"integer","title":"Credits Added","default":0},"currency":{"type":"string","title":"Currency","default":"USD"},"gross_amount_minor":{"type":"integer","title":"Gross Amount Minor","default":0},"new_balance_credits":{"type":"integer","title":"New Balance Credits","default":0},"grant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Grant Id"},"credited":{"type":"boolean","title":"Credited","default":true},"amount_usd":{"type":"number","title":"Amount Usd","default":0.0},"new_balance_usd":{"type":"number","title":"New Balance Usd","default":0.0}},"type":"object","required":["tenant_id"],"title":"AddCreditsResponse"},"AdminBillingConfigHistoryResponse":{"properties":{"active":{"$ref":"#/components/schemas/BillingConfigResponse"},"history":{"items":{"$ref":"#/components/schemas/BillingConfigResponse"},"type":"array","title":"History"}},"type":"object","required":["active","history"],"title":"AdminBillingConfigHistoryResponse"},"AdminCreditAdjustRequest":{"properties":{"credits":{"type":"integer","title":"Credits","description":"Signed; never zero. Sign must fit the kind."},"reason":{"type":"string","title":"Reason","default":""},"promote_to_paid":{"type":"boolean","title":"Promote To Paid","default":true},"kind":{"anyOf":[{"type":"string","enum":["comp","revocation","correction"]},{"type":"null"}],"title":"Kind"}},"type":"object","required":["credits"],"title":"AdminCreditAdjustRequest","description":"A credit movement with no money attached.\n\n``kind`` says what it is — see ``ControlPlaneStore.adjust_credits``:\n\n- ``comp`` (credits > 0): free credits — welcome, goodwill.\n- ``revocation`` (credits < 0): take back credits we issued.\n- ``correction`` (either sign): fix a metering error; reported as\n  consumption, under \"Metering correction\".\n\nOmitted, positive means ``comp`` and negative is the pre-taxonomy clawback\n(an ``admin_adjustment`` burn, excluded from reports). Invoice and Paddle\nsales belong on ``/v1/billing/credits``, refunds on ``/v1/billing/refunds``."},"AdminCreditAdjustResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"credits_adjusted":{"type":"integer","title":"Credits Adjusted"},"new_balance_credits":{"type":"integer","title":"New Balance Credits"},"new_plan_type":{"type":"string","title":"New Plan Type"},"reason":{"type":"string","title":"Reason"},"ledger_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ledger Id"},"grant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Grant Id"},"credited":{"type":"boolean","title":"Credited","default":true},"kind":{"type":"string","title":"Kind","default":"comp"}},"type":"object","required":["tenant_id","credits_adjusted","new_balance_credits","new_plan_type","reason"],"title":"AdminCreditAdjustResponse","description":"Result of ``POST /v1/admin/tenants/{tenant_id}/adjust-credits``.\n\nComps and revocations are grants and return ``grant_id``; corrections and\nunclassified clawbacks are ledger rows and return ``ledger_id``. The other\nis ``None``. ``kind`` echoes what was applied, including the default.\n\nA retry with the same ``Idempotency-Key`` either replays the original\nresponse byte-for-byte (header ``Idempotent-Replayed: true``) or, once that\ncache has expired, returns ``credited=False``: nothing moved, and the body\ndescribes the original adjustment. Both are success."},"AdminSetPlanRequest":{"properties":{"plan_type":{"type":"string","title":"Plan Type"}},"type":"object","required":["plan_type"],"title":"AdminSetPlanRequest"},"AdminSetPlanResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"plan_type":{"type":"string","title":"Plan Type"}},"type":"object","required":["tenant_id","plan_type"],"title":"AdminSetPlanResponse"},"AdminTenantLedgerResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"items":{"items":{"$ref":"#/components/schemas/UsageLedgerItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","default":0}},"type":"object","required":["tenant_id","items"],"title":"AdminTenantLedgerResponse"},"AdminTenantListItem":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"balance_credits":{"type":"integer","title":"Balance Credits","default":0},"total_credits_purchased":{"type":"integer","title":"Total Credits Purchased","default":0},"total_credits_used":{"type":"integer","title":"Total Credits Used","default":0},"last_activity":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Activity"},"plan_type":{"type":"string","title":"Plan Type","default":"free"}},"type":"object","required":["tenant_id"],"title":"AdminTenantListItem"},"AdminTenantListResponse":{"properties":{"tenants":{"items":{"$ref":"#/components/schemas/AdminTenantListItem"},"type":"array","title":"Tenants"}},"type":"object","required":["tenants"],"title":"AdminTenantListResponse"},"AdminUsageStatsAggregate":{"properties":{"group":{"type":"string","title":"Group"},"secondary_group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Secondary Group"},"total_credits":{"type":"integer","title":"Total Credits","default":0},"total_usd":{"type":"number","title":"Total Usd","default":0.0},"total_llm_cost_usd":{"type":"number","title":"Total Llm Cost Usd","default":0.0},"total_pages":{"type":"integer","title":"Total Pages","default":0},"job_count":{"type":"integer","title":"Job Count","default":0},"margin_usd":{"type":"number","title":"Margin Usd","default":0.0},"margin_pct":{"type":"number","title":"Margin Pct","default":0.0}},"type":"object","required":["group"],"title":"AdminUsageStatsAggregate"},"AdminUsageStatsResponse":{"properties":{"period":{"additionalProperties":{"type":"string"},"type":"object","title":"Period"},"aggregates":{"items":{"$ref":"#/components/schemas/AdminUsageStatsAggregate"},"type":"array","title":"Aggregates"},"totals":{"$ref":"#/components/schemas/AdminUsageStatsTotals"}},"type":"object","required":["period","aggregates","totals"],"title":"AdminUsageStatsResponse"},"AdminUsageStatsTotals":{"properties":{"total_credits":{"type":"integer","title":"Total Credits","default":0},"total_usd":{"type":"number","title":"Total Usd","default":0.0},"total_llm_cost_usd":{"type":"number","title":"Total Llm Cost Usd","default":0.0},"job_count":{"type":"integer","title":"Job Count","default":0},"margin_usd":{"type":"number","title":"Margin Usd","default":0.0},"margin_pct":{"type":"number","title":"Margin Pct","default":0.0}},"type":"object","title":"AdminUsageStatsTotals"},"ApiKeyCreateRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["tenant_id"],"title":"ApiKeyCreateRequest"},"ApiKeyCreateResponse":{"properties":{"key":{"type":"string","title":"Key"},"tenant_id":{"type":"string","title":"Tenant Id"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["key","tenant_id"],"title":"ApiKeyCreateResponse"},"ApiKeyRotateRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"old_key":{"type":"string","title":"Old Key"}},"type":"object","required":["tenant_id","old_key"],"title":"ApiKeyRotateRequest"},"BalanceResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"balance_credits":{"type":"integer","title":"Balance Credits","default":0},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"low_balance_threshold_credits":{"type":"integer","title":"Low Balance Threshold Credits","default":0},"balance_usd":{"type":"number","title":"Balance Usd"},"low_balance_threshold_usd":{"type":"number","title":"Low Balance Threshold Usd"}},"type":"object","required":["tenant_id","balance_usd","low_balance_threshold_usd"],"title":"BalanceResponse"},"BillingConfigCreateRequest":{"properties":{"credits_per_dollar":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credits Per Dollar"},"extraction_fast_cpp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extraction Fast Cpp"},"extraction_default_cpp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extraction Default Cpp"},"extraction_robust_cpp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extraction Robust Cpp"},"extraction_fast_cpp_byok":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extraction Fast Cpp Byok"},"extraction_default_cpp_byok":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extraction Default Cpp Byok"},"extraction_robust_cpp_byok":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extraction Robust Cpp Byok"},"to_markdown_cpp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"To Markdown Cpp"},"to_markdown_cpp_byok":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"To Markdown Cpp Byok"},"training_base_fee_credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Training Base Fee Credits"},"training_byok_fee_credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Training Byok Fee Credits"},"training_tiny_credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Training Tiny Credits"},"training_mipro_min_credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Training Mipro Min Credits"},"training_mipro_max_credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Training Mipro Max Credits"},"training_gepa_per_metric_call":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Training Gepa Per Metric Call"},"dspy_examples_fee_credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dspy Examples Fee Credits"},"free_extraction_pages":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Extraction Pages"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","title":"BillingConfigCreateRequest"},"BillingConfigResponse":{"properties":{"id":{"type":"integer","title":"Id"},"credits_per_dollar":{"type":"integer","title":"Credits Per Dollar","default":500},"price_list":{"anyOf":[{"$ref":"#/components/schemas/CreditPriceListResponse"},{"type":"null"}]},"extraction_fast_cpp":{"type":"integer","title":"Extraction Fast Cpp","default":1},"extraction_default_cpp":{"type":"integer","title":"Extraction Default Cpp","default":3},"extraction_robust_cpp":{"type":"integer","title":"Extraction Robust Cpp","default":5},"extraction_fast_cpp_byok":{"type":"integer","title":"Extraction Fast Cpp Byok","default":1},"extraction_default_cpp_byok":{"type":"integer","title":"Extraction Default Cpp Byok","default":1},"extraction_robust_cpp_byok":{"type":"integer","title":"Extraction Robust Cpp Byok","default":2},"to_markdown_cpp":{"type":"integer","title":"To Markdown Cpp","default":4},"to_markdown_cpp_byok":{"type":"integer","title":"To Markdown Cpp Byok","default":2},"training_base_fee_credits":{"type":"integer","title":"Training Base Fee Credits","default":1500},"training_byok_fee_credits":{"type":"integer","title":"Training Byok Fee Credits","default":1500},"training_tiny_credits":{"type":"integer","title":"Training Tiny Credits","default":300},"training_mipro_min_credits":{"type":"integer","title":"Training Mipro Min Credits","default":1000},"training_mipro_max_credits":{"type":"integer","title":"Training Mipro Max Credits","default":2000},"training_gepa_per_metric_call":{"type":"integer","title":"Training Gepa Per Metric Call","default":15},"dspy_examples_fee_credits":{"type":"integer","title":"Dspy Examples Fee Credits","default":1250},"free_extraction_pages":{"type":"integer","title":"Free Extraction Pages","default":10},"effective_from":{"type":"string","format":"date-time","title":"Effective From"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["id","effective_from"],"title":"BillingConfigResponse"},"BillingRateItem":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"operation":{"type":"string","title":"Operation"},"billing_type":{"type":"string","title":"Billing Type"},"rate_per_page_usd":{"type":"number","title":"Rate Per Page Usd"},"pricing_model":{"type":"string","title":"Pricing Model","default":"per_page"},"flat_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Flat Cost Usd"},"flat_cost_usd_above_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Flat Cost Usd Above Threshold"},"page_threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page Threshold"},"is_active":{"type":"boolean","title":"Is Active","default":true},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["operation","billing_type","rate_per_page_usd"],"title":"BillingRateItem"},"BillingRatesResponse":{"properties":{"rates":{"items":{"$ref":"#/components/schemas/BillingRateItem"},"type":"array","title":"Rates"}},"type":"object","required":["rates"],"title":"BillingRatesResponse"},"Body_extract_v1_extract_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"Document file (PDF, image, DOCX, XLSX, CSV, EML, etc.)"},"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema","description":"JSON Schema describing the fields to extract"},"mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mode","description":"Extraction mode: fast, trained, robust, robust-trained"},"artifact_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Id","description":"Trained pipeline artifact ID"},"config_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Config Id","description":"Saved config ID (cfg-...). Resolves schema, mode, trained artifact, and BYOK model/key from a config you published in Emio. Inline form fields override the config's values."},"allow_partial":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Partial","description":"Return partial results on validation failure"},"project_id":{"type":"string","title":"Project Id","description":"Project scope (defaults to 'default')","default":"default"},"llm_provider_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Provider Model","description":"BYOK extraction model in LiteLLM form (e.g. 'openai/gpt-4o-mini', 'gemini/gemini-2.0-flash', 'anthropic/claude-3-5-sonnet-latest'). Pair with llm_api_key to bill the call as BYOK."},"llm_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Api Key","description":"BYOK extraction LLM API key. Sending any non-empty value switches this request to BYOK billing rates."},"llm_api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Api Base","description":"Optional BYOK extraction LLM API base URL (self-hosted / proxy)."},"llm_max_tokens":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Llm Max Tokens","description":"Optional max-tokens override for the BYOK extraction LLM."},"llm_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Llm Temperature","description":"Optional temperature override for the BYOK extraction LLM (0.0–2.0)."},"llm_num_retries":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Llm Num Retries","description":"Optional retry count for the BYOK extraction LLM."},"ocr_provider_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Provider Model","description":"BYOK OCR model in LiteLLM form. Used by 'robust' / parser-LLM modes. Falls back to the extraction model when omitted."},"ocr_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Api Key","description":"BYOK OCR LLM API key. Independent from llm_api_key."},"ocr_api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Api Base","description":"Optional BYOK OCR LLM API base URL."},"ocr_max_tokens":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Ocr Max Tokens","description":"Optional max-tokens override for the BYOK OCR LLM."},"ocr_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Ocr Temperature","description":"Optional temperature override for the BYOK OCR LLM."},"ocr_num_retries":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Ocr Num Retries","description":"Optional retry count for the BYOK OCR LLM."}},"type":"object","required":["file"],"title":"Body_extract_v1_extract_post"},"Body_to_markdown_endpoint_v1_to_markdown_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"Document file (PDF, image, DOCX, XLSX, CSV, EML, etc.)"},"conversion_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversion Mode","description":"Conversion mode: 'default' (full OCR pipeline) or 'fast' (VLM-only, no OCR)."},"ocr_provider_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Provider Model","description":"BYOK OCR model in LiteLLM form (e.g. 'openai/gpt-4o-mini'). Pair with ocr_api_key to bill the call as BYOK."},"ocr_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Api Key","description":"BYOK OCR LLM API key. Sending any non-empty value switches this request to BYOK billing rates."},"ocr_api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Api Base","description":"Optional BYOK OCR LLM API base URL."},"ocr_max_tokens":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Ocr Max Tokens","description":"Optional max-tokens override for the BYOK OCR LLM."},"ocr_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Ocr Temperature","description":"Optional temperature override for the BYOK OCR LLM."},"ocr_num_retries":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Ocr Num Retries","description":"Optional retry count for the BYOK OCR LLM."}},"type":"object","required":["file"],"title":"Body_to_markdown_endpoint_v1_to_markdown_post"},"CanonicalEnvelope":{"properties":{"schema_version":{"type":"string","const":"1.0","title":"Schema Version"},"operation":{"$ref":"#/components/schemas/Operation"},"request_id":{"type":"string","title":"Request Id"},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency Key"},"scope":{"$ref":"#/components/schemas/Scope"},"resource":{"$ref":"#/components/schemas/Resource"},"payload":{"additionalProperties":true,"type":"object","title":"Payload"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"additionalProperties":false,"type":"object","required":["schema_version","operation","request_id","scope"],"title":"CanonicalEnvelope","description":"External canonical envelope at API ingress.\nStrict (extra=\"forbid\"). metadata is open dict.\nMutating operations require idempotency_key."},"ConfigResponse":{"properties":{"config_id":{"type":"string","title":"Config Id"},"tenant_id":{"type":"string","title":"Tenant Id"},"name":{"type":"string","title":"Name"},"extraction_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Mode"},"has_schema":{"type":"boolean","title":"Has Schema","default":false},"artifact_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Id"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"has_byok_key":{"type":"boolean","title":"Has Byok Key","default":false},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"allow_partial":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Partial"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["config_id","tenant_id","name"],"title":"ConfigResponse","description":"Public-safe view of a saved config (never exposes the BYOK secret)."},"ConfigUpsertRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"name":{"type":"string","title":"Name"},"config_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Config Id"},"extraction_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Mode"},"json_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Json Schema"},"artifact_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Id"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"byok_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Byok Api Key"},"byok_api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Byok Api Base"},"max_tokens":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Tokens"},"temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Temperature"},"allow_partial":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Partial"}},"type":"object","required":["tenant_id","name"],"title":"ConfigUpsertRequest","description":"Admin payload to publish/update a saved extraction config.\n\nEmio is the source of truth; it pushes a resolved snapshot of a user's\n``PipelineConfig`` here when the user explicitly enables REST API access.\n``config_id`` is omitted on first publish (the server mints one) and echoed\nback on subsequent re-publishes so the same id keeps resolving to the\nlatest snapshot.\n\n``byok_api_key`` travels in plaintext over the (TLS) admin channel and is\nencrypted at rest before it touches the database."},"CostByDocumentItem":{"properties":{"id":{"type":"integer","title":"Id"},"tenant_id":{"type":"string","title":"Tenant Id"},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"operation":{"type":"string","title":"Operation"},"pages":{"type":"integer","title":"Pages","default":0},"credits_delta":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credits Delta"},"total_cost_usd":{"type":"number","title":"Total Cost Usd","default":0.0},"extraction_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Mode"},"billing_type":{"type":"string","title":"Billing Type","default":""}},"type":"object","required":["id","tenant_id","timestamp","operation"],"title":"CostByDocumentItem"},"CostByDocumentResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CostByDocumentItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","default":0}},"type":"object","required":["items"],"title":"CostByDocumentResponse"},"CostByTaskItem":{"properties":{"task_id":{"type":"string","title":"Task Id"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"total_credits":{"type":"integer","title":"Total Credits","default":0},"total_charged_usd":{"type":"number","title":"Total Charged Usd","default":0.0},"total_llm_cost_usd":{"type":"number","title":"Total Llm Cost Usd","default":0.0},"total_pages":{"type":"integer","title":"Total Pages","default":0},"extraction_count":{"type":"integer","title":"Extraction Count","default":0},"document_count":{"type":"integer","title":"Document Count","default":0},"margin_usd":{"type":"number","title":"Margin Usd","default":0.0},"margin_pct":{"type":"number","title":"Margin Pct","default":0.0}},"type":"object","required":["task_id"],"title":"CostByTaskItem"},"CostByTaskResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"period":{"additionalProperties":{"type":"string"},"type":"object","title":"Period"},"items":{"items":{"$ref":"#/components/schemas/CostByTaskItem"},"type":"array","title":"Items"}},"type":"object","required":["tenant_id","period","items"],"title":"CostByTaskResponse"},"CreateProviderPricingRequest":{"properties":{"provider":{"type":"string","title":"Provider"},"model_name":{"type":"string","title":"Model Name"},"prompt_token_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prompt Token Cost"},"completion_token_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Completion Token Cost"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["provider","model_name"],"title":"CreateProviderPricingRequest"},"CreateTrainingJobRequest":{"properties":{"request_id":{"type":"string","title":"Request Id"},"tenant_id":{"type":"string","title":"Tenant Id"},"project_id":{"type":"string","title":"Project Id"},"task_id":{"type":"string","title":"Task Id","default":"default"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"payload":{"$ref":"#/components/schemas/TrainingJobPayload"}},"additionalProperties":true,"type":"object","required":["request_id","tenant_id","project_id"],"title":"CreateTrainingJobRequest"},"CreateTrainingJobResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"links":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Links"}},"type":"object","required":["job_id","status","created_at"],"title":"CreateTrainingJobResponse"},"CreditGrantItem":{"properties":{"id":{"type":"integer","title":"Id"},"tenant_id":{"type":"string","title":"Tenant Id"},"credits":{"type":"integer","title":"Credits"},"currency":{"type":"string","title":"Currency"},"gross_amount_minor":{"type":"integer","title":"Gross Amount Minor","default":0},"tax_amount_minor":{"type":"integer","title":"Tax Amount Minor","default":0},"net_amount_minor":{"type":"integer","title":"Net Amount Minor","default":0},"functional_currency":{"type":"string","title":"Functional Currency","default":"EUR"},"functional_net_minor":{"type":"integer","title":"Functional Net Minor","default":0},"fx_rate_to_functional":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fx Rate To Functional"},"fx_rate_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Fx Rate Date"},"fx_rate_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fx Rate Source"},"provider":{"type":"string","title":"Provider"},"provider_txn_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Txn Id"},"provider_net_minor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Provider Net Minor"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"reverses_grant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reverses Grant Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","tenant_id","credits","currency","provider","created_at"],"title":"CreditGrantItem","description":"One immutable sale record. See ControlPlaneStore.record_grant."},"CreditPriceEntryItem":{"properties":{"currency":{"type":"string","title":"Currency"},"credits_per_unit":{"type":"integer","title":"Credits Per Unit"},"min_topup_minor":{"type":"integer","title":"Min Topup Minor","default":500},"pricing_fx_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pricing Fx Rate"}},"type":"object","required":["currency","credits_per_unit"],"title":"CreditPriceEntryItem"},"CreditPriceListResponse":{"properties":{"price_list_id":{"type":"integer","title":"Price List Id"},"effective_from":{"type":"string","format":"date-time","title":"Effective From"},"change_reason":{"type":"string","title":"Change Reason","default":"repricing"},"announced_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Announced At"},"entries":{"items":{"$ref":"#/components/schemas/CreditPriceEntryItem"},"type":"array","title":"Entries"},"functional_currency":{"type":"string","title":"Functional Currency","default":"EUR"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["price_list_id","effective_from"],"title":"CreditPriceListResponse","description":"The price-list version currently in force, with all its entries.\n\nDjango renders checkout from this and quotes ``price_list_id`` back on the\nwebhook so the server can reject a quote made against a superseded version.\nThe entries are also the currency allow-list: a currency absent here cannot\nbe sold in, and adding one is a data change rather than a deploy."},"DatasetPayload":{"properties":{"input_uri":{"type":"string","title":"Input Uri","default":""},"ground_truth_uri":{"type":"string","title":"Ground Truth Uri","default":""},"input_mode":{"type":"string","enum":["markdown","media"],"title":"Input Mode","default":"markdown"}},"additionalProperties":true,"type":"object","title":"DatasetPayload"},"DeploymentResponse":{"properties":{"deployment_id":{"type":"string","title":"Deployment Id"},"status":{"type":"string","const":"active","title":"Status","default":"active"},"active_artifact_id":{"type":"string","title":"Active Artifact Id"},"artifact_uri":{"type":"string","title":"Artifact Uri"},"tenant_id":{"type":"string","title":"Tenant Id"},"project_id":{"type":"string","title":"Project Id"},"task_id":{"type":"string","title":"Task Id","default":"default"},"environment":{"type":"string","title":"Environment"},"activated_at":{"type":"string","format":"date-time","title":"Activated At"}},"type":"object","required":["deployment_id","active_artifact_id","artifact_uri","tenant_id","project_id","environment","activated_at"],"title":"DeploymentResponse"},"DeploymentRollout":{"properties":{"mode":{"type":"string","const":"immediate","title":"Mode","default":"immediate"}},"type":"object","title":"DeploymentRollout"},"DocumentItem":{"properties":{"document_id":{"type":"string","title":"Document Id"},"tenant_id":{"type":"string","title":"Tenant Id"},"project_id":{"type":"string","title":"Project Id"},"task_id":{"type":"string","title":"Task Id","default":"default"},"file_name":{"type":"string","title":"File Name"},"file_type":{"type":"string","title":"File Type"},"file_uri":{"type":"string","title":"File Uri"},"content_sha256":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Sha256"},"size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size Bytes"},"source":{"type":"string","title":"Source"},"page_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["document_id","tenant_id","project_id","file_name","file_type","file_uri","source","created_at"],"title":"DocumentItem"},"DocumentListResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"items":{"items":{"$ref":"#/components/schemas/DocumentItem"},"type":"array","title":"Items"}},"type":"object","required":["tenant_id","items"],"title":"DocumentListResponse"},"DspyExamplesChargeRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"idempotency_key":{"type":"string","title":"Idempotency Key"},"task_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Id"}},"type":"object","required":["tenant_id","idempotency_key"],"title":"DspyExamplesChargeRequest"},"DspyExamplesChargeResponse":{"properties":{"charged":{"type":"boolean","title":"Charged"},"credits":{"type":"integer","title":"Credits"},"total_usd":{"type":"number","title":"Total Usd"},"balance_credits":{"type":"integer","title":"Balance Credits"}},"type":"object","required":["charged","credits","total_usd","balance_credits"],"title":"DspyExamplesChargeResponse"},"FreeTierSubsidyItem":{"properties":{"day":{"type":"string","title":"Day"},"llm_cost_usd":{"type":"number","title":"Llm Cost Usd","default":0.0},"pages":{"type":"integer","title":"Pages","default":0},"rows":{"type":"integer","title":"Rows","default":0}},"type":"object","required":["day"],"title":"FreeTierSubsidyItem"},"FreeTierSubsidyResponse":{"properties":{"period":{"additionalProperties":{"type":"string"},"type":"object","title":"Period"},"items":{"items":{"$ref":"#/components/schemas/FreeTierSubsidyItem"},"type":"array","title":"Items"},"total_llm_cost_usd":{"type":"number","title":"Total Llm Cost Usd","default":0.0},"total_pages":{"type":"integer","title":"Total Pages","default":0},"total_rows":{"type":"integer","title":"Total Rows","default":0}},"type":"object","required":["period","items"],"title":"FreeTierSubsidyResponse"},"FxEffectBlock":{"properties":{"currency":{"type":"string","title":"Currency","default":"EUR"},"amount":{"type":"number","title":"Amount","default":0.0},"note":{"type":"string","title":"Note","default":""}},"type":"object","title":"FxEffectBlock"},"FxRateResponse":{"properties":{"base":{"type":"string","title":"Base"},"quote":{"type":"string","title":"Quote"},"rate":{"type":"number","title":"Rate"},"rate_date":{"type":"string","format":"date","title":"Rate Date"},"requested_date":{"type":"string","format":"date","title":"Requested Date"},"source":{"type":"string","title":"Source"},"stale_days":{"type":"integer","title":"Stale Days","default":0}},"type":"object","required":["base","quote","rate","rate_date","requested_date","source"],"title":"FxRateResponse"},"GrantHistoryResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"items":{"items":{"$ref":"#/components/schemas/CreditGrantItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","default":0}},"type":"object","required":["tenant_id","items"],"title":"GrantHistoryResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status","description":"'healthy' if the service is running, 'unhealthy' otherwise"}},"type":"object","required":["status"],"title":"HealthResponse","description":"Response model for health check."},"LlmCostAggregateItem":{"properties":{"group":{"type":"string","title":"Group"},"total_prompt_tokens":{"type":"integer","title":"Total Prompt Tokens","default":0},"total_completion_tokens":{"type":"integer","title":"Total Completion Tokens","default":0},"total_tokens":{"type":"integer","title":"Total Tokens","default":0},"total_estimated_usd":{"type":"number","title":"Total Estimated Usd","default":0.0},"total_dspy_usd":{"type":"number","title":"Total Dspy Usd","default":0.0},"total_cost_usd":{"type":"number","title":"Total Cost Usd","default":0.0},"entry_count":{"type":"integer","title":"Entry Count","default":0}},"type":"object","required":["group"],"title":"LlmCostAggregateItem"},"LlmCostAggregateResponse":{"properties":{"period":{"additionalProperties":{"type":"string"},"type":"object","title":"Period"},"aggregates":{"items":{"$ref":"#/components/schemas/LlmCostAggregateItem"},"type":"array","title":"Aggregates"},"totals":{"additionalProperties":true,"type":"object","title":"Totals"}},"type":"object","required":["period","aggregates","totals"],"title":"LlmCostAggregateResponse"},"LlmCostLogItem":{"properties":{"id":{"type":"integer","title":"Id"},"tenant_id":{"type":"string","title":"Tenant Id"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"operation":{"type":"string","title":"Operation"},"provider":{"type":"string","title":"Provider"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"prompt_tokens":{"type":"integer","title":"Prompt Tokens","default":0},"completion_tokens":{"type":"integer","title":"Completion Tokens","default":0},"total_tokens":{"type":"integer","title":"Total Tokens","default":0},"estimated_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Cost Usd"},"dspy_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dspy Cost Usd"},"dspy_metric_calls":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dspy Metric Calls"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","tenant_id","operation","provider","created_at"],"title":"LlmCostLogItem"},"LlmCostLogRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"operation":{"type":"string","title":"Operation"},"provider":{"type":"string","title":"Provider"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"prompt_tokens":{"type":"integer","title":"Prompt Tokens","default":0},"completion_tokens":{"type":"integer","title":"Completion Tokens","default":0},"total_tokens":{"type":"integer","title":"Total Tokens","default":0},"dspy_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dspy Cost Usd"},"dspy_metric_calls":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dspy Metric Calls"},"raw_usage_json":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw Usage Json"}},"type":"object","required":["tenant_id","operation","provider"],"title":"LlmCostLogRequest"},"LlmCostLogResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/LlmCostLogItem"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"LlmCostLogResponse"},"MarginReportResponse":{"properties":{"from_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From Date"},"to_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To Date"},"functional_currency":{"type":"string","title":"Functional Currency","default":"EUR"},"credits_burned":{"type":"integer","title":"Credits Burned","default":0},"unit_margin":{"$ref":"#/components/schemas/UnitMarginBlock"},"realized_margin":{"$ref":"#/components/schemas/RealizedMarginBlock"},"fx_effect":{"$ref":"#/components/schemas/FxEffectBlock"},"revenue_by_currency":{"items":{"$ref":"#/components/schemas/RevenueByCurrencyItem"},"type":"array","title":"Revenue By Currency"}},"type":"object","required":["unit_margin","realized_margin","fx_effect"],"title":"MarginReportResponse","description":"The three margins of §6, kept apart on purpose.\n\nMixing them means a pricing problem and a currency problem become\nindistinguishable."},"MissingPricingItem":{"properties":{"provider":{"type":"string","title":"Provider"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"tokens":{"type":"integer","title":"Tokens","default":0},"last_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen"},"calls":{"type":"integer","title":"Calls","default":0}},"type":"object","required":["provider"],"title":"MissingPricingItem","description":"One ``(provider, model_name)`` pair seen in ``llm_cost_log`` but missing\nfrom ``llm_provider_pricing`` — silent margin killer surfaced by §4.5.4."},"MissingPricingResponse":{"properties":{"days":{"type":"integer","title":"Days"},"items":{"items":{"$ref":"#/components/schemas/MissingPricingItem"},"type":"array","title":"Items"}},"type":"object","required":["days","items"],"title":"MissingPricingResponse"},"ModelEndpointPayload":{"properties":{"provider_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Model"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key"},"max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Tokens"},"temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Temperature"},"num_retries":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Num Retries"},"api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Base"}},"additionalProperties":true,"type":"object","title":"ModelEndpointPayload"},"ModelPayload":{"properties":{"provider_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Model"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key"},"max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Tokens"},"temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Temperature"},"num_retries":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Num Retries"},"api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Base"},"ocr_provider_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Provider Model"},"ocr_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Api Key"},"ocr_max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Ocr Max Tokens"},"ocr_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Ocr Temperature"},"trainer_provider_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trainer Provider Model"},"trainer_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trainer Api Key"},"trainer_max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Trainer Max Tokens"},"trainer_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Trainer Temperature"},"extraction":{"anyOf":[{"$ref":"#/components/schemas/ModelEndpointPayload"},{"type":"null"}]},"ocr":{"anyOf":[{"$ref":"#/components/schemas/ModelEndpointPayload"},{"type":"null"}]},"trainer":{"anyOf":[{"$ref":"#/components/schemas/ModelEndpointPayload"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"ModelPayload"},"Operation":{"type":"string","enum":["inference.extract","training.create_job","training.get_job","training.cancel_job","deployment.activate","deployment.resolve","artifact.get"],"title":"Operation","description":"Canonical operations. Mutating ops require idempotency_key."},"PageCountDocumentItem":{"properties":{"document_id":{"type":"string","title":"Document Id"},"pages":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pages"},"file_name":{"type":"string","title":"File Name","default":""}},"type":"object","required":["document_id"],"title":"PageCountDocumentItem"},"PageCountRequest":{"properties":{"document_ids":{"items":{"type":"string"},"type":"array","title":"Document Ids"},"tenant_id":{"type":"string","title":"Tenant Id"}},"type":"object","required":["document_ids","tenant_id"],"title":"PageCountRequest"},"PageCountResponse":{"properties":{"total_pages":{"type":"integer","title":"Total Pages"},"documents":{"items":{"$ref":"#/components/schemas/PageCountDocumentItem"},"type":"array","title":"Documents"}},"type":"object","required":["total_pages","documents"],"title":"PageCountResponse"},"ParsingPayload":{"properties":{"input_mode":{"anyOf":[{"type":"string","enum":["markdown","media"]},{"type":"null"}],"title":"Input Mode"},"pdf_image_parser":{"anyOf":[{"type":"string","enum":["docling","docling_vlm","ocr_llm","yolo_per_partes"]},{"type":"null"}],"title":"Pdf Image Parser"},"pdf_fallback_to_ocr_llm":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pdf Fallback To Ocr Llm"},"pdf_structured_fallback_to_image":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pdf Structured Fallback To Image"},"pdf_ocr_engine":{"anyOf":[{"type":"string","enum":["tesseract","rapidocr","easyocr"]},{"type":"null"}],"title":"Pdf Ocr Engine"},"pdf_ocr_lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdf Ocr Lang"},"use_ocr_llm_body":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Use Ocr Llm Body"},"image_parser":{"anyOf":[{"type":"string","enum":["pytesseract","rapidocr","docling","ocr_llm"]},{"type":"null"}],"title":"Image Parser"},"image_parser_fallback":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Image Parser Fallback"},"image_parser_lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Parser Lang"}},"additionalProperties":true,"type":"object","title":"ParsingPayload"},"PresignUploadRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id","default":"default"},"project_id":{"type":"string","title":"Project Id","default":"default"},"task_id":{"type":"string","title":"Task Id","default":"default"},"environment":{"type":"string","title":"Environment","description":"Logical environment tag (dev / prod / staging). Recorded as metadata on the canonical envelope and the document control-plane row, and echoed back on the response ``scope``. Does NOT drive bucket selection — that is server-owned via ``S3_BUCKET_NAME``. Kept on the request body for backwards compatibility and for logical scoping; clients can omit it and accept the default.","default":"dev"},"upload_kind":{"type":"string","enum":["document","training_input","training_ground_truth"],"title":"Upload Kind"},"filename":{"type":"string","title":"Filename","description":"Original filename (e.g. example.pdf, invoice_001.json)"},"content_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Content Length","description":"File size in bytes (for validation)"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type","description":"MIME type (can be derived)"},"dataset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id","description":"Training dataset ID. Required for training kinds. Server generates if omitted."},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id","description":"Document ID for extraction uploads. Server generates if omitted."},"artifact_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Id","description":"Artifact ID. When provided, server resolves scope from the artifact record."}},"additionalProperties":false,"type":"object","required":["upload_kind","filename"],"title":"PresignUploadRequest","description":"Request to generate a presigned PUT URL for a file upload."},"PresignUploadResponse":{"properties":{"upload_url":{"type":"string","title":"Upload Url","description":"Presigned PUT URL"},"method":{"type":"string","title":"Method","default":"PUT"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers"},"expires_in_s":{"type":"integer","title":"Expires In S","description":"URL validity in seconds","default":3600},"file_uri":{"type":"string","title":"File Uri","description":"Canonical s3:// URI of the uploaded file"},"dataset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id","description":"Dataset ID (for training kinds)"},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id","description":"Document ID (for document kind)"},"scope":{"additionalProperties":{"type":"string"},"type":"object","title":"Scope","description":"Echoed scope for debugging"}},"type":"object","required":["upload_url","file_uri"],"title":"PresignUploadResponse","description":"Response containing the presigned upload URL and canonical file URI."},"PricingResponse":{"properties":{"model_name":{"type":"string","title":"Model Name"},"input_per_1m":{"type":"number","title":"Input Per 1M"},"output_per_1m":{"type":"number","title":"Output Per 1M"},"thinking_per_1m":{"type":"number","title":"Thinking Per 1M"}},"type":"object","required":["model_name","input_per_1m","output_per_1m","thinking_per_1m"],"title":"PricingResponse"},"PricingUpsertRequest":{"properties":{"model_name":{"type":"string","title":"Model Name"},"input_per_1m":{"type":"number","title":"Input Per 1M"},"output_per_1m":{"type":"number","title":"Output Per 1M"},"thinking_per_1m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Thinking Per 1M"}},"type":"object","required":["model_name","input_per_1m","output_per_1m"],"title":"PricingUpsertRequest"},"ProviderPricingItem":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"provider":{"type":"string","title":"Provider"},"model_name":{"type":"string","title":"Model Name"},"prompt_token_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prompt Token Cost"},"completion_token_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Completion Token Cost"},"effective_from":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Effective From"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["provider","model_name"],"title":"ProviderPricingItem"},"ProviderPricingResponse":{"properties":{"current":{"items":{"$ref":"#/components/schemas/ProviderPricingItem"},"type":"array","title":"Current"},"history":{"items":{"$ref":"#/components/schemas/ProviderPricingItem"},"type":"array","title":"History"}},"type":"object","required":["current","history"],"title":"ProviderPricingResponse"},"PublicCostInfo":{"properties":{"credits_used":{"type":"integer","title":"Credits Used","description":"Credits consumed for this extraction. Partial results (schema validation failed but raw data was returned with validation_errors) still consume OCR + LLM work and are billed identically to successful extractions."},"pages":{"type":"integer","title":"Pages","description":"Number of document pages processed"},"balance_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Balance Remaining","description":"Tenant credit balance remaining after this extraction was billed. Null for admin/service callers that bypass billing. Poll this to build client-side low-balance safety guards without a separate call to GET /v1/billing/balance/{tenant_id}."}},"type":"object","required":["credits_used","pages"],"title":"PublicCostInfo","description":"Credits-based cost info returned to public API callers."},"PublicExtractResponse":{"properties":{"status":{"type":"string","title":"Status","description":"'success' (schema-valid) or 'partial' (validation failed; credits still consumed)"},"result":{"additionalProperties":true,"type":"object","title":"Result","description":"Extracted structured data matching the provided schema"},"cost":{"anyOf":[{"$ref":"#/components/schemas/PublicCostInfo"},{"type":"null"}],"description":"Credits consumed and pages processed"},"validation_errors":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Validation Errors","description":"Per-field validation errors when extraction is partial"}},"type":"object","required":["status","result"],"title":"PublicExtractResponse","description":"Simplified extraction response for the public API."},"PublicToMarkdownResponse":{"properties":{"markdown":{"type":"string","title":"Markdown","description":"Document content as markdown"},"plain_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plain Text","description":"Document content as plain text"},"meta":{"additionalProperties":true,"type":"object","title":"Meta","description":"Parser metadata"}},"type":"object","required":["markdown"],"title":"PublicToMarkdownResponse","description":"Simplified to-markdown response for the public API."},"PublishPriceListRequest":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/CreditPriceEntryItem"},"type":"array","minItems":1,"title":"Entries"},"change_reason":{"type":"string","enum":["launch","repricing","fx_review"],"title":"Change Reason","default":"repricing"},"announced_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Announced At","description":"When customers were told. Required for a repricing."},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["entries"],"title":"PublishPriceListRequest","description":"Publish a new price-list version, atomic across every currency.\n\nThe sticky pricing rate is a human decision: never derived from a live\nfeed, and a spot move does not reprice anything on its own — it raises an\nalert a person acts on.\n\n``entries`` is the **complete** set for the new version. Every currency we\nintend to keep selling in must appear; omitting one retires it. That is\ndeliberately not something that can happen one row at a time, because\nper-currency publishes are what let two currencies drift apart across a\nrepricing announcement."},"QuoteResponse":{"properties":{"currency":{"type":"string","title":"Currency","default":"USD"},"estimated_cost_usd":{"type":"number","title":"Estimated Cost Usd"},"estimated_credits":{"type":"integer","title":"Estimated Credits","default":0},"credits_per_page":{"type":"integer","title":"Credits Per Page","default":0},"pricing_model":{"type":"string","title":"Pricing Model"},"rate_per_page_usd":{"type":"number","title":"Rate Per Page Usd"},"flat_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Flat Cost Usd"},"pages":{"type":"integer","title":"Pages"},"free_pages_applied":{"type":"integer","title":"Free Pages Applied","default":0},"free_pages_remaining_after":{"type":"integer","title":"Free Pages Remaining After","default":0},"balance_usd":{"type":"number","title":"Balance Usd"},"balance_credits":{"type":"integer","title":"Balance Credits","default":0},"balance_sufficient":{"type":"boolean","title":"Balance Sufficient"},"breakdown":{"type":"string","title":"Breakdown"}},"type":"object","required":["estimated_cost_usd","pricing_model","rate_per_page_usd","pages","balance_usd","balance_sufficient","breakdown"],"title":"QuoteResponse"},"RealizedMarginBlock":{"properties":{"currency":{"type":"string","title":"Currency","default":"EUR"},"recognized_revenue":{"type":"number","title":"Recognized Revenue","default":0.0},"cogs":{"type":"number","title":"Cogs","default":0.0},"gross_margin":{"type":"number","title":"Gross Margin","default":0.0},"attribution":{"type":"string","title":"Attribution","default":"weighted-average issue price per tenant"},"cogs_translation_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cogs Translation Rate"},"fx_rate_available":{"type":"boolean","title":"Fx Rate Available","default":true}},"type":"object","title":"RealizedMarginBlock"},"ReconciliationItem":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"granted_credits":{"type":"integer","title":"Granted Credits"},"burned_credits":{"type":"integer","title":"Burned Credits"},"expected_balance":{"type":"integer","title":"Expected Balance"},"actual_balance":{"type":"integer","title":"Actual Balance"},"drift":{"type":"integer","title":"Drift"},"ok":{"type":"boolean","title":"Ok"}},"type":"object","required":["tenant_id","granted_credits","burned_credits","expected_balance","actual_balance","drift","ok"],"title":"ReconciliationItem"},"ReconciliationResponse":{"properties":{"checked_at":{"type":"string","format":"date-time","title":"Checked At"},"drifted":{"items":{"$ref":"#/components/schemas/ReconciliationItem"},"type":"array","title":"Drifted"},"drifted_count":{"type":"integer","title":"Drifted Count","default":0},"ok":{"type":"boolean","title":"Ok","default":true}},"type":"object","required":["checked_at","drifted"],"title":"ReconciliationResponse","description":"Result of the §3 invariant sweep.\n\n``sum(grants) - sum(burns) == balance_credits``. It catches every class of\nbug in this subsystem: a burn that never landed, a grant written without a\nbalance update, a double-credited webhook."},"RefundRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"credits":{"type":"integer","minimum":0.0,"title":"Credits","description":"Credits taken back from the balance."},"currency":{"type":"string","title":"Currency","description":"Must match the sale's currency."},"gross_amount_minor":{"type":"integer","minimum":0.0,"title":"Gross Amount Minor","description":"Money refunded, incl. tax.","default":0},"tax_amount_minor":{"type":"integer","minimum":0.0,"title":"Tax Amount Minor","default":0},"provider":{"type":"string","title":"Provider","description":"Same provider as the sale: 'invoice' | 'paddle'."},"provider_txn_id":{"type":"string","maxLength":120,"minLength":1,"title":"Provider Txn Id","description":"The refund's own id (dobropis number); the idempotency key."},"reverses_provider_txn_id":{"type":"string","maxLength":120,"minLength":1,"title":"Reverses Provider Txn Id","description":"provider_txn_id of the sale being refunded (the invoice number)."},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["tenant_id","credits","currency","provider","provider_txn_id","reverses_provider_txn_id"],"title":"RefundRequest","description":"Refund all or part of a sale: a Paddle refund or an invoice credit note.\n\nAmounts are positive — what goes back to the customer. Either ``credits``\nor ``gross_amount_minor`` may be zero, not both::\n\n    {\"tenant_id\": \"acme\", \"credits\": 10000, \"currency\": \"EUR\",\n     \"gross_amount_minor\": 2000, \"provider\": \"invoice\",\n     \"provider_txn_id\": \"DOB-2026-001\",\n     \"reverses_provider_txn_id\": \"RAC-2026-004\"}"},"RefundResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"grant_id":{"type":"integer","title":"Grant Id"},"reverses_grant_id":{"type":"integer","title":"Reverses Grant Id"},"credits_refunded":{"type":"integer","title":"Credits Refunded"},"currency":{"type":"string","title":"Currency"},"gross_amount_minor":{"type":"integer","title":"Gross Amount Minor"},"new_balance_credits":{"type":"integer","title":"New Balance Credits"},"credited":{"type":"boolean","title":"Credited"}},"type":"object","required":["tenant_id","grant_id","reverses_grant_id","credits_refunded","currency","gross_amount_minor","new_balance_credits","credited"],"title":"RefundResponse","description":"``credited`` is False when ``provider_txn_id`` was already recorded:\nnothing moved, and the body describes the original refund. Treat it as\nsuccess."},"ResolvedDeployment":{"properties":{"deployment_id":{"type":"string","title":"Deployment Id"},"artifact_id":{"type":"string","title":"Artifact Id"},"artifact_uri":{"type":"string","title":"Artifact Uri"},"tenant_id":{"type":"string","title":"Tenant Id"},"project_id":{"type":"string","title":"Project Id"},"task_id":{"type":"string","title":"Task Id","default":"default"},"environment":{"type":"string","title":"Environment"}},"type":"object","required":["deployment_id","artifact_id","artifact_uri","tenant_id","project_id","environment"],"title":"ResolvedDeployment"},"Resource":{"properties":{"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id"},"artifact_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Id"},"config_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Config Id"},"file_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Uri"}},"additionalProperties":false,"type":"object","title":"Resource","description":"Resource identifiers. file_uri is canonical S3 only (no presigned URLs)."},"RevenueByCurrencyItem":{"properties":{"currency":{"type":"string","title":"Currency"},"credits":{"type":"integer","title":"Credits","default":0},"gross_minor":{"type":"integer","title":"Gross Minor","default":0},"tax_minor":{"type":"integer","title":"Tax Minor","default":0},"net_minor":{"type":"integer","title":"Net Minor","default":0},"gross":{"type":"number","title":"Gross","default":0.0},"tax":{"type":"number","title":"Tax","default":0.0},"net":{"type":"number","title":"Net","default":0.0},"functional_currency":{"type":"string","title":"Functional Currency","default":"EUR"},"functional_net_minor":{"type":"integer","title":"Functional Net Minor","default":0},"functional_net":{"type":"number","title":"Functional Net","default":0.0},"provider_net_minor":{"type":"integer","title":"Provider Net Minor","default":0},"grant_count":{"type":"integer","title":"Grant Count","default":0}},"type":"object","required":["currency"],"title":"RevenueByCurrencyItem"},"SchemaPayload":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","default":"TrainingSchema"},"schema":{"additionalProperties":true,"type":"object","title":"Schema"}},"additionalProperties":true,"type":"object","title":"SchemaPayload"},"Scope":{"properties":{"tenant_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Id"},"project_id":{"type":"string","title":"Project Id"},"task_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Id"},"environment":{"type":"string","title":"Environment","default":"prod"}},"additionalProperties":false,"type":"object","required":["project_id"],"title":"Scope","description":"External scope: tenant_id optional at API ingress."},"TenantInfoResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"plan_type":{"type":"string","title":"Plan Type"},"balance_credits":{"type":"integer","title":"Balance Credits","default":0},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"credits_per_unit":{"type":"integer","title":"Credits Per Unit","default":500},"total_credits_purchased":{"type":"integer","title":"Total Credits Purchased","default":0},"total_credits_used":{"type":"integer","title":"Total Credits Used","default":0},"free_extraction_pages_remaining":{"type":"integer","title":"Free Extraction Pages Remaining"},"low_balance_threshold_credits":{"type":"integer","title":"Low Balance Threshold Credits","default":0},"low_balance":{"type":"boolean","title":"Low Balance"},"balance_usd":{"type":"number","title":"Balance Usd"},"low_balance_threshold_usd":{"type":"number","title":"Low Balance Threshold Usd"}},"type":"object","required":["tenant_id","plan_type","free_extraction_pages_remaining","low_balance","balance_usd","low_balance_threshold_usd"],"title":"TenantInfoResponse"},"TenantRateLimitsBucketSpec":{"properties":{"rate_per_sec":{"type":"number","title":"Rate Per Sec"},"burst":{"type":"integer","title":"Burst"}},"type":"object","required":["rate_per_sec","burst"],"title":"TenantRateLimitsBucketSpec"},"TenantRateLimitsOverride":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"heavy_rate_per_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Heavy Rate Per Sec"},"heavy_burst":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heavy Burst"},"general_rate_per_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"General Rate Per Sec"},"general_burst":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"General Burst"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"updated_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated By"}},"type":"object","required":["tenant_id"],"title":"TenantRateLimitsOverride","description":"Raw override row as persisted in ``tenant_rate_overrides``."},"TenantRateLimitsRequest":{"properties":{"heavy_rate_per_sec":{"anyOf":[{"type":"number","maximum":100.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"Heavy Rate Per Sec"},"heavy_burst":{"anyOf":[{"type":"integer","maximum":1000.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"Heavy Burst"},"general_rate_per_sec":{"anyOf":[{"type":"number","maximum":100.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"General Rate Per Sec"},"general_burst":{"anyOf":[{"type":"integer","maximum":1000.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"General Burst"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"updated_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated By"}},"type":"object","title":"TenantRateLimitsRequest","description":"Body for ``PUT /v1/admin/tenants/{tenant_id}/rate-limits``.\n\nEvery numeric field is independently optional: omit a field (or send\n``null``) to inherit the default for that knob. Sending all four fields\nas ``null`` upserts a row with no overrides — equivalent to leaving the\nrow absent and relying on defaults, but keeps the audit columns\n(``notes`` / ``updated_by`` / ``updated_at``) populated.\n\nServer enforces ``> 0`` and the ceilings declared above; values outside\nthat band cause a 400, not a silent clamp, so admins notice a typo\ninstead of getting a quietly wrong limit."},"TenantRateLimitsResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"defaults":{"additionalProperties":{"$ref":"#/components/schemas/TenantRateLimitsBucketSpec"},"type":"object","title":"Defaults"},"effective":{"additionalProperties":{"$ref":"#/components/schemas/TenantRateLimitsBucketSpec"},"type":"object","title":"Effective"},"override":{"anyOf":[{"$ref":"#/components/schemas/TenantRateLimitsOverride"},{"type":"null"}]},"ceilings":{"additionalProperties":{"type":"number"},"type":"object","title":"Ceilings"}},"type":"object","required":["tenant_id","defaults","effective","ceilings"],"title":"TenantRateLimitsResponse","description":"Body for ``GET /v1/admin/tenants/{tenant_id}/rate-limits``.\n\nCarries:\n\n* ``defaults`` — the server-wide :class:`Settings` values, so the admin\n  UI can render placeholders like \"Default: 2/s\" alongside each input.\n* ``effective`` — what the limiter would actually use right now (defaults\n  merged with the cached override, per-field).\n* ``override`` — the raw override row (or ``None`` if no overrides set).\n* ``ceilings`` — the validation upper bounds so the UI can surface them\n  next to inputs without hard-coding the numbers."},"ToMarkdownRequest":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id","description":"Tenant scope for this operation; must match the authenticated user API key's tenant (e.g. Emio uses str(user.pk)). Admin keys ignore this field.","default":"default"},"file_uri":{"type":"string","title":"File Uri","description":"S3 URI of the file to convert (s3://bucket/key)"},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Name","description":"Original filename (used for MIME detection). Inferred from file_uri if omitted."},"mode":{"anyOf":[{"type":"string","enum":["fast","default"]},{"type":"null"}],"title":"Mode","description":"Conversion mode. 'fast' sends file bytes directly to VLM. 'default' (or None) uses the full OCR pipeline."},"ocr":{"anyOf":[{"$ref":"#/components/schemas/ModelEndpointPayload"},{"type":"null"}],"description":"BYOK OCR LLM endpoint config."},"parsing":{"anyOf":[{"$ref":"#/components/schemas/ParsingPayload"},{"type":"null"}],"description":"Fine-grained parsing options (pdf_ocr_engine, image_parser, etc.)."}},"additionalProperties":false,"type":"object","required":["file_uri"],"title":"ToMarkdownRequest","description":"Request for OCR / to-markdown conversion."},"ToMarkdownResponse":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"markdown":{"type":"string","title":"Markdown","description":"Extracted markdown text"},"plain_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plain Text","description":"Plain text (without markdown formatting)"},"meta":{"additionalProperties":true,"type":"object","title":"Meta","description":"Parser metadata (mode, parser, etc.)"}},"type":"object","required":["markdown"],"title":"ToMarkdownResponse","description":"Response for OCR / to-markdown conversion."},"TrackingPayload":{"properties":{"experiment_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Experiment Name"}},"additionalProperties":true,"type":"object","title":"TrackingPayload"},"TrainingJobPayload":{"properties":{"dataset":{"$ref":"#/components/schemas/DatasetPayload"},"schema":{"anyOf":[{"$ref":"#/components/schemas/SchemaPayload"},{"type":"null"}]},"model_schema":{"anyOf":[{"$ref":"#/components/schemas/SchemaPayload"},{"type":"null"}]},"model":{"$ref":"#/components/schemas/ModelPayload"},"parsing":{"anyOf":[{"$ref":"#/components/schemas/ParsingPayload"},{"type":"null"}]},"training":{"$ref":"#/components/schemas/TrainingPayload"},"tracking":{"$ref":"#/components/schemas/TrackingPayload"},"trained_module_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trained Module Path"},"artifact_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Uri"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"llm_model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Model Name"},"llm_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Api Key"},"llm_max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Llm Max Tokens"},"llm_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Llm Temperature"},"llm_num_retries":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Llm Num Retries"},"ocr_llm_model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Llm Model Name"},"ocr_llm_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Llm Api Key"},"ocr_model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Model Name"},"ocr_api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocr Api Key"}},"additionalProperties":true,"type":"object","title":"TrainingJobPayload"},"TrainingJobStatusResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"status":{"type":"string","title":"Status"},"phase":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phase"},"progress":{"additionalProperties":true,"type":"object","title":"Progress"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"artifact":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Artifact"},"error":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Error"}},"type":"object","required":["job_id","status"],"title":"TrainingJobStatusResponse"},"TrainingPayload":{"properties":{"optimizer":{"anyOf":[{"type":"string","enum":["auto","mipro","gepa"]},{"type":"null"}],"title":"Optimizer"},"metric":{"anyOf":[{"type":"string","enum":["exact","fuzzy"]},{"type":"null"}],"title":"Metric"},"metric_scope":{"anyOf":[{"type":"string","enum":["aggregate","per_field"]},{"type":"null"}],"title":"Metric Scope"},"metric_kind":{"anyOf":[{"type":"string","enum":["graduated_pydantic","graduated_pydantic_item","graduated_pydantic_fuzzy","graduated_pydantic_fuzzy_item"]},{"type":"null"}],"title":"Metric Kind"},"verifier_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Verifier Enabled"},"dev_split":{"anyOf":[{"type":"number","exclusiveMaximum":1.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"Dev Split"},"llm_max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Llm Max Tokens"},"llm_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Llm Temperature"},"llm_num_retries":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Llm Num Retries"},"trainer_model_max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Trainer Model Max Tokens"},"trainer_model_temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Trainer Model Temperature"}},"additionalProperties":true,"type":"object","title":"TrainingPayload"},"TrainingQuoteResponse":{"properties":{"base_credits":{"type":"integer","title":"Base Credits"},"usage_credits":{"type":"integer","title":"Usage Credits"},"total_credits":{"type":"integer","title":"Total Credits"},"total_usd":{"type":"number","title":"Total Usd"},"breakdown":{"type":"string","title":"Breakdown"},"sufficient_balance":{"type":"boolean","title":"Sufficient Balance"},"current_balance_credits":{"type":"integer","title":"Current Balance Credits"}},"type":"object","required":["base_credits","usage_credits","total_credits","total_usd","breakdown","sufficient_balance","current_balance_credits"],"title":"TrainingQuoteResponse"},"UnitMarginBlock":{"properties":{"currency":{"type":"string","title":"Currency","default":"USD"},"charged_at_list":{"type":"number","title":"Charged At List","default":0.0},"llm_cogs":{"type":"number","title":"Llm Cogs","default":0.0},"gross_margin_at_list":{"type":"number","title":"Gross Margin At List","default":0.0},"gross_margin_at_list_pct":{"type":"number","title":"Gross Margin At List Pct","default":0.0},"excludes":{"items":{"type":"string"},"type":"array","title":"Excludes"}},"type":"object","title":"UnitMarginBlock"},"UpsertRateRequest":{"properties":{"operation":{"type":"string","title":"Operation"},"billing_type":{"type":"string","title":"Billing Type"},"rate_per_page_usd":{"type":"number","minimum":0.0,"title":"Rate Per Page Usd"}},"type":"object","required":["operation","billing_type","rate_per_page_usd"],"title":"UpsertRateRequest"},"UsageHistoryResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"items":{"items":{"$ref":"#/components/schemas/UsageLedgerItem"},"type":"array","title":"Items"}},"type":"object","required":["tenant_id","items"],"title":"UsageHistoryResponse"},"UsageLedgerItem":{"properties":{"id":{"type":"integer","title":"Id"},"tenant_id":{"type":"string","title":"Tenant Id"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"operation":{"type":"string","title":"Operation"},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id"},"pages":{"type":"integer","title":"Pages"},"rate_per_page_usd":{"type":"number","title":"Rate Per Page Usd"},"total_cost_usd":{"type":"number","title":"Total Cost Usd"},"billing_type":{"type":"string","title":"Billing Type"},"llm_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Llm Cost Usd"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id"},"credits_delta":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credits Delta"},"extraction_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Mode"},"trigger":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trigger"}},"type":"object","required":["id","tenant_id","timestamp","operation","pages","rate_per_page_usd","total_cost_usd","billing_type"],"title":"UsageLedgerItem"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}