{"openapi":"3.0.3","info":{"title":"AUBRAI x402 Service","version":"0.1.0","description":"Aubrai is the world's first decentralized AI co-scientist for longevity research, developed by VitaDAO. Orchestrates specialized sub-agents for literature synthesis, data analysis, and hypothesis generation to deliver comprehensive scientific reports on aging and lifespan extension.\n\nAll endpoints are gated by x402 micropayments using USDC on Base. Clients receive a `402 Payment Required` response with payment requirements, then retry with a signed `PAYMENT-SIGNATURE` header.\n\nProduction requests are served by the Aubrai production API (`api.aubr.ai`), which the gateway reaches through its attested Tinfoil enclave host; preview deployments use Aubrai staging.\n\nSee [x402 docs](https://docs.cdp.coinbase.com/x402/core-concepts/how-it-works) for details."},"servers":[{"url":"/","description":"Current deployment"}],"tags":[{"name":"Research","description":"Deep research endpoints — **$1.00** per job"},{"name":"Chat","description":"Aubrai chat agent — **$0.02** per request. Includes a TEE-encrypted private variant via HPKE."},{"name":"Literature","description":"Aubrai literature search agent — **$0.03** per request"},{"name":"System","description":"Health and operational endpoints"}],"paths":{"/api/deep-research/start":{"post":{"x-payment-info":{"protocols":["x402"],"pricingMode":"fixed","price":"$1.00"},"tags":["Research"],"summary":"Start a deep research job","description":"Submit a research query to AUBRAI. Requires an x402 payment signature.\n\nThe current Aubrai API accepts the job asynchronously and returns a message and conversation ID. Payment settlement is scheduled after the job is accepted.\n\nIf no `PAYMENT-SIGNATURE` header is provided, returns `402` with payment requirements.","operationId":"startResearch","parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"description":"x402 payment signature. Omit to receive `402` with payment requirements.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","description":"The research query or question.","example":"What are the latest developments in quantum computing?"},"conversationId":{"type":"string","description":"Optional. Continue an existing conversation by providing its ID."}}}}}},"responses":{"202":{"description":"Research job queued successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string","description":"Aubrai research run identifier."},"conversationId":{"type":"string","description":"Unique ID to poll for results."},"status":{"type":"string","enum":["queued"]}}},"example":{"messageId":"msg_abc123","conversationId":"conv_abc123","status":"queued"}}}},"400":{"description":"Invalid request body or missing `message` field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Missing required field: message"}}}},"402":{"description":"Payment required. Returns payment requirements in the `PAYMENT-REQUIRED` header and response body.","headers":{"PAYMENT-REQUIRED":{"description":"Encoded payment requirements for x402 clients.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"},"example":{"x402Version":2,"resource":{"url":"https://example.com/api/deep-research/start","description":"AUBRAI API request","mimeType":"application/json"},"accepts":[{"scheme":"exact","network":"eip155:8453","amount":"1000000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","payTo":"0xa06D...cDa9F","maxTimeoutSeconds":29400,"extra":{"name":"USDC","version":"2"}}]}}}},"500":{"description":"Internal server error (DB or payment verification failure).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Internal server error"}}}},"4xx":{"description":"Upstream AUBRAI API error relayed with original status code and body (e.g. 429 rate limit, 503 service unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"rate limit exceeded"}}}}}}},"/api/deep-research/{conversationId}":{"get":{"tags":["Research"],"summary":"Get research results","description":"Returns the current AUBRAI conversation history. The response contains `status`, `sessionStatus`, `worldState`, optional `activeMessageId`, and `turns`; each completed turn contains its reply and citations. `status`, on the conversation and on each turn, is `queued`, `running` or `cancelling` while research is in progress, then `completed`, `failed` or `cancelled`.","operationId":"getResearch","parameters":[{"name":"conversationId","in":"path","required":true,"description":"The conversation ID returned from `POST /api/deep-research/start`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Research status or completed results.","content":{"application/json":{"schema":{"type":"object","properties":{"conversationId":{"type":"string"},"status":{"type":"string","enum":["queued","running","cancelling","completed","failed","cancelled"]},"worldState":{"type":"object","nullable":true},"sessionStatus":{"type":"string"},"activeMessageId":{"type":"string"},"turns":{"type":"array","items":{"type":"object","properties":{"messageId":{"type":"string"},"objective":{"type":"string"},"reply":{"type":"string"},"citations":{"type":"array","items":{"type":"object"}},"status":{"type":"string","enum":["queued","running","cancelling","completed","failed","cancelled"]},"isFinal":{"type":"boolean"}}}}}},"examples":{"queued":{"summary":"Job still processing","value":{"conversationId":"conv_abc123","status":"queued"}},"completed":{"summary":"Job completed with results","value":{"conversationId":"conv_abc123","status":"completed","worldState":null,"sessionStatus":"completed","turns":[{"messageId":"msg_abc123","reply":"Quantum computing has seen...","citations":[],"status":"completed","isFinal":true}]}}}}}},"404":{"description":"Conversation not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Conversation not found"}}}},"500":{"description":"Internal server error (DB or unknown status).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Internal server error"}}}},"4xx":{"description":"Upstream AUBRAI API error relayed with original status code and body (e.g. 429 rate limit, 503 service unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"service unavailable"}}}}}}},"/api/deep-research/encrypted":{"post":{"x-payment-info":{"protocols":["x402"],"pricingMode":"fixed","price":"$1.00"},"tags":["Research"],"summary":"Start an encrypted deep-research run","description":"Start an HPKE-encrypted deep-research run inside an attested private enclave. The sealed plaintext carries `{message, recoveryKey}` (same X25519 → HKDF-SHA256 → XChaCha20-Poly1305 scheme as `/api/chat/encrypted`, request info string `\"chat-private-request-v1\"`). Async — poll the returned `pollUrl` by POSTing the sealed `{recoveryKey}`.","operationId":"startEncryptedResearch","parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hpke_ciphertext","hpke_ephemeral_public_key"],"properties":{"hpke_ciphertext":{"type":"string","description":"HPKE-encrypted {message, recoveryKey}, base64."},"hpke_ephemeral_public_key":{"type":"string","description":"Sender's one-time X25519 public key, base64."}}}}}},"responses":{"202":{"description":"Accepted — poll pollUrl for the sealed result.","content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string"},"status":{"type":"string","enum":["queued"]},"pollUrl":{"type":"string","format":"uri"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/deep-research/encrypted/status/{messageId}":{"post":{"tags":["Research"],"summary":"Poll an encrypted deep-research run","description":"Poll the sealed encrypted deep-research result. POST the sealed `{recoveryKey}` (same scheme). Response `status` is plaintext; when `completed`, decrypt `hpke_response_ciphertext` with info `\"chat-private-response-v1\"` to read `{reply, citations[], worldState, ...}`.","operationId":"getEncryptedResearchStatus","parameters":[{"name":"messageId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hpke_ciphertext","hpke_ephemeral_public_key"],"properties":{"hpke_ciphertext":{"type":"string","description":"HPKE-encrypted {recoveryKey}, base64."},"hpke_ephemeral_public_key":{"type":"string","description":"Sender's one-time X25519 public key, base64."}}}}}},"responses":{"200":{"description":"Run status (result sealed when completed).","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["queued","running","completed","failed"]},"hpke_response_ciphertext":{"type":"string"},"hpke_response_ephemeral_key":{"type":"string"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/chat":{"post":{"x-payment-info":{"protocols":["x402"],"pricingMode":"fixed","price":"$0.02"},"tags":["Chat"],"summary":"Start a chat job","description":"Submit a question to the Aubrai chat agent. Requires x402 payment of $0.02. Returns a requestId to poll for results. Literature retrieval is intent-driven and remains enabled when `fast: true`; use the separate deep-research API for deep research. Completed results use the canonical `ChatResult`: citeable `references[]`, non-citeable screening diagnostics in `rejectedReferences[]`, and citation/qualification checks in `quality`.\n\n**Poll** `/api/chat/status/{requestId}` every ~750ms until `status` is `completed` or `failed`; give up after 60s.","operationId":"startChat","parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"description":"x402 payment signature header. Make a request without it first to receive the 402 payment requirements.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","description":"The question to send to the chat agent.","example":"What foods improve longevity?"},"fast":{"type":"boolean","description":"Legacy compatibility hint. Literature retrieval remains intent-driven in chat; this flag does not disable scientific retrieval or select deep research."}}}}}},"responses":{"202":{"description":"Job queued successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string"},"status":{"type":"string","enum":["queued"]}}},"example":{"requestId":"req_abc123","status":"queued"}}}},"400":{"description":"Invalid request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Missing required field: message"}}}},"402":{"description":"Payment required.","headers":{"PAYMENT-REQUIRED":{"description":"x402 payment requirements header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/chat/status/{requestId}":{"get":{"tags":["Chat"],"summary":"Poll chat job status","description":"Poll for the result of a chat job. Poll every ~2s until `status` is `completed` or `failed`; give up after 60s. A 404 means the requestId is unknown (typo or expired >1h).","operationId":"getChatStatus","parameters":[{"name":"requestId","in":"path","required":true,"description":"The requestId returned from POST /api/chat.","schema":{"type":"string"}}],"responses":{"200":{"description":"Job status and result.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["queued","active","completed","failed"]},"progress":{"type":"object","nullable":true,"properties":{"stage":{"type":"string"},"percent":{"type":"integer"}}},"result":{"allOf":[{"$ref":"#/components/schemas/QueuedChatResult"}],"nullable":true},"error":{"type":"string","nullable":true,"description":"Set when status is \"failed\"."}}},"examples":{"queued":{"summary":"Queued","value":{"status":"queued"}},"active":{"summary":"In progress","value":{"status":"active","progress":{"stage":"thinking","percent":80}}},"completed":{"summary":"Completed","value":{"status":"completed","result":{"reply":"A primary trial reported improvement [1].","answer":"A primary trial reported improvement [1].","text":"A primary trial reported improvement [1].\n\nSources:\n[1] [supporting] Primary trial. https://doi.org/10.1000/trial","conversationId":"conversation_abc123","references":[{"ordinal":1,"title":"Primary trial","url":"https://doi.org/10.1000/trial","source":"journal","evidenceRole":"supporting"}],"rejectedReferences":[],"quality":{"contractValid":true,"primaryEvidencePresent":true},"responseTime":5442}}},"failed":{"summary":"Failed","value":{"status":"failed","error":"upstream error"}}}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/enclave-key":{"get":{"tags":["Chat"],"summary":"Fetch enclave HPKE public key","description":"Returns the X25519 public key clients use to encrypt requests to `/api/chat/encrypted` and `/api/deep-research/encrypted`. Free — no payment required. Cached for 60s.\n\n**Note:** Despite the `hpke_*` field name (retained for wire compatibility), the encrypted endpoints use a *custom* scheme — **not** standard HPKE. Do not use an HPKE library. See the protocol on those endpoints.","operationId":"getEnclaveKey","responses":{"200":{"description":"Enclave's HPKE public key.","content":{"application/json":{"schema":{"type":"object","properties":{"hpke_public_key":{"type":"string","description":"X25519 public key, base64-encoded."}}},"example":{"hpke_public_key":"pBbUKMAOC20RbFqfbqNcmqUwb8TGUbpxw4jS4OOj+QY="}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/chat/encrypted":{"post":{"x-payment-info":{"protocols":["x402"],"pricingMode":"fixed","price":"$0.02"},"tags":["Chat"],"summary":"Encrypted chat (TEE)","description":"Submit an encrypted prompt to the Aubrai chat agent running inside an attested private enclave. Proxied to the enclave after x402 payment verification. Requires x402 payment of $0.02; payment authorization is valid for up to 10 minutes. The Aubrai API responds synchronously with encrypted output.\n\n**Privacy boundary:** HPKE protects request and response transport. Direct chat generation stays on the private model path. Private runs do not use external literature tools.\n\n**Scheme:** X25519 ECDH → HKDF-SHA256 → XChaCha20-Poly1305. **Not standard HPKE — do not use an HPKE library.**\n\n**Protocol (plaintext = `{ message, recoveryKey?, conversationId?, attachments? }`; `message` is required; omit `recoveryKey` for stateless requests):**\n1. `serverPub = base64decode(GET /api/enclave-key → hpke_public_key)`\n2. `clientEphPriv = random 32 bytes; clientEphPub = X25519.pub(clientEphPriv)`\n3. `reqKey = HKDF-SHA256(ikm = X25519(clientEphPriv, serverPub), salt = clientEphPub, info = \"chat-private-request-v1\")`\n4. `nonce = random 24 bytes; ct = nonce || XChaCha20Poly1305.seal(reqKey, nonce, JSON.stringify(plaintext))`\n5. POST `{ hpke_ciphertext: base64(ct), hpke_ephemeral_public_key: base64(clientEphPub) }`\n6. Decrypt the completed response with info string `\"chat-private-response-v1\"`.\n\nFor persistent private chat, the client creates and retains `recoveryKey`; it must use the `aubrai_key_v1_` format documented by Aubrai and remains inside the sealed payload.","x-sealed-plaintext-required":["message"],"x-decrypted-response-schema":"#/components/schemas/ChatResult","operationId":"startEncryptedChat","parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"description":"x402 payment signature header.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hpke_ciphertext","hpke_ephemeral_public_key"],"properties":{"hpke_ciphertext":{"type":"string","description":"The encrypted prompt, base64-encoded. Only the enclave can decrypt this."},"hpke_ephemeral_public_key":{"type":"string","description":"Sender's one-time X25519 public key, base64-encoded."}}}}}},"responses":{"200":{"description":"Sync encrypted response.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string"},"hpke_response_ciphertext":{"type":"string","description":"Encrypted AI response, base64-encoded."},"hpke_response_ephemeral_key":{"type":"string","description":"Enclave's one-time public key, base64-encoded."}}},"example":{"requestId":"abc123","hpke_response_ciphertext":"<base64>","hpke_response_ephemeral_key":"<base64>"}}}},"202":{"description":"Queued — poll pollUrl for result.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string"},"status":{"type":"string","enum":["queued"]},"pollUrl":{"type":"string","format":"uri","description":"Absolute URL to poll for status."}}},"example":{"requestId":"abc123","status":"queued","pollUrl":"https://x402-api.aubr.ai/api/chat/encrypted/status/abc123"}}}},"400":{"description":"Invalid request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required.","headers":{"PAYMENT-REQUIRED":{"description":"x402 payment requirements header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Private chat is unavailable: the enclave is unreachable or its private mode is not ready. Checked before payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"private_chat_unavailable","reason":"private_mode_not_ready"}}}}}}},"/api/chat/encrypted/status/{requestId}":{"get":{"tags":["Chat"],"summary":"Poll encrypted chat status","description":"Poll the status of a queued encrypted chat job. Free — no payment required. When complete, returns the HPKE-encrypted reply payload; decrypted plaintext matches the `ChatResult` contract documented on POST /api/chat/encrypted.","operationId":"getEncryptedChatStatus","parameters":[{"name":"requestId","in":"path","required":true,"description":"The requestId returned from POST /api/chat/encrypted.","schema":{"type":"string"}}],"responses":{"200":{"description":"Job status. Completed responses carry the HPKE-encrypted reply.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","enum":["queued","active"]}}},{"type":"object","properties":{"status":{"type":"string","enum":["completed"]},"requestId":{"type":"string"},"hpke_response_ciphertext":{"type":"string","description":"Encrypted AI response, base64-encoded."},"hpke_response_ephemeral_key":{"type":"string","description":"Enclave's one-time public key, base64-encoded."}}},{"type":"object","properties":{"status":{"type":"string","enum":["failed"]},"error":{"type":"string"}}}]},"examples":{"queued":{"summary":"Still queued","value":{"status":"queued"}},"active":{"summary":"Processing","value":{"status":"active"}},"completed":{"summary":"Done — encrypted reply","value":{"status":"completed","requestId":"abc123","hpke_response_ciphertext":"<base64>","hpke_response_ephemeral_key":"<base64>"}},"failed":{"summary":"Failed","value":{"status":"failed","error":"upstream error"}}}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/literature/encrypted":{"post":{"x-payment-info":{"protocols":["x402"],"pricingMode":"fixed","price":"$0.03"},"tags":["Literature"],"summary":"Start an encrypted literature search","description":"Send an HPKE-sealed literature query (the `/api/literature` body plus optional `recoveryKey`, sealed to the key from `GET /api/enclave-key`) and receive a sealed result. Requires x402 payment of $0.03. The search queries leave the Aubrai enclave for external literature sources (Firecrawl, PubMed and others); the question and the answer stay sealed.\n\nChecked before payment: when the Aubrai API has private literature off this returns `403 private_literature_disabled`, and `503 private_literature_unavailable` when its private-mode status cannot be read.\n\n**Async polling:** returns `202 { requestId, status: \"pending\", pollUrl }`. Poll `GET /api/literature/encrypted/status/{requestId}` (free) until `status: \"completed\"`, then open the sealed result with the ephemeral key that sealed the request.","operationId":"startEncryptedLiterature","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hpke_ciphertext","hpke_ephemeral_public_key"],"properties":{"hpke_ciphertext":{"type":"string","description":"Base64 HPKE ciphertext of the JSON literature request."},"hpke_ephemeral_public_key":{"type":"string","description":"Base64 ephemeral public key the request was sealed with."}}}}}},"responses":{"202":{"description":"Accepted; poll pollUrl for the sealed result.","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string"},"status":{"type":"string","enum":["pending"]},"pollUrl":{"type":"string","format":"uri","description":"Absolute URL of the free status route."}}},"example":{"requestId":"elit_3f0c2a64-8d1e-4b7a-9c55-2e6f1b0a9d42","status":"pending","pollUrl":"https://x402-api.aubr.ai/api/literature/encrypted/status/elit_3f0c2a64-8d1e-4b7a-9c55-2e6f1b0a9d42"}}}},"400":{"description":"Missing envelope fields, undecryptable envelope, or an invalid literature request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required."},"403":{"description":"The Aubrai API has private literature off; checked before payment verification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"private_literature_disabled"}}}},"503":{"description":"The Aubrai private-mode status could not be read; checked before payment verification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"private_literature_unavailable"}}}}}}},"/api/literature/encrypted/status/{requestId}":{"get":{"tags":["Literature"],"summary":"Poll an encrypted literature search","description":"Free. `?timeout=` (seconds, up to 25) waits for the answer. Returns `{status: \"active\"}` while running, `{status: \"completed\", hpke_response_ciphertext, hpke_response_ephemeral_key}` sealed to the request's ephemeral key (the body is the `/api/literature/jobs/{jobId}` result), or `{status: \"failed\", error}`. Results are kept for an hour; an unknown id is `404 {\"status\":\"not_found\"}`.","operationId":"getEncryptedLiteratureStatus","parameters":[{"name":"requestId","in":"path","required":true,"description":"The requestId returned from POST /api/literature/encrypted.","schema":{"type":"string"}}],"responses":{"404":{"description":"Encrypted literature status is unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["not_found"]}}},"example":{"status":"not_found"}}}}}}},"/api/literature":{"post":{"x-payment-info":{"protocols":["x402"],"pricingMode":"fixed","price":"$0.03"},"tags":["Literature"],"summary":"Start a literature search","description":"Start a literature search across scientific sources. Requires x402 payment of $0.03.\n\nRetrieval runs on one unified research-paper index covering major biomedical journals, repositories, and preprint servers. The legacy `sources` / `perSourceLimit` / `allowSourceExpansion` / `sourceProfile` params are accepted for back-compat but no longer steer retrieval, so a source allowlist has no effect. For deliberate scoping use `scope`: `preprints` (biorxiv/medrxiv/arxiv), `no-preprints` (exclude those), or `trials` (clinicaltrials.gov). Omit `scope` for the full index (best recall).\n\nFor radar-style tracked terms, send separate `tags` with `tagMode: \"fanout\"`; do not concatenate tracked terms into `question` unless you want a combined search. Completed fanout responses include `resultsByTag`; clients should check each tag coverage, not just overall accepted counts.\n\nUpstream applies reference filtering by default (`filterReferences` defaults to true when omitted). Set `includeRejected: true` to receive `rejectedReferences[]` and per-ref `relevance` metadata on completed jobs.\n\n**Async polling:** Both fast and deep modes commonly return `202 { jobId, status: \"queued\" }`. Poll `GET /api/literature/jobs/{jobId}` (free, no second payment) until `status: \"completed\"`. Sync inline answers (HTTP 200) are possible but uncommon.","operationId":"startLiteratureQuery","parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"description":"x402 payment signature header.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiteratureQueryRequest"}}}},"responses":{"200":{"description":"Synchronous search result (uncommon for fast mode).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiteratureJobResult"}}}},"202":{"description":"Job queued — poll GET /api/literature/jobs/{jobId} (free).","content":{"application/json":{"schema":{"type":"object","required":["jobId","status"],"properties":{"jobId":{"type":"string"},"status":{"type":"string","enum":["queued"]}}},"example":{"jobId":"lit_abc123","status":"queued"}}}},"400":{"description":"Invalid request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Missing required field: question"}}}},"402":{"description":"Payment required.","headers":{"PAYMENT-REQUIRED":{"description":"x402 payment requirements header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/literature/jobs/{jobId}":{"get":{"tags":["Literature"],"summary":"Poll literature job","description":"Poll the status and results of a literature search job. Free — no second x402 payment. Completed payloads include upstream reference filtering metadata (`quality`, optional `rejectedReferences`, `references[].relevance`, `retrievalBackend`, `fallbackUsed`).","operationId":"getLiteratureJob","parameters":[{"name":"jobId","in":"path","required":true,"description":"The jobId returned from POST /api/literature.","schema":{"type":"string"}}],"responses":{"200":{"description":"Job status and result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiteratureJobResult"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/health":{"get":{"tags":["System"],"summary":"System health check","description":"Returns the health status of all system components (database, AUBRAI API, x402 facilitator), conversation statistics, and configuration info.\n\nReturns HTTP 503 if any component is `down`.","operationId":"healthCheck","responses":{"200":{"description":"System is healthy or degraded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"503":{"description":"System is down — at least one critical component is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/cron":{"get":{"tags":["System"],"summary":"Trigger settlement cron job","description":"Processes all `queued` conversations: checks AUBRAI for completion, settles valid payments, and marks expired ones as `timeout`.\n\nProtected by a Bearer token (`CRON_SECRET`). Typically invoked by Vercel Cron every minute.","operationId":"triggerCron","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Cron job executed successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}},"example":{"ok":true}}}},"401":{"description":"Unauthorized — invalid or missing Bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Unauthorized"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"CRON_SECRET Bearer token for the cron endpoint."}},"schemas":{"ChatReference":{"type":"object","required":["ordinal","id","title","url","source","evidenceRole","evidenceType","verification","confidence","roleReason"],"properties":{"ordinal":{"type":"integer","minimum":1},"id":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"},"source":{"type":"string"},"year":{"type":"integer","nullable":true},"doi":{"type":"string","nullable":true},"pmid":{"type":"string","nullable":true},"pmcid":{"type":"string","nullable":true},"evidenceRole":{"type":"string","enum":["supporting","context","lead_only"]},"evidenceType":{"type":"string","enum":["randomized_controlled_trial","controlled_trial","single_arm_trial","observational","systematic_review","narrative_review","preclinical","commentary","unknown"]},"verification":{"type":"string","enum":["verified","probable","unknown"]},"confidence":{"type":"number","minimum":0,"maximum":1},"roleReason":{"type":"string"},"duplicateOfOrdinal":{"type":"integer","minimum":1,"nullable":true}}},"ChatRejectedReference":{"type":"object","description":"A screened candidate that was not accepted into the citeable references[] namespace.","required":["candidateOrdinal","id","title","url","source","evidenceRole","evidenceType","verification","confidence","roleReason"],"properties":{"candidateOrdinal":{"type":"integer","minimum":1},"id":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"},"source":{"type":"string"},"year":{"type":"integer","nullable":true},"doi":{"type":"string","nullable":true},"pmid":{"type":"string","nullable":true},"pmcid":{"type":"string","nullable":true},"evidenceRole":{"type":"string","enum":["context","lead_only"]},"evidenceType":{"type":"string","enum":["randomized_controlled_trial","controlled_trial","single_arm_trial","observational","systematic_review","narrative_review","preclinical","commentary","unknown"]},"verification":{"type":"string","enum":["verified","probable","unknown"]},"confidence":{"type":"number","minimum":0,"maximum":1},"roleReason":{"type":"string"},"duplicateOfOrdinal":{"type":"integer","minimum":1,"nullable":true}}},"ChatQuality":{"type":"object","required":["citations","roleCounts","citedSupportingOrdinals","citedContextOrdinals","citedLeadOnlyOrdinals","primaryEvidencePresent","containsNonSupportingCitations","contractValid"],"properties":{"citations":{"type":"object","required":["markers","referenceCount","outOfRangeOrdinals","missingMarkerOrdinals","uncitedReferenceOrdinals","allMarkersResolve","contiguousMarkers"],"properties":{"markers":{"type":"array","items":{"type":"integer"}},"referenceCount":{"type":"integer"},"outOfRangeOrdinals":{"type":"array","items":{"type":"integer"}},"missingMarkerOrdinals":{"type":"array","items":{"type":"integer"}},"uncitedReferenceOrdinals":{"type":"array","items":{"type":"integer"}},"allMarkersResolve":{"type":"boolean"},"contiguousMarkers":{"type":"boolean"}}},"roleCounts":{"type":"object","additionalProperties":{"type":"integer"}},"citedSupportingOrdinals":{"type":"array","items":{"type":"integer"}},"citedContextOrdinals":{"type":"array","items":{"type":"integer"}},"citedLeadOnlyOrdinals":{"type":"array","items":{"type":"integer"}},"primaryEvidencePresent":{"type":"boolean"},"containsNonSupportingCitations":{"type":"boolean"},"contractValid":{"type":"boolean"},"qualification":{"type":"object","nullable":true,"additionalProperties":true}}},"ChatResult":{"type":"object","required":["reply","answer","text","conversationId","references","rejectedReferences","quality"],"properties":{"reply":{"type":"string","description":"Backward-compatible answer field."},"answer":{"type":"string"},"text":{"type":"string","description":"Self-contained answer plus deterministic source list."},"conversationId":{"type":"string"},"messageId":{"type":"string","nullable":true},"references":{"type":"array","items":{"$ref":"#/components/schemas/ChatReference"}},"rejectedReferences":{"type":"array","items":{"$ref":"#/components/schemas/ChatRejectedReference"},"description":"Screened context/lead candidates. These are diagnostics only and are never addressed by inline [N] markers."},"quality":{"$ref":"#/components/schemas/ChatQuality"},"metadata":{"type":"object","nullable":true,"additionalProperties":true}}},"QueuedChatResult":{"allOf":[{"$ref":"#/components/schemas/ChatResult"},{"type":"object","required":["responseTime"],"properties":{"responseTime":{"type":"integer","description":"Upstream processing time in milliseconds."}}}]},"Error":{"type":"object","properties":{"error":{"type":"string","description":"Error message."},"reason":{"type":"string","description":"Machine-readable reason (payment errors).","nullable":true},"message":{"type":"string","description":"Human-readable details (payment errors).","nullable":true}},"required":["error"]},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","down"]},"timestamp":{"type":"string","format":"date-time"},"uptime":{"type":"integer","description":"Seconds since process start."},"version":{"type":"string"},"components":{"type":"object","properties":{"upstreamApi":{"$ref":"#/components/schemas/ComponentHealth"},"database":{"$ref":"#/components/schemas/ComponentHealth"}}},"config":{"type":"object","properties":{"paymentAddress":{"type":"string"},"upstreamApiBaseUrl":{"type":"string"},"network":{"type":"string"},"pricing":{"type":"object","additionalProperties":{"type":"string"}}}}}},"PaymentRequired":{"type":"object","description":"x402 payment requirements returned when no valid payment is provided.","properties":{"x402Version":{"type":"integer","description":"x402 protocol version.","example":2},"resource":{"type":"object","description":"The resource that requires payment.","properties":{"url":{"type":"string","description":"The resource URL that requires payment.","example":"https://example.com/api/deep-research/start"},"description":{"type":"string","description":"Human-readable description of the paid resource.","example":"AUBRAI API request"},"mimeType":{"type":"string","example":"application/json"}}},"accepts":{"type":"array","description":"List of accepted payment methods.","items":{"type":"object","properties":{"scheme":{"type":"string","description":"Payment scheme identifier.","example":"exact"},"network":{"type":"string","description":"Chain ID in CAIP-2 format.","example":"eip155:8453"},"amount":{"type":"string","description":"Amount in token base units (USDC has 6 decimals, so 200000 = $0.20).","example":"200000"},"asset":{"type":"string","description":"Token contract address (USDC on Base).","example":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},"payTo":{"type":"string","description":"Wallet address to receive payment.","example":"0xa06D...cDa9F"},"maxTimeoutSeconds":{"type":"integer","description":"Maximum seconds before the payment authorization expires.","example":1800},"extra":{"type":"object","description":"Additional scheme-specific fields.","properties":{"name":{"type":"string","description":"Token name.","example":"USDC"},"version":{"type":"string","description":"Token contract version.","example":"2"}}}}}},"extensions":{"type":"object","description":"x402 Bazaar discovery extensions. Contains metadata for AI agent discoverability via x402scan.","properties":{"bazaar":{"type":"object","properties":{"info":{"type":"object","description":"Example input/output for the endpoint, used by AI agents to understand how to call it."},"schema":{"type":"object","description":"JSON Schema describing the expected input and output format."}}}}}}},"ComponentHealth":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","down"]},"latencyMs":{"type":"integer","nullable":true},"message":{"type":"string","nullable":true}}},"LiteratureQueryRequest":{"type":"object","required":["question"],"properties":{"question":{"type":"string","minLength":1,"maxLength":8192,"description":"The research question.","example":"What are the latest scientific findings on rapamycin and longevity?"},"mode":{"type":"string","enum":["fast","deep"],"default":"fast","description":"Search depth. Both modes may return 202 + jobId; poll is free."},"sourceProfile":{"type":"string","enum":["fast-default","deep-default","clinical","paperclip","litqa-recall"],"description":"Optional source profile. Omit to preserve old behavior and let Aubrai choose defaults.","example":"clinical"},"tags":{"type":"array","items":{"type":"string"},"description":"Tracked terms for radar-style searches. With tagMode=fanout, Aubrai fans out each tag instead of treating them as one combined query.","example":["NAD+","autophagy"]},"tagMode":{"type":"string","enum":["fanout","combined"],"description":"Use fanout for independent tag searches; use combined only when the user explicitly wants terms searched together.","example":"fanout"},"allowSourceExpansion":{"type":"boolean","deprecated":true,"description":"Deprecated / ignored. Aubrai retrieves from one unified scientific index; there is no per-source expansion to toggle. Use `scope` for deliberate scoping."},"maxResults":{"type":"integer","description":"Maximum number of results."},"perSourceLimit":{"type":"integer","description":"Deprecated / ignored — retrieval uses one unified index, so there is no per-source cap.","deprecated":true},"sources":{"type":"array","items":{"type":"string"},"deprecated":true,"description":"Deprecated / ignored. Retrieval uses one unified research-paper index, so a source allowlist has no effect. For deliberate scoping use `scope`."},"scope":{"type":"string","enum":["preprints","no-preprints","trials"],"description":"Opt-in retrieval scoping, mapped upstream to include/exclude domains. Omit for the full index (best recall). `preprints` = biorxiv/medrxiv/arxiv only; `no-preprints` = exclude those; `trials` = clinicaltrials.gov only. Restricting scope trades recall for a narrower, deliberate set.","example":"preprints"},"retrievalProfile":{"type":"string","enum":["default","litqa-recall"],"description":"Optional retrieval profile: \"default\" or \"litqa-recall\".","example":"litqa-recall"},"privacyMode":{"type":"string","description":"Optional plaintext privacy mode forwarded to Aubrai when provided."},"year":{"type":"string","description":"Filter by publication year."},"date_from":{"type":"string","format":"date","description":"Start date filter (YYYY-MM-DD)."},"date_to":{"type":"string","format":"date","description":"End date filter (YYYY-MM-DD)."},"filterReferences":{"type":"boolean","default":true,"description":"Default true upstream — drop off-topic refs. Set false for raw/unfiltered refs (debug)."},"includeRejected":{"type":"boolean","default":false,"description":"When true, completed responses include rejectedReferences[] and relevance.reason on rejected refs."}}},"LiteratureReferenceRelevance":{"type":"object","properties":{"accepted":{"type":"boolean"},"score":{"type":"number"},"matchedTerms":{"type":"array","items":{"type":"string"}},"flags":{"type":"array","items":{"type":"string"}},"reason":{"type":"string","nullable":true,"description":"Present on rejected refs when includeRejected is true."}}},"LiteratureReference":{"type":"object","properties":{"id":{"oneOf":[{"type":"number"},{"type":"string"}]},"title":{"type":"string"},"url":{"type":"string"},"source":{"type":"string","nullable":true},"year":{"type":"number","nullable":true},"item_date":{"type":"string","nullable":true,"description":"Publication date in YYYY-MM-DD format."},"relevance":{"$ref":"#/components/schemas/LiteratureReferenceRelevance"}}},"LiteratureQuality":{"type":"object","description":"Reference filtering summary from upstream. Present on completed jobs even when clients omit new request params.","properties":{"filtered":{"type":"boolean"},"rawCount":{"type":"integer"},"acceptedCount":{"type":"integer"},"rejectedCount":{"type":"integer"},"lowConfidence":{"type":"boolean"},"evidenceThin":{"type":"boolean"},"rejectionReasons":{"type":"object","additionalProperties":{"type":"integer"},"description":"e.g. { low_query_overlap: 4, low_relevance: 1 }"}}},"LiteratureResultsByTagEntry":{"type":"object","description":"Per-tag coverage summary for tagMode=fanout literature requests.","properties":{"tag":{"type":"string"},"covered":{"type":"boolean","description":"True when Aubrai found source-grounded accepted evidence for this tag."},"acceptedCount":{"type":"integer"},"rejectedCount":{"type":"integer"},"matchedTerms":{"type":"array","items":{"type":"string"}},"acceptedReferences":{"type":"array","items":{"type":"object"}},"rejectedReferences":{"type":"array","items":{"type":"object"},"nullable":true}}},"LiteratureJobResult":{"type":"object","properties":{"answer":{"type":"string","nullable":true},"formattedAnswer":{"type":"string","nullable":true},"references":{"type":"array","nullable":true,"items":{"$ref":"#/components/schemas/LiteratureReference"}},"rejectedReferences":{"type":"array","nullable":true,"items":{"type":"object"},"description":"Only when includeRejected was true on the request."},"contextPassages":{"type":"array","items":{"type":"object"},"nullable":true},"jobId":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"reasoning":{"type":"array","items":{"type":"string"},"nullable":true},"quality":{"$ref":"#/components/schemas/LiteratureQuality"},"retrievalBackend":{"type":"string","nullable":true,"example":"literature-agent"},"fallbackUsed":{"type":"boolean","nullable":true},"effectiveSources":{"type":"array","items":{"type":"string"},"description":"Sources actually used by upstream.","nullable":true},"sourceProfile":{"type":"string","nullable":true,"description":"Source profile applied by upstream."},"tagMode":{"type":"string","nullable":true,"description":"Tag mode applied by upstream."},"tags":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Tags echoed by upstream for radar/fanout requests."},"resultsByTag":{"type":"object","nullable":true,"additionalProperties":{"$ref":"#/components/schemas/LiteratureResultsByTagEntry"},"description":"Per-tag fanout coverage and accepted/rejected references. Check each tag coverage instead of relying only on overall quality counts."}}}}}}