{"openapi":"3.1.0","info":{"title":"ClinicalTrials.gov Query-to-Visualization Agent","summary":"Ask about clinical trials, get a cited chart specification.","description":"\nTurns a natural-language question about [ClinicalTrials.gov](https://clinicaltrials.gov)\ninto a chart specification in Vega-Lite style. Every data point cites the trials behind it,\nand `meta` says how the question was read, which filters were applied, how trials were\ncounted and which ClinicalTrials.gov API queries produced the numbers.\n\n## Flow\n\n1. **Ask:** `POST /v1/query` with a `query` and, optionally, structured fields\n   (`drug_name`, `condition`, `trial_phase`, `compare`, `chart_type`...). Fields are\n   authoritative: they override what the AI reads in the question, and a conflict is\n   reported in `meta.warnings`.\n2. **200:** most questions are answered synchronously. `status` is `ok` (the chart is in\n   `visualization`), or `no_matching_trials`, `out_of_scope` or `could_not_interpret`\n   (`visualization` is `null` and `meta.details` explains why). These are answers, not errors.\n3. **202:** a broad question whose retrieval is estimated to take longer than about a minute\n   runs as a background job instead. The body has a `job_id` and a `poll_url`.\n4. **Poll:** `GET /v1/jobs/{job_id}` every few seconds until `status` is `succeeded`\n   (the normal response is in `result`) or `failed` (the error body is in `error`).\n   `progress` reports the ClinicalTrials.gov pages fetched so far. No longer need the\n   answer? `DELETE /v1/jobs/{job_id}` cancels the job (`status: cancelled`).\n5. **Cite:** each data point has a stable `key`, its full `citation_count` and up to\n   `citations_per_datum` citations inline (`citations: \"full\"` inlines all of them, up to\n   2,000 per response). Page through every trial behind one data point\n   with `GET /v1/results/{result_id}/citations?datum=<key>`. Stored results expire after\n   24 hours (then `410 expired`).\n\n`GET /v1/options` lists the dimensions, measures, chart types and filter values (with\nlabels), so a client can build pickers. `GET /health` reports the database and\nClinicalTrials.gov status.\n\n## Errors\n\nReal errors share one body, and never contain internal details:\n\n```json\n{\"error\": {\"code\": \"upstream_unavailable\", \"message\": \"...\", \"details\": null, \"trace_id\": \"...\"}}\n```\n\n| HTTP | `code` | When |\n|---|---|---|\n| 400 | `rejected_by_policy` | The input guard classified the request as malicious |\n| 401 | `unauthorized` | `GET /v1/usage` without the admin token |\n| 404 | `not_found` | Unknown job, result, data point or path |\n| 405 | `method_not_allowed` | Wrong HTTP method for the path (see the `Allow` header) |\n| 410 | `expired` | The stored result, or the finished job, is past its 24-hour retention |\n| 422 | `invalid_request` | Validation failed; `details` lists each field (`loc`, `msg`) |\n| 429 | `too_many_requests` | Rate limit (with `Retry-After`), or too many active background jobs |\n| 500 | `internal_error` | A bug on our side |\n| 503 | `budget_exceeded` | Today's AI budget is used up |\n| 503 | `upstream_unavailable` | ClinicalTrials.gov is failing or changed data mid-read; retry |\n| 503 | `llm_unavailable` | The AI model and its fallback are failing; retry |\n| 503 | `safety_check_unavailable` | The input guard is failing; the API fails closed; retry |\n\nQuote the `trace_id` when reporting a problem.\n\n## Limits\n\n- **Rate limit:** 300 requests per minute per client IP on `/v1/*` (setting\n  `RATE_LIMIT_PER_IP_PER_MIN`). Over it, `429 too_many_requests` with a `Retry-After`\n  header in seconds. `/health` and the docs are not limited.\n- **Background jobs:** at most 10 pending or running jobs per client IP\n  (`MAX_ACTIVE_JOBS_PER_IP`); another broad question gets `429 too_many_requests`.\n  Asking the same question again while its job is active returns the same job.\n- **Daily AI budget:** every guard, planner and narrator call is costed. Once today's spend\n  (UTC day) reaches the cap (USD 100 by default, `LLM_DAILY_BUDGET_USD`), a question that\n  needs a model call gets `503 budget_exceeded` until midnight UTC. An exact repeat of a\n  question whose stored answer is still valid is still answered, with no model call (not\n  even the guard: it passed the first time). Jobs, citations and options keep working.\n  `meta.usage` reports each answer's calls and cost.\n- **ClinicalTrials.gov:** the API calls it at most about 40 times per minute for all users\n  together, which is why broad questions run as background jobs.\n\n## Versions\n\n`info.version` is the code version. Every response carries `schema_version` (now `2.0`),\nwhich changes when the response shape changes in a way that can break a client.\n\nNo authentication is needed, except for `GET /v1/usage` (admin bearer token).\n","version":"0.6.0"},"servers":[{"url":"https://api.cheiron.engineeradriel.com","description":"Production"},{"url":"http://localhost:8000","description":"Local (make up)"}],"paths":{"/health":{"get":{"tags":["health"],"summary":"Liveness and readiness","description":"Checks the database and ClinicalTrials.gov and reports the ClinicalTrials.gov data version. Only the database decides the status (503 when it is unreachable); a ClinicalTrials.gov outage is reported in `checks`, and questions then fail with `503 upstream_unavailable`. Not rate limited.","operationId":"health_health_get","responses":{"200":{"description":"The database is reachable. A ClinicalTrials.gov outage shows in `checks` but keeps `status` at `ok`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"},"examples":{"ok":{"summary":"Healthy","value":{"status":"ok","checks":{"database":"ok","ctgov":"ok"},"data_timestamp":"2026-10-23T09:00:04"}},"ctgov_down":{"summary":"ClinicalTrials.gov unreachable","value":{"status":"ok","checks":{"database":"ok","ctgov":"error"},"data_timestamp":null}}}}}},"503":{"description":"The database is unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"},"examples":{"unavailable":{"summary":"Database down","value":{"status":"unavailable","checks":{"database":"error","ctgov":"ok"},"data_timestamp":"2026-10-23T09:00:04"}}}}}}}}},"/v1/query":{"post":{"tags":["query"],"summary":"Ask a question, get a chart specification","description":"Runs the question through the input guard and the planning agent (in parallel), checks the\nplan, fetches the matching trials from ClinicalTrials.gov, aggregates them, verifies every\ncitation against the trial records, and has the narrator write the title.\n\n- **Fields override the AI.** `drug_name`, `condition`, `sponsor`, `country`, `trial_phase`,\n  `status`, the years, `compare`, `chart_type` and the options are applied as given, even when\n  the question says otherwise; a conflict is noted in `meta.warnings`.\n- **200** is an answer: a chart (`status: ok`) or the reason there is none\n  (`no_matching_trials`, `out_of_scope`, `could_not_interpret`).\n- **202** means the question is broad (its retrieval is estimated at over a minute) and runs\n  as a background job: poll `poll_url`. The same question while its job is active returns\n  the same job.\n- Each data point inlines up to `citations_per_datum` citations; page through all of them\n  with `GET /v1/results/{result_id}/citations?datum=<key>`.\n- Repeated questions reuse the cached plan and, if ClinicalTrials.gov data has not changed,\n  the stored result (`meta.cache`).","operationId":"query_v1_query_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryRequest"},"examples":{"condition_phases":{"summary":"Distribution: breast cancer trials by phase","value":{"query":"How are breast cancer trials distributed across phases?","citations_per_datum":3}},"drug_trend":{"summary":"Trend with a field: the drug comes from drug_name","value":{"query":"How has the number of trials for this drug changed per year since 2015?","drug_name":"Pembrolizumab","citations_per_datum":3}},"comparison":{"summary":"Comparison: two drugs by phase","value":{"query":"Compare phases for trials involving pembrolizumab vs nivolumab."}},"compare_field":{"summary":"Comparison with explicit groups and filters","value":{"query":"Compare these drugs by phase","compare":[{"label":"Pembrolizumab","drug_name":"pembrolizumab"},{"label":"Nivolumab","drug_name":"nivolumab"}],"condition":"melanoma","start_year":2015}},"countries":{"summary":"Geographic: top countries for recruiting lung cancer trials","value":{"query":"Which countries have the most recruiting trials for lung cancer?","top_n":10}},"network":{"summary":"Network: drugs that co-occur in melanoma trials","value":{"query":"Which drugs frequently co-occur in combination studies for melanoma?","citations_per_datum":2}}}}},"required":true},"responses":{"200":{"description":"An answer. `status` is `ok` with a chart, or `no_matching_trials`, `out_of_scope` or `could_not_interpret` with `visualization: null` and the reason in `meta.details`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryResponse"},"examples":{"ok":{"summary":"ok: bar chart (breast cancer trials by phase)","value":{"schema_version":"2.0","result_id":"d70db059-8f32-49a2-9fdc-231f5e3fd056","status":"ok","visualization":{"type":"bar_chart","title":"ClinicalTrials.gov breast cancer trials by phase","encoding":{"x":{"field":"phase","type":"ordinal","label":"Phase","sort":"natural"},"y":{"field":"trial_count","type":"quantitative","label":"Number of trials","unit":"trials"}},"data":[{"key":"PHASE2","phase":"Phase 2","trial_count":3546,"citation_count":3546,"citations":[{"nct_id":"NCT07729046","url":"https://clinicaltrials.gov/study/NCT07729046","title":"Neu Direction: Testing the Efficacy of Adding HER Inhibition to Standard of Care in Metastatic MLH1-low Endocrine-resistant ER+/HER2- Breast Cancer","evidence":[{"field":"protocolSection.designModule.phases[0]","excerpt":"PHASE2"}]}],"citations_truncated":true},{"key":"PHASE3","phase":"Phase 3","trial_count":1408,"citation_count":1408,"citations":[{"nct_id":"NCT07578116","url":"https://clinicaltrials.gov/study/NCT07578116","title":"Adding Surgery and Radiation to the Usual Treatment for HER2-Positive Breast Cancer That Had Already Spread at Diagnosis","evidence":[{"field":"protocolSection.designModule.phases[0]","excerpt":"PHASE3"}]}],"citations_truncated":true}]},"meta":{"interpretation":{"intent":"distribution","chart_type":"bar_chart","dimension":"phase","dimension_2":null,"measure":"trial_count","chart_type_source":"ai"},"filters":{"conditions":["breast cancer"]},"assumptions":["Interpreting 'breast cancer trials' as trials with condition 'breast cancer'."],"warnings":[],"notes":[],"counting_rule":"Each trial is counted once; trials with two phases get a combined bucket (e.g. Phase 2/Phase 3).","additive":true,"unique_trials":16765,"excluded":[],"sort":{"by":"x","order":"natural"},"api_queries":[{"group":null,"url":"https://clinicaltrials.gov/api/v2/studies?query.cond=%22breast+cancer%22","total_count":16765}],"citations":{"requested":"sample","applied":"sample","per_datum":3,"reason":null},"data_timestamp":"2026-10-23T09:00:04","retrieved_at":"2026-10-24T12:07:55+00:00","source":"clinicaltrials.gov","guard":{"verdict":"ok","model":"gpt-5.4-nano"},"planner":{"steps":2,"model":"gpt-5.4-mini"},"narration":{"model":"gpt-5.4-nano","attempts":2,"fallback":false,"errors":[]},"usage":{"llm_calls":5,"input_tokens":3878,"output_tokens":422,"cost_usd":0.00198,"models":["gpt-5.4-mini","gpt-5.4-nano"]},"cache":{"plan":"miss","result":"miss"},"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd","timings_ms":{"plan":2840,"count":610,"retrieve":25949,"aggregate":326,"narrate":2523,"total":32260},"details":{}}}},"ok_network":{"summary":"ok: network graph (drugs in melanoma trials)","value":{"schema_version":"2.0","result_id":"d351b949-6832-4d8b-a127-c2e16573f0cf","status":"ok","visualization":{"type":"network_graph","title":"ClinicalTrials.gov network of melanoma trials by drug, showing trial counts","encoding":{"node_id":{"field":"id","type":"nominal","label":"Entity"},"node_label":{"field":"label","type":"nominal","label":"Name"},"node_size":{"field":"weight","type":"quantitative","label":"Trials","unit":"trials"},"node_color":{"field":"community","type":"nominal","label":"Community"},"edge_source":{"field":"source","type":"nominal","label":"From"},"edge_target":{"field":"target","type":"nominal","label":"To"},"edge_width":{"field":"weight","type":"quantitative","label":"Shared trials","unit":"trials"}},"data":{"nodes":[{"key":"drug:nivolumab","id":"drug:nivolumab","label":"Nivolumab","type":"drug","weight":231,"degree":16,"community":2,"is_query_entity":false,"citation_count":231,"citations":[{"nct_id":"NCT07862530","url":"https://clinicaltrials.gov/study/NCT07862530","title":"Neoadjuvant RP2 + Nivolumab in Patients With Melanoma","evidence":[{"field":"protocolSection.armsInterventionsModule.interventions[1].name","excerpt":"Nivolumab"}]}],"citations_truncated":true},{"key":"drug:ipilimumab","id":"drug:ipilimumab","label":"Ipilimumab","type":"drug","weight":206,"degree":18,"community":2,"is_query_entity":false,"citation_count":206,"citations":[{"nct_id":"NCT07838974","url":"https://clinicaltrials.gov/study/NCT07838974","title":"Adding Anakinra and Tocilizumab to Nivolumab and Ipilimumab for the Treatment of Melanoma Patients 50 Years of Age or Older","evidence":[{"field":"protocolSection.armsInterventionsModule.interventions[4].name","excerpt":"Ipilimumab"}]}],"citations_truncated":true}],"edges":[{"key":"drug:ipilimumab|drug:nivolumab","source":"drug:ipilimumab","target":"drug:nivolumab","weight":122,"jaccard":0.3873,"citation_count":122,"citations":[{"nct_id":"NCT07838974","url":"https://clinicaltrials.gov/study/NCT07838974","title":"Adding Anakinra and Tocilizumab to Nivolumab and Ipilimumab for the Treatment of Melanoma Patients 50 Years of Age or Older","evidence":[{"field":"protocolSection.armsInterventionsModule.interventions[4].name","excerpt":"Ipilimumab"},{"field":"protocolSection.armsInterventionsModule.interventions[6].name","excerpt":"Nivolumab"}]}],"citations_truncated":true}]}},"meta":{"interpretation":{"intent":"network","chart_type":"network_graph","dimension":"drug","dimension_2":"drug","measure":"trial_count","chart_type_source":"ai"},"filters":{"conditions":["melanoma"]},"assumptions":["Interpreting 'combination studies' as trials involving more than one drug intervention."],"counting_rule":"Node size = distinct trials with that entity; edge width = distinct trials with both.","additive":false,"unique_trials":1446,"network":{"nodes_before":1439,"edges_before":4049,"nodes":38,"edges":130,"min_edge_weight":3,"top_n_per_type":40,"trials_with_data":2758,"trials_without_links":2334,"community_algorithm":"greedy modularity (networkx), weighted by edge weight"},"data_timestamp":"2026-10-23T09:00:04","guard":{"verdict":"ok","model":"gpt-5.4-nano"},"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd"}}},"no_matching_trials":{"summary":"no_matching_trials: a misspelt drug_name matches no trial","value":{"schema_version":"2.0","result_id":"3e0b7a4c-6f1d-4c2a-8b9e-5d7f0a1c2b3d","status":"no_matching_trials","visualization":null,"meta":{"interpretation":{"intent":"distribution","chart_type":"bar_chart","dimension":"phase","dimension_2":null,"measure":"trial_count","chart_type_source":"ai"},"filters":{"drugs":["pembrolizumb"]},"assumptions":["No chart was asked for; showing trials by phase."],"citations":{"requested":"sample","applied":"sample","per_datum":5,"reason":null},"data_timestamp":"2026-10-23T09:00:04","guard":{"verdict":"ok","model":"gpt-5.4-nano"},"cache":{"plan":"miss","result":"miss"},"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd","timings_ms":{"total":412},"details":{"search_counts":[{"group":null,"count":0}]}}}},"out_of_scope":{"summary":"out_of_scope: with a suggested question","value":{"schema_version":"2.0","result_id":null,"status":"out_of_scope","visualization":null,"meta":{"guard":{"verdict":"ok","model":"gpt-5.4-nano"},"planner":{"steps":1,"model":"gpt-5.4-mini"},"cache":{"plan":"miss"},"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd","details":{"reason":"average trial duration isn't a measure we can compute","suggestion":"How are trial durations distributed for trials started since 2015?"}}}},"could_not_interpret":{"summary":"could_not_interpret: no valid plan within the planner's steps","value":{"schema_version":"2.0","result_id":null,"status":"could_not_interpret","visualization":null,"meta":{"guard":{"verdict":"ok","model":"gpt-5.4-nano"},"planner":{"steps":6,"model":"gpt-5.4-mini"},"cache":{"plan":"miss"},"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd","details":{"errors":["dimension: Value error, unknown dimension 'colour'"],"best_attempt":{"scope":"in_scope","intent":"distribution","chart_type":"bar_chart","dimension":"colour","measure":"trial_count"}}}}}}}}},"202":{"description":"A broad question runs as a background job. Poll `poll_url` (`GET /v1/jobs/{job_id}`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"},"examples":{"job":{"summary":"Background job","value":{"job_id":"8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","status":"pending","poll_url":"/v1/jobs/8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","estimated_seconds":240}}}}}},"400":{"description":"The input guard classified the request as malicious (`rejected_by_policy`). The reason is not disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"rejected_by_policy":{"summary":"Rejected by the input guard","value":{"error":{"code":"rejected_by_policy","message":"Request rejected by input policy.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}}}}},"422":{"description":"Validation failed (`invalid_request`): `details` has one `{loc, msg}` per invalid field. Unknown fields are rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_request":{"summary":"Blank question and an unknown field","value":{"error":{"code":"invalid_request","message":"The request is not valid.","details":[{"loc":["body","query"],"msg":"String should have at least 1 character"},{"loc":["body","colour"],"msg":"Extra inputs are not permitted"}],"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}},"bad_compare":{"summary":"Only one compare group","value":{"error":{"code":"invalid_request","message":"The request is not valid.","details":[{"loc":["body","compare"],"msg":"Value error, compare needs 2-4 groups"}],"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}}}}},"429":{"description":"Rate limit (with `Retry-After`), or this client already has `MAX_ACTIVE_JOBS_PER_IP` (10) pending or running background jobs (`too_many_requests`).","headers":{"Retry-After":{"description":"Seconds until the client may retry (rate limit only).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"rate_limit":{"summary":"Rate limit","value":{"error":{"code":"too_many_requests","message":"Too many requests; slow down.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}},"too_many_jobs":{"summary":"Too many background jobs","value":{"error":{"code":"too_many_requests","message":"Too many background jobs for this client.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}}}}},"500":{"description":"A bug on our side (`internal_error`). Quote the `trace_id`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"internal_error":{"summary":"Internal error","value":{"error":{"code":"internal_error","message":"Something went wrong on our side.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}}}}},"503":{"description":"A dependency or the daily budget stops the answer. Retry later; `budget_exceeded` lasts until midnight UTC, but cached answers are still served meanwhile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"budget_exceeded":{"summary":"Today's AI budget is used up","value":{"error":{"code":"budget_exceeded","message":"Today's AI budget is used up; cached answers are still available.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}},"upstream_unavailable":{"summary":"ClinicalTrials.gov is failing","value":{"error":{"code":"upstream_unavailable","message":"ClinicalTrials.gov is not responding. Please retry later.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}},"upstream_changed":{"summary":"ClinicalTrials.gov data changed while reading it","value":{"error":{"code":"upstream_unavailable","message":"ClinicalTrials.gov data changed while reading it. Please retry.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}},"llm_unavailable":{"summary":"The AI model and its fallback are failing","value":{"error":{"code":"llm_unavailable","message":"The AI service is not responding. Please retry.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}},"safety_check_unavailable":{"summary":"The input guard is failing (the API fails closed)","value":{"error":{"code":"safety_check_unavailable","message":"Safety check unavailable, please retry later.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}}}}}}}},"/v1/results/{result_id}/citations":{"get":{"tags":["citations"],"summary":"List every trial behind one data point","description":"Every trial that contributes to one data point (bar, bucket, node, edge...) of a stored result, in the same order as its inline citations, keyset-paginated. Use the response's `result_id` and the data point's `key`; follow `next_cursor` until it is null. Each citation has the `evidence`: the trial record fields that place it in the data point. Results are kept for 24 hours.","operationId":"citations_v1_results__result_id__citations_get","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`result_id` from the query response.","title":"Result Id"},"description":"`result_id` from the query response."},{"name":"datum","in":"query","required":true,"schema":{"type":"string","description":"The data point's `key`, e.g. `PHASE2` or `drug:nivolumab`.","title":"Datum"},"description":"The data point's `key`, e.g. `PHASE2` or `drug:nivolumab`."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"`next_cursor` from the previous page; omit for the first.","title":"Cursor"},"description":"`next_cursor` from the previous page; omit for the first."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Citations per page.","default":50,"title":"Page Size"},"description":"Citations per page."}],"responses":{"200":{"description":"One page of citations, in the same order as the inline sample.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CitationPage"},"examples":{"first_page":{"summary":"First page with page_size=1","value":{"result_id":"d70db059-8f32-49a2-9fdc-231f5e3fd056","datum":"PHASE2","label":"Phase 2","citation_count":3546,"citations":[{"rank":0,"nct_id":"NCT07729046","url":"https://clinicaltrials.gov/study/NCT07729046","title":"Neu Direction: Testing the Efficacy of Adding HER Inhibition to Standard of Care in Metastatic MLH1-low Endocrine-resistant ER+/HER2- Breast Cancer","evidence":[{"field":"protocolSection.designModule.phases[0]","excerpt":"PHASE2"}]}],"next_cursor":1}}}}}},"404":{"description":"No such result, no data point with that `key` in it, or no database (`not_found`).","content":{"application/json":{"examples":{"not_found":{"summary":"Unknown result_id or datum","value":{"error":{"code":"not_found","message":"Not found.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The stored result is past its 24-hour retention; ask the question again (`expired`).","content":{"application/json":{"examples":{"expired":{"summary":"Expired result","value":{"error":{"code":"expired","message":"This result has expired; please run the query again.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Malformed `result_id`, missing `datum`, or `cursor` / `page_size` out of range (`invalid_request`).","content":{"application/json":{"examples":{"invalid_request":{"summary":"Missing datum","value":{"error":{"code":"invalid_request","message":"The request is not valid.","details":[{"loc":["query","datum"],"msg":"Field required"}],"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"More than `RATE_LIMIT_PER_IP_PER_MIN` (300) requests in a minute from this client on `/v1/*` (`too_many_requests`). Wait `Retry-After` seconds.","content":{"application/json":{"examples":{"too_many_requests":{"summary":"Rate limit","value":{"error":{"code":"too_many_requests","message":"Too many requests; slow down.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds until the client may retry (rate limit only).","schema":{"type":"integer"}}}},"500":{"description":"A bug on our side (`internal_error`). Quote the `trace_id`.","content":{"application/json":{"examples":{"internal_error":{"summary":"Internal error","value":{"error":{"code":"internal_error","message":"Something went wrong on our side.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/jobs/{job_id}":{"get":{"tags":["jobs"],"summary":"Poll a background job","description":"Status of the background job started by a broad question (`202` from `POST /v1/query`). Poll every few seconds: `pending` and `running` report `progress` in ClinicalTrials.gov pages; `succeeded` carries the normal query response in `result`; `failed` carries the shared error body in `error`, and so does `cancelled` (code `cancelled`, after `DELETE`). A job that crashed is retried before it is marked failed. A finished job is kept for 24 hours, like its result; after that, polling returns `410 expired`.","operationId":"job_status_v1_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`job_id` from the 202 response.","title":"Job Id"},"description":"`job_id` from the 202 response."}],"responses":{"200":{"description":"The job. `result` is set once `succeeded`, `error` once `failed`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatus"},"examples":{"running":{"summary":"Running","value":{"job_id":"8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","status":"running","progress":{"stage":"retrieve","pages_done":12,"pages_total":34},"estimated_seconds":240,"result":null,"error":null}},"succeeded":{"summary":"Succeeded: `result` is the normal response","value":{"job_id":"8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","status":"succeeded","progress":{"stage":"retrieve","pages_done":34,"pages_total":34},"estimated_seconds":240,"result":{"schema_version":"2.0","result_id":"d70db059-8f32-49a2-9fdc-231f5e3fd056","status":"ok","visualization":{"type":"bar_chart","title":"ClinicalTrials.gov breast cancer trials by phase","encoding":{"x":{"field":"phase","type":"ordinal","label":"Phase","sort":"natural"},"y":{"field":"trial_count","type":"quantitative","label":"Number of trials","unit":"trials"}},"data":[{"key":"PHASE2","phase":"Phase 2","trial_count":3546,"citation_count":3546,"citations":[{"nct_id":"NCT07729046","url":"https://clinicaltrials.gov/study/NCT07729046","title":"Neu Direction: Testing the Efficacy of Adding HER Inhibition to Standard of Care in Metastatic MLH1-low Endocrine-resistant ER+/HER2- Breast Cancer","evidence":[{"field":"protocolSection.designModule.phases[0]","excerpt":"PHASE2"}]}],"citations_truncated":true},{"key":"PHASE3","phase":"Phase 3","trial_count":1408,"citation_count":1408,"citations":[{"nct_id":"NCT07578116","url":"https://clinicaltrials.gov/study/NCT07578116","title":"Adding Surgery and Radiation to the Usual Treatment for HER2-Positive Breast Cancer That Had Already Spread at Diagnosis","evidence":[{"field":"protocolSection.designModule.phases[0]","excerpt":"PHASE3"}]}],"citations_truncated":true}]},"meta":{"interpretation":{"intent":"distribution","chart_type":"bar_chart","dimension":"phase","dimension_2":null,"measure":"trial_count","chart_type_source":"ai"},"filters":{"conditions":["breast cancer"]},"assumptions":["Interpreting 'breast cancer trials' as trials with condition 'breast cancer'."],"warnings":[],"notes":[],"counting_rule":"Each trial is counted once; trials with two phases get a combined bucket (e.g. Phase 2/Phase 3).","additive":true,"unique_trials":16765,"excluded":[],"sort":{"by":"x","order":"natural"},"api_queries":[{"group":null,"url":"https://clinicaltrials.gov/api/v2/studies?query.cond=%22breast+cancer%22","total_count":16765}],"citations":{"requested":"sample","applied":"sample","per_datum":3,"reason":null},"data_timestamp":"2026-10-23T09:00:04","retrieved_at":"2026-10-24T12:07:55+00:00","source":"clinicaltrials.gov","guard":{"verdict":"ok","model":"gpt-5.4-nano"},"planner":{"steps":2,"model":"gpt-5.4-mini"},"narration":{"model":"gpt-5.4-nano","attempts":2,"fallback":false,"errors":[]},"usage":{"llm_calls":5,"input_tokens":3878,"output_tokens":422,"cost_usd":0.00198,"models":["gpt-5.4-mini","gpt-5.4-nano"]},"cache":{"plan":"miss","result":"miss"},"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd","timings_ms":{"plan":2840,"count":610,"retrieve":25949,"aggregate":326,"narrate":2523,"total":32260},"details":{}}},"error":null}},"failed":{"summary":"Failed: `error` is the shared error body","value":{"job_id":"8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","status":"failed","progress":{"stage":"retrieve","pages_done":12,"pages_total":34},"estimated_seconds":240,"result":null,"error":{"code":"upstream_unavailable","message":"ClinicalTrials.gov is not responding. Please retry later.","details":null,"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd"}}},"cancelled":{"summary":"Cancelled by `DELETE`: `error.code` is `cancelled`","value":{"job_id":"8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","status":"cancelled","progress":{"stage":"retrieve","pages_done":12,"pages_total":34},"estimated_seconds":240,"result":null,"error":{"code":"cancelled","message":"This job was cancelled.","details":null,"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd"}}}}}}},"404":{"description":"No such job, or this deployment has no database (`not_found`).","content":{"application/json":{"examples":{"not_found":{"summary":"Unknown job_id","value":{"error":{"code":"not_found","message":"Not found.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The job finished more than 24 hours ago, or its stored result has expired; ask the question again (`expired`).","content":{"application/json":{"examples":{"expired":{"summary":"Expired job","value":{"error":{"code":"expired","message":"This job has expired; please run the query again.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"`job_id` is not a UUID (`invalid_request`).","content":{"application/json":{"examples":{"invalid_request":{"summary":"Malformed job_id","value":{"error":{"code":"invalid_request","message":"The request is not valid.","details":[{"loc":["path","job_id"],"msg":"Input should be a valid UUID, invalid character: found `n` at 0"}],"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"More than `RATE_LIMIT_PER_IP_PER_MIN` (300) requests in a minute from this client on `/v1/*` (`too_many_requests`). Wait `Retry-After` seconds.","content":{"application/json":{"examples":{"too_many_requests":{"summary":"Rate limit","value":{"error":{"code":"too_many_requests","message":"Too many requests; slow down.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds until the client may retry (rate limit only).","schema":{"type":"integer"}}}},"500":{"description":"A bug on our side (`internal_error`). Quote the `trace_id`.","content":{"application/json":{"examples":{"internal_error":{"summary":"Internal error","value":{"error":{"code":"internal_error","message":"Something went wrong on our side.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["jobs"],"summary":"Cancel a background job","description":"Stops a `pending` or `running` job: its status becomes `cancelled` (with `error.code` `cancelled`) and the worker stops within about a second, before its next ClinicalTrials.gov page. Returns the job as polling would. A job that has already finished (`succeeded`, `failed` or `cancelled`) is returned unchanged, so repeating the call is safe. Anyone holding the `job_id` can cancel the job, as anyone holding it can poll it: the id is a random UUID returned only to the client that asked. Asking the same question again afterwards starts a new job.","operationId":"cancel_job_v1_jobs__job_id__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`job_id` from the 202 response.","title":"Job Id"},"description":"`job_id` from the 202 response."}],"responses":{"200":{"description":"The job, as polling returns it: now `cancelled` if it was `pending` or `running`, otherwise unchanged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatus"},"examples":{"cancelled":{"summary":"Cancelled","value":{"job_id":"8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","status":"cancelled","progress":{"stage":"retrieve","pages_done":12,"pages_total":34},"estimated_seconds":240,"result":null,"error":{"code":"cancelled","message":"This job was cancelled.","details":null,"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd"}}},"already_finished":{"summary":"Already finished: returned unchanged","value":{"job_id":"8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11","status":"succeeded","progress":{"stage":"retrieve","pages_done":34,"pages_total":34},"estimated_seconds":240,"result":{"schema_version":"2.0","result_id":"d70db059-8f32-49a2-9fdc-231f5e3fd056","status":"ok","visualization":{"type":"bar_chart","title":"ClinicalTrials.gov breast cancer trials by phase","encoding":{"x":{"field":"phase","type":"ordinal","label":"Phase","sort":"natural"},"y":{"field":"trial_count","type":"quantitative","label":"Number of trials","unit":"trials"}},"data":[{"key":"PHASE2","phase":"Phase 2","trial_count":3546,"citation_count":3546,"citations":[{"nct_id":"NCT07729046","url":"https://clinicaltrials.gov/study/NCT07729046","title":"Neu Direction: Testing the Efficacy of Adding HER Inhibition to Standard of Care in Metastatic MLH1-low Endocrine-resistant ER+/HER2- Breast Cancer","evidence":[{"field":"protocolSection.designModule.phases[0]","excerpt":"PHASE2"}]}],"citations_truncated":true},{"key":"PHASE3","phase":"Phase 3","trial_count":1408,"citation_count":1408,"citations":[{"nct_id":"NCT07578116","url":"https://clinicaltrials.gov/study/NCT07578116","title":"Adding Surgery and Radiation to the Usual Treatment for HER2-Positive Breast Cancer That Had Already Spread at Diagnosis","evidence":[{"field":"protocolSection.designModule.phases[0]","excerpt":"PHASE3"}]}],"citations_truncated":true}]},"meta":{"interpretation":{"intent":"distribution","chart_type":"bar_chart","dimension":"phase","dimension_2":null,"measure":"trial_count","chart_type_source":"ai"},"filters":{"conditions":["breast cancer"]},"assumptions":["Interpreting 'breast cancer trials' as trials with condition 'breast cancer'."],"warnings":[],"notes":[],"counting_rule":"Each trial is counted once; trials with two phases get a combined bucket (e.g. Phase 2/Phase 3).","additive":true,"unique_trials":16765,"excluded":[],"sort":{"by":"x","order":"natural"},"api_queries":[{"group":null,"url":"https://clinicaltrials.gov/api/v2/studies?query.cond=%22breast+cancer%22","total_count":16765}],"citations":{"requested":"sample","applied":"sample","per_datum":3,"reason":null},"data_timestamp":"2026-10-23T09:00:04","retrieved_at":"2026-10-24T12:07:55+00:00","source":"clinicaltrials.gov","guard":{"verdict":"ok","model":"gpt-5.4-nano"},"planner":{"steps":2,"model":"gpt-5.4-mini"},"narration":{"model":"gpt-5.4-nano","attempts":2,"fallback":false,"errors":[]},"usage":{"llm_calls":5,"input_tokens":3878,"output_tokens":422,"cost_usd":0.00198,"models":["gpt-5.4-mini","gpt-5.4-nano"]},"cache":{"plan":"miss","result":"miss"},"trace_id":"f99e189b-ed92-498b-909d-51252c63d1cd","timings_ms":{"plan":2840,"count":610,"retrieve":25949,"aggregate":326,"narrate":2523,"total":32260},"details":{}}},"error":null}}}}}},"404":{"description":"No such job, or this deployment has no database (`not_found`).","content":{"application/json":{"examples":{"not_found":{"summary":"Unknown job_id","value":{"error":{"code":"not_found","message":"Not found.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The job finished more than 24 hours ago, or its stored result has expired (`expired`). There is nothing left to cancel.","content":{"application/json":{"examples":{"expired":{"summary":"Expired job","value":{"error":{"code":"expired","message":"This job has expired; please run the query again.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"`job_id` is not a UUID (`invalid_request`).","content":{"application/json":{"examples":{"invalid_request":{"summary":"Malformed job_id","value":{"error":{"code":"invalid_request","message":"The request is not valid.","details":[{"loc":["path","job_id"],"msg":"Input should be a valid UUID, invalid character: found `n` at 0"}],"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"More than `RATE_LIMIT_PER_IP_PER_MIN` (300) requests in a minute from this client on `/v1/*` (`too_many_requests`). Wait `Retry-After` seconds.","content":{"application/json":{"examples":{"too_many_requests":{"summary":"Rate limit","value":{"error":{"code":"too_many_requests","message":"Too many requests; slow down.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds until the client may retry (rate limit only).","schema":{"type":"integer"}}}},"500":{"description":"A bug on our side (`internal_error`). Quote the `trace_id`.","content":{"application/json":{"examples":{"internal_error":{"summary":"Internal error","value":{"error":{"code":"internal_error","message":"Something went wrong on our side.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/options":{"get":{"tags":["options"],"summary":"List dimensions, measures, chart types and filter values","description":"The registry the planner works from, so a client can build pickers: dimensions (what data can be grouped by, with their counting rules and, for categorical ones, their values and labels), measures, chart types, and the values the `trial_phase`, `status` and `country` fields accept.","operationId":"options_v1_options_get","responses":{"200":{"description":"The registry (shortened in this example).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Options"},"examples":{"options":{"summary":"Options","value":{"dimensions":[{"key":"phase","label":"Phase","kind":"categorical","multi_valued":false,"counting_rule":"Each trial is counted once; trials with two phases get a combined bucket (e.g. Phase 2/Phase 3).","values":[{"value":"PHASE3","label":"Phase 3"}]}],"measures":[{"key":"trial_count","label":"Number of trials","unit":"trials"}],"chart_types":[{"key":"bar_chart"},{"key":"network_graph"}],"filters":{"trial_phase":[{"value":"PHASE3","label":"Phase 3"}],"status":[{"value":"RECRUITING","label":"Recruiting"}],"country":["Germany","United States"]}}}}}}},"429":{"description":"More than `RATE_LIMIT_PER_IP_PER_MIN` (300) requests in a minute from this client on `/v1/*` (`too_many_requests`). Wait `Retry-After` seconds.","headers":{"Retry-After":{"description":"Seconds until the client may retry (rate limit only).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"too_many_requests":{"summary":"Rate limit","value":{"error":{"code":"too_many_requests","message":"Too many requests; slow down.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}}}}},"500":{"description":"A bug on our side (`internal_error`). Quote the `trace_id`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"internal_error":{"summary":"Internal error","value":{"error":{"code":"internal_error","message":"Something went wrong on our side.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}}}}}}}},"/v1/usage":{"get":{"tags":["admin"],"summary":"Today's AI usage and cost","description":"AI calls and cost so far today (UTC day), per model, with the daily budget. Needs `Authorization: Bearer <ADMIN_TOKEN>`; without `ADMIN_TOKEN` configured the endpoint always answers 401.","operationId":"usage_today_v1_usage_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`Bearer <ADMIN_TOKEN>`.","title":"Authorization"},"description":"`Bearer <ADMIN_TOKEN>`."}],"responses":{"200":{"description":"Today's usage and the budget.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummary"},"examples":{"usage":{"summary":"Usage","value":{"day":"2026-10-24","calls":412,"cost_usd":0.731,"unknown_cost_calls":0,"fallback_calls":3,"by_model":{"gpt-5.4-mini":{"calls":152,"cost_usd":0.627},"gpt-5.4-nano":{"calls":260,"cost_usd":0.104}},"budget_usd":100.0}}}}}},"401":{"description":"Missing or wrong admin token, or no `ADMIN_TOKEN` configured (`unauthorized`).","content":{"application/json":{"examples":{"unauthorized":{"summary":"No or wrong token","value":{"error":{"code":"unauthorized","message":"Authentication required.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"This deployment has no database (`not_found`).","content":{"application/json":{"examples":{"not_found":{"summary":"No database","value":{"error":{"code":"not_found","message":"Not found.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid request (`invalid_request`); the shared body, should a header ever fail validation.","content":{"application/json":{"examples":{"invalid_request":{"summary":"Invalid header","value":{"error":{"code":"invalid_request","message":"The request is not valid.","details":[{"loc":["header","authorization"],"msg":"Input should be a valid string"}],"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"More than `RATE_LIMIT_PER_IP_PER_MIN` (300) requests in a minute from this client on `/v1/*` (`too_many_requests`). Wait `Retry-After` seconds.","content":{"application/json":{"examples":{"too_many_requests":{"summary":"Rate limit","value":{"error":{"code":"too_many_requests","message":"Too many requests; slow down.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"Retry-After":{"description":"Seconds until the client may retry (rate limit only).","schema":{"type":"integer"}}}},"500":{"description":"A bug on our side (`internal_error`). Quote the `trace_id`.","content":{"application/json":{"examples":{"internal_error":{"summary":"Internal error","value":{"error":{"code":"internal_error","message":"Something went wrong on our side.","details":null,"trace_id":"5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"ApiQuery":{"properties":{"group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Group","description":"Comparison group label; null for a single search.","examples":[null]},"url":{"type":"string","title":"Url","description":"The ClinicalTrials.gov API v2 request, to reproduce the numbers.","examples":["https://clinicaltrials.gov/api/v2/studies?query.cond=%22breast+cancer%22"]},"total_count":{"type":"integer","title":"Total Count","description":"Trials the search matched.","examples":[16765]}},"type":"object","required":["group","url","total_count"],"title":"ApiQuery","description":"One ClinicalTrials.gov search behind the numbers."},"Channel":{"properties":{"field":{"type":"string","title":"Field","description":"The key in each data record that holds this channel's value.","examples":["trial_count"]},"type":{"type":"string","enum":["quantitative","nominal","ordinal","temporal"],"title":"Type","description":"Vega-Lite measurement type of the field.","examples":["quantitative"]},"label":{"type":"string","title":"Label","description":"Axis or legend title.","examples":["Number of trials"]},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit","description":"Unit of a quantitative value.","examples":["trials"]},"sort":{"anyOf":[{"type":"string","enum":["ascending","descending","natural"]},{"type":"null"}],"title":"Sort","description":"Order of the categories; `natural` is the domain order, e.g. phases.","examples":["natural"]},"time_unit":{"anyOf":[{"type":"string","const":"year"},{"type":"null"}],"title":"Time Unit","description":"Time unit of a temporal field.","examples":["year"]}},"type":"object","required":["field","type","label"],"title":"Channel","description":"Maps a data key to a visual channel (Vega-Lite style)."},"ChartType":{"type":"string","enum":["bar_chart","grouped_bar_chart","time_series","histogram","scatter_plot","network_graph","metric"],"title":"ChartType"},"ChartTypeOption":{"properties":{"key":{"type":"string","title":"Key","description":"Chart type.","examples":["bar_chart"]}},"type":"object","required":["key"],"title":"ChartTypeOption"},"Citation":{"properties":{"rank":{"type":"integer","title":"Rank","description":"Position in the data point's citation order.","examples":[0]},"nct_id":{"type":"string","title":"Nct Id","description":"ClinicalTrials.gov id.","examples":["NCT04430595"]},"url":{"type":"string","title":"Url","description":"The trial's page on ClinicalTrials.gov.","examples":["https://clinicaltrials.gov/study/NCT04430595"]},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Brief title.","examples":["Multi-4SCAR-T Therapy Targeting Breast Cancer"]},"evidence":{"items":{"$ref":"#/components/schemas/Evidence"},"type":"array","title":"Evidence","description":"Why this trial is in the data point."}},"type":"object","required":["rank","nct_id","url","title","evidence"],"title":"Citation","description":"One trial behind a data point."},"CitationPage":{"properties":{"result_id":{"type":"string","title":"Result Id","description":"Stored result id.","examples":["d70db059-8f32-49a2-9fdc-231f5e3fd056"]},"datum":{"type":"string","title":"Datum","description":"The data point's `key`.","examples":["PHASE2"]},"label":{"type":"string","title":"Label","description":"The data point's label.","examples":["Phase 2"]},"citation_count":{"type":"integer","title":"Citation Count","description":"Trials behind the data point.","examples":[3546]},"citations":{"items":{"$ref":"#/components/schemas/Citation"},"type":"array","title":"Citations","description":"This page, in citation order."},"next_cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Cursor","description":"Pass as `cursor` for the next page; null on the last page.","examples":[50]}},"type":"object","required":["result_id","datum","label","citation_count","citations","next_cursor"],"title":"CitationPage","description":"One page of every trial behind one data point."},"CitationsMeta":{"properties":{"requested":{"type":"string","enum":["sample","full"],"title":"Requested","description":"Citation mode asked for.","default":"sample"},"applied":{"type":"string","enum":["sample","full"],"title":"Applied","description":"Citation mode used.","default":"sample"},"per_datum":{"type":"integer","title":"Per Datum","description":"Maximum citations inlined per data point.","examples":[5]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Why `applied` differs from `requested`, or why a sample was all there was: e.g. the full-citation size limit was exceeded, or years were counted."}},"type":"object","required":["per_datum"],"title":"CitationsMeta","description":"How citations were inlined."},"CompareGroup":{"properties":{"label":{"type":"string","maxLength":100,"minLength":1,"title":"Label","description":"Name of the group, shown as the series in the chart. Unique per request.","examples":["Pembrolizumab"]},"drug_name":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Drug Name","description":"A string or a list of up to 10 strings, matched with OR within this group. Drug or intervention.","default":[],"examples":["pembrolizumab"]},"condition":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Condition","description":"A string or a list of up to 10 strings, matched with OR within this group. Condition or disease.","default":[],"examples":["melanoma"]},"sponsor":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Sponsor","description":"A string or a list of up to 10 strings, matched with OR within this group. Sponsor name.","default":[],"examples":["Merck Sharp & Dohme"]},"country":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Country","description":"A string or a list of up to 10 strings, matched with OR within this group. Country with a trial site.","default":[],"examples":["Germany"]}},"additionalProperties":false,"type":"object","required":["label"],"title":"CompareGroup","description":"One side of a comparison. Needs at least one of drug_name, condition, sponsor, country.","examples":[{"drug_name":"pembrolizumab","label":"Pembrolizumab"}]},"DimensionOption":{"properties":{"key":{"type":"string","title":"Key","description":"Dimension key.","examples":["phase"]},"label":{"type":"string","title":"Label","description":"Label to show.","examples":["Phase"]},"kind":{"type":"string","enum":["categorical","entity","time","numeric"],"title":"Kind","description":"`categorical` (fixed values), `entity` (open-ended names such as drugs), `time` (years) or `numeric` (per-trial numbers for histograms and scatter plots)."},"multi_valued":{"type":"boolean","title":"Multi Valued","description":"Whether a trial can have several values."},"counting_rule":{"type":"string","title":"Counting Rule","description":"How a trial is counted when grouped by it."},"values":{"anyOf":[{"items":{"$ref":"#/components/schemas/OptionValue"},"type":"array"},{"type":"null"}],"title":"Values","description":"Possible values for enum dimensions; null otherwise."}},"type":"object","required":["key","label","kind","multi_valued","counting_rule","values"],"title":"DimensionOption"},"ErrorBody":{"properties":{"code":{"type":"string","enum":["invalid_request","rejected_by_policy","unauthorized","not_found","method_not_allowed","expired","too_many_requests","upstream_unavailable","llm_unavailable","safety_check_unavailable","budget_exceeded","internal_error","cancelled"],"title":"Code","description":"Stable, machine-readable error code."},"message":{"type":"string","title":"Message","description":"Short message safe to show to a user.","examples":["ClinicalTrials.gov is not responding. Please retry later."]},"details":{"title":"Details","description":"`invalid_request`: one `{loc, msg}` per invalid field. Otherwise null.","examples":[null]},"trace_id":{"type":"string","title":"Trace Id","description":"Trace id; quote it when reporting a problem.","examples":["5b3f9a1e-2c4d-4e8f-9a7b-1c2d3e4f5a6b"]}},"type":"object","required":["code","message","details","trace_id"],"title":"ErrorBody","description":"A real error. Never contains stack traces, prompts, model output or keys."},"ErrorResponse":{"properties":{"error":{"$ref":"#/components/schemas/ErrorBody","description":"The error."}},"type":"object","required":["error"],"title":"ErrorResponse","description":"The one body every real error shares."},"Evidence":{"properties":{"field":{"type":"string","title":"Field","description":"Path in the ClinicalTrials.gov study record.","examples":["protocolSection.designModule.phases[0]"]},"excerpt":{"title":"Excerpt","description":"The value found there.","examples":["PHASE2"]}},"type":"object","required":["field","excerpt"],"title":"Evidence","description":"A field of the trial record that places the trial in the data point."},"Excluded":{"properties":{"reason":{"type":"string","title":"Reason","description":"Why they were left out.","examples":["no start date"]},"count":{"type":"integer","title":"Count","description":"How many trials.","examples":[5]}},"type":"object","required":["reason","count"],"title":"Excluded","description":"Trials left out of the chart for one reason."},"FilterOptions":{"properties":{"trial_phase":{"items":{"$ref":"#/components/schemas/OptionValue"},"type":"array","title":"Trial Phase","description":"Values for `trial_phase`."},"status":{"items":{"$ref":"#/components/schemas/OptionValue"},"type":"array","title":"Status","description":"Values for `status`."},"country":{"items":{"type":"string"},"type":"array","title":"Country","description":"Country names for `country`."}},"type":"object","required":["trial_phase","status","country"],"title":"FilterOptions"},"Health":{"properties":{"status":{"type":"string","enum":["ok","unavailable"],"title":"Status","description":"`ok` when the database is reachable, else `unavailable` (with 503)."},"checks":{"$ref":"#/components/schemas/HealthChecks","description":"Result of each check."},"data_timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data Timestamp","description":"ClinicalTrials.gov data version; null when it cannot be reached.","examples":["2026-10-23T09:00:04"]}},"type":"object","required":["status","checks","data_timestamp"],"title":"Health"},"HealthChecks":{"properties":{"database":{"type":"string","enum":["ok","error"],"title":"Database","description":"Postgres answers a query."},"ctgov":{"type":"string","enum":["ok","error"],"title":"Ctgov","description":"ClinicalTrials.gov answers its version endpoint. Reported only: it does not change `status`."}},"type":"object","required":["database","ctgov"],"title":"HealthChecks"},"Interpretation":{"properties":{"intent":{"type":"string","title":"Intent","description":"Kind of question: trend, distribution, top_n, comparison, geographic, network, numeric_distribution, numeric_relationship or single_number.","examples":["distribution"]},"chart_type":{"type":"string","title":"Chart Type","description":"The chart type used.","examples":["bar_chart"]},"dimension":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dimension","description":"What the data is grouped by (see `GET /v1/options`).","examples":["phase"]},"dimension_2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dimension 2","description":"Second dimension: the series of a grouped chart, or a network's second node type.","examples":[null]},"measure":{"type":"string","title":"Measure","description":"What is counted or summed.","examples":["trial_count"]},"chart_type_source":{"type":"string","enum":["ai","user","fallback","plan"],"title":"Chart Type Source","description":"Who chose the chart type: `ai`; `user` (the `chart_type` field); `fallback` (the AI's choice did not fit, so the intent's default was used); or `plan` (a hand-written plan on the debug endpoint).","default":"plan","examples":["ai"]}},"type":"object","required":["intent","chart_type","dimension","measure"],"title":"Interpretation","description":"How the question was read."},"JobAccepted":{"properties":{"job_id":{"type":"string","title":"Job Id","description":"Job id.","examples":["8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11"]},"status":{"type":"string","const":"pending","title":"Status","description":"Always `pending` when accepted."},"poll_url":{"type":"string","title":"Poll Url","description":"Where to poll, relative to the API root.","examples":["/v1/jobs/8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11"]},"estimated_seconds":{"type":"integer","title":"Estimated Seconds","description":"Rough estimate of the run time, from the number of pages to fetch.","examples":[240]}},"type":"object","required":["job_id","status","poll_url","estimated_seconds"],"title":"JobAccepted","description":"A broad question is running as a background job (202)."},"JobProgress":{"properties":{"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage","description":"Current stage.","examples":["retrieve"]},"pages_done":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pages Done","description":"ClinicalTrials.gov pages fetched.","examples":[12]},"pages_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pages Total","description":"Pages to fetch in total.","examples":[34]}},"type":"object","title":"JobProgress","description":"Retrieval progress; empty until the job starts fetching."},"JobStatus":{"properties":{"job_id":{"type":"string","title":"Job Id","description":"Job id.","examples":["8c1f6c52-4a8e-4d3b-9a51-0f2e7b6d9c11"]},"status":{"type":"string","enum":["pending","running","succeeded","failed","cancelled"],"title":"Status","description":"`pending` (queued, or waiting for a retry), `running`, `succeeded` (see `result`), `failed` (see `error`) or `cancelled` (by `DELETE`; `error.code` is `cancelled`)."},"progress":{"$ref":"#/components/schemas/JobProgress","description":"Retrieval progress."},"estimated_seconds":{"type":"integer","title":"Estimated Seconds","description":"Estimate given when accepted.","examples":[240]},"result":{"anyOf":[{"$ref":"#/components/schemas/QueryResponse"},{"type":"null"}],"description":"The normal `POST /v1/query` response once `succeeded`; otherwise null."},"error":{"anyOf":[{"$ref":"#/components/schemas/ErrorBody"},{"type":"null"}],"description":"The error once `failed` (same body as a synchronous error) or `cancelled` (code `cancelled`); otherwise null."}},"type":"object","required":["job_id","status","progress","estimated_seconds","result","error"],"title":"JobStatus","description":"A background job and, once it has finished, its result or error."},"MeasureOption":{"properties":{"key":{"type":"string","title":"Key","description":"Measure key.","examples":["trial_count"]},"label":{"type":"string","title":"Label","description":"Label to show.","examples":["Number of trials"]},"unit":{"type":"string","title":"Unit","description":"Unit.","examples":["trials"]}},"type":"object","required":["key","label","unit"],"title":"MeasureOption"},"Meta":{"properties":{"interpretation":{"anyOf":[{"$ref":"#/components/schemas/Interpretation"},{"type":"null"}],"description":"How the question was read; null when there is no chart."},"filters":{"additionalProperties":true,"type":"object","title":"Filters","description":"Filters applied, after merging the request fields into the AI's plan (e.g. `drugs`, `conditions`, `phases`, `start_year_min`, `groups`). Terms are shown as cleaned.","default":{},"examples":[{"conditions":["breast cancer"]}]},"assumptions":{"items":{"type":"string"},"type":"array","title":"Assumptions","description":"How ambiguous parts of the question were read.","default":[],"examples":[["Interpreting 'breast cancer trials' as trials with condition 'breast cancer'."]]},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings","description":"Things to know, e.g. a request field overriding the question, or a chart type replaced by a better fit.","default":[]},"notes":{"items":{"type":"string"},"type":"array","title":"Notes","description":"Facts about the chart, e.g. `Showing the top 10 of 84 countries.`","default":[]},"counting_rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Counting Rule","description":"How a trial is counted in the chart.","examples":["Each trial is counted once; trials with two phases get a combined bucket (e.g. Phase 2/Phase 3)."]},"additive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Additive","description":"Whether the values add up to `unique_trials`. False when a trial can count in several categories (e.g. countries, split phases).","examples":[true]},"unique_trials":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Unique Trials","description":"Distinct trials behind the chart.","examples":[16765]},"excluded":{"items":{"$ref":"#/components/schemas/Excluded"},"type":"array","title":"Excluded","description":"Trials left out of the chart, by reason.","default":[]},"sort":{"anyOf":[{"$ref":"#/components/schemas/Sort"},{"type":"null"}],"description":"How the categories are ordered."},"api_queries":{"items":{"$ref":"#/components/schemas/ApiQuery"},"type":"array","title":"Api Queries","description":"Every ClinicalTrials.gov search behind the numbers.","default":[]},"group_overlap":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Group Overlap","description":"Comparisons only: trials shared by each pair of groups.","examples":[[{"groups":["pembrolizumab","nivolumab"],"trials":174}]]},"network":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Network","description":"Networks only: node and edge counts before and after pruning, the thresholds and the community algorithm."},"citations":{"anyOf":[{"$ref":"#/components/schemas/CitationsMeta"},{"type":"null"}],"description":"How citations were inlined."},"data_timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data Timestamp","description":"ClinicalTrials.gov data version the answer was computed from.","examples":["2026-10-23T09:00:04"]},"retrieved_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retrieved At","description":"When the trials were fetched.","examples":["2026-10-24T12:07:55+00:00"]},"source":{"type":"string","title":"Source","description":"Data source.","default":"clinicaltrials.gov"},"guard":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Guard","description":"Input guard verdict and model. `cached: true` (model null) when the daily AI budget is spent and an exact repeat of an already-guarded request was answered from cache without calling the guard.","examples":[{"model":"gpt-5.4-nano","verdict":"ok"}]},"planner":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Planner","description":"Planning agent trace: steps, tool calls and model."},"narration":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Narration","description":"Title narrator: model, attempts, and `fallback: true` when the template title was used."},"usage":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Usage","description":"AI calls, tokens and cost in USD for this answer.","examples":[{"cost_usd":0.00198,"input_tokens":3878,"llm_calls":5,"models":["gpt-5.4-mini","gpt-5.4-nano"],"output_tokens":422}]},"cache":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Cache","description":"Whether the plan (`hit`, `miss`) and the result (`hit`, `revalidated`, `miss`) came from cache.","examples":[{"plan":"miss","result":"miss"}]},"trace_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trace Id","description":"Trace id of the request; quote it when reporting a problem.","examples":["f99e189b-ed92-498b-909d-51252c63d1cd"]},"timings_ms":{"additionalProperties":{"type":"integer"},"type":"object","title":"Timings Ms","description":"Time per stage in milliseconds: `plan` (guard and planner, side by side), `count` (ClinicalTrials.gov counts), `retrieve`, `aggregate`, `narrate`, and `total` from the request's arrival. For a background job, `total` is the planning time plus the job's own run, leaving out its wait in the queue. A reused answer keeps the timings of the run that computed it.","default":{},"examples":[{"aggregate":326,"count":610,"narrate":2523,"plan":2840,"retrieve":25949,"total":32260}]},"details":{"additionalProperties":true,"type":"object","title":"Details","description":"Status-specific details. `no_matching_trials`: `search_counts` per group. `out_of_scope`: `reason` and an optional `suggestion`. `could_not_interpret`: the validation `errors` and the planner's `best_attempt`.","default":{}}},"additionalProperties":false,"type":"object","title":"Meta","description":"Everything needed to trust and reproduce the answer."},"OptionValue":{"properties":{"value":{"type":"string","title":"Value","description":"Code to send.","examples":["PHASE3"]},"label":{"type":"string","title":"Label","description":"Label to show.","examples":["Phase 3"]}},"type":"object","required":["value","label"],"title":"OptionValue"},"Options":{"properties":{"dimensions":{"items":{"$ref":"#/components/schemas/DimensionOption"},"type":"array","title":"Dimensions","description":"What data can be grouped by."},"measures":{"items":{"$ref":"#/components/schemas/MeasureOption"},"type":"array","title":"Measures","description":"What can be counted or summed."},"chart_types":{"items":{"$ref":"#/components/schemas/ChartTypeOption"},"type":"array","title":"Chart Types","description":"Chart types."},"filters":{"$ref":"#/components/schemas/FilterOptions","description":"Values accepted by the filter fields."}},"type":"object","required":["dimensions","measures","chart_types","filters"],"title":"Options","description":"The registry, for building pickers."},"Phase":{"type":"string","enum":["NA","EARLY_PHASE1","PHASE1","PHASE2","PHASE3","PHASE4"],"title":"Phase"},"QueryRequest":{"properties":{"query":{"type":"string","maxLength":1000,"minLength":1,"title":"Query","description":"The question in plain language, 1-1,000 characters after trimming. May refer to the fields, e.g. 'this drug'.","examples":["How are breast cancer trials distributed across phases?"]},"drug_name":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Drug Name","description":"Drug or intervention name(s). A string or a list of up to 10 strings (1-200 characters each), matched with OR. Authoritative: it overrides what the AI reads in the question, and a conflict is reported in `meta.warnings`.","default":[],"examples":["Pembrolizumab",["pembrolizumab","nivolumab"]]},"condition":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Condition","description":"Condition or disease name(s). A string or a list of up to 10 strings (1-200 characters each), matched with OR. Authoritative: it overrides what the AI reads in the question, and a conflict is reported in `meta.warnings`.","default":[],"examples":["breast cancer"]},"sponsor":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Sponsor","description":"Sponsor name(s); see `sponsor_role`. A string or a list of up to 10 strings (1-200 characters each), matched with OR. Authoritative: it overrides what the AI reads in the question, and a conflict is reported in `meta.warnings`.","default":[],"examples":["Merck Sharp & Dohme LLC"]},"country":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Country","description":"Country name(s): trials with at least one site there. A string or a list of up to 10 strings (1-200 characters each), matched with OR. Authoritative: it overrides what the AI reads in the question, and a conflict is reported in `meta.warnings`. `GET /v1/options` lists the country names.","default":[],"examples":["United States"]},"trial_phase":{"items":{"$ref":"#/components/schemas/Phase"},"type":"array","title":"Trial Phase","description":"Only trials in any of these phases. Codes (`PHASE3`) or labels (`Phase 3`), ignoring case and punctuation. Overrides the question.","default":[],"examples":[["PHASE2","Phase 3"]]},"status":{"items":{"$ref":"#/components/schemas/Status"},"type":"array","title":"Status","description":"Only trials with any of these overall statuses. Codes (`RECRUITING`) or labels (`Recruiting`). Overrides the question.","default":[],"examples":[["RECRUITING"]]},"start_year":{"anyOf":[{"type":"integer","minimum":1900.0},{"type":"null"}],"title":"Start Year","description":"Only trials that started in or after this year (1900 to 10 years from now). Overrides the question.","examples":[2015]},"end_year":{"anyOf":[{"type":"integer","minimum":1900.0},{"type":"null"}],"title":"End Year","description":"Only trials that started in or before this year. Must not be before `start_year`. Overrides the question.","examples":[2024]},"compare":{"items":{"$ref":"#/components/schemas/CompareGroup"},"type":"array","title":"Compare","description":"2-4 groups to compare side by side (unique labels). Each group is searched separately; overlapping trials are reported in `meta.group_overlap`.","default":[],"examples":[[{"drug_name":"pembrolizumab","label":"Pembrolizumab"},{"drug_name":"nivolumab","label":"Nivolumab"}]]},"chart_type":{"anyOf":[{"$ref":"#/components/schemas/ChartType"},{"type":"null"}],"description":"Force a chart type instead of the AI's choice (`meta.interpretation.chart_type_source` is then `user`). If it cannot show the question, the answer is `could_not_interpret` with the reason in `meta.details`.","examples":["bar_chart"]},"top_n":{"anyOf":[{"type":"integer","maximum":50.0,"minimum":1.0},{"type":"null"}],"title":"Top N","description":"Keep the N largest categories of a ranked chart, or the N nodes with the most trials per node type in a network. Overrides the AI; `meta.notes` says when categories were cut.","examples":[10]},"match_mode":{"type":"string","enum":["strict","broad"],"title":"Match Mode","description":"Drug and condition matching. `strict`: a drug must match an intervention name and a condition matches as an exact phrase. `broad`: ClinicalTrials.gov's wider intervention search, and a condition's words may match separately.","default":"strict"},"sponsor_role":{"type":"string","enum":["lead","any"],"title":"Sponsor Role","description":"`lead`: the sponsor is the lead sponsor. `any`: lead sponsor or collaborator.","default":"lead"},"citations":{"type":"string","enum":["sample","full"],"title":"Citations","description":"`sample`: up to `citations_per_datum` citations inline per data point. `full`: every citation inline, unless the response would carry more than 2,000 (setting `CITATIONS_FULL_MAX`); it then falls back to a sample and `meta.citations` says why. The full list for any data point always comes from `GET /v1/results/{result_id}/citations`.","default":"sample"},"citations_per_datum":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Citations Per Datum","description":"Maximum citations inlined per data point (bar, bucket, node, edge). `citation_count` always gives the full number; `citations_truncated` says whether more exist.","default":5,"examples":[3]},"phase_mode":{"type":"string","enum":["combined","split"],"title":"Phase Mode","description":"Trials with two phases. `combined`: one bucket such as `PHASE2/PHASE3`. `split`: counted once in each phase (the chart is then not additive).","default":"combined"},"condition_source":{"type":"string","enum":["mesh","raw"],"title":"Condition Source","description":"Condition names for charts by condition. `mesh`: normalised MeSH terms. `raw`: the names as the sponsor entered them.","default":"mesh"},"include_unknown":{"type":"boolean","title":"Include Unknown","description":"Show a 'Not reported' bucket for trials missing the charted value. When false, they are excluded and counted in `meta.excluded`.","default":true},"edge_metric":{"type":"string","enum":["count","jaccard"],"title":"Edge Metric","description":"Network graphs only. Edge weight: `count` (shared trials) or `jaccard` (shared trials / trials with either).","default":"count"},"hide_query_entity":{"type":"boolean","title":"Hide Query Entity","description":"Network graphs only. Hide the node for the entity the question is about (e.g. melanoma in a melanoma drug network), since it links to everything.","default":false}},"additionalProperties":false,"type":"object","required":["query"],"title":"QueryRequest","description":"A question plus optional structured fields. Unknown fields are rejected (422)."},"QueryResponse":{"properties":{"schema_version":{"type":"string","title":"Schema Version","description":"Response schema version; changes when the shape changes in a way that can break a client.","default":"2.0","examples":["2.0"]},"result_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result Id","description":"Id of the stored result, for the citations endpoint. Null for `out_of_scope` and `could_not_interpret`, or when the deployment has no database.","examples":["d70db059-8f32-49a2-9fdc-231f5e3fd056"]},"status":{"type":"string","enum":["ok","no_matching_trials","out_of_scope","could_not_interpret"],"title":"Status","description":"`ok`: `visualization` has the chart. `no_matching_trials`, `out_of_scope`, `could_not_interpret`: `visualization` is null and `meta.details` says why.","examples":["ok"]},"visualization":{"anyOf":[{"$ref":"#/components/schemas/Visualization"},{"type":"null"}],"description":"The chart; null when `status` is not `ok`."},"meta":{"$ref":"#/components/schemas/Meta","description":"Interpretation, filters, counting rules and provenance."}},"type":"object","required":["status","visualization","meta"],"title":"QueryResponse","description":"The answer to a question: a chart specification, or why there is none."},"Sort":{"properties":{"by":{"type":"string","enum":["x","y"],"title":"By","description":"By the category (`x`) or the value (`y`)."},"order":{"type":"string","enum":["asc","desc","natural"],"title":"Order","description":"Direction; `natural` is the domain order."}},"type":"object","required":["by","order"],"title":"Sort","description":"How the categories are ordered."},"Status":{"type":"string","enum":["ACTIVE_NOT_RECRUITING","COMPLETED","ENROLLING_BY_INVITATION","NOT_YET_RECRUITING","RECRUITING","SUSPENDED","TERMINATED","WITHDRAWN","AVAILABLE","NO_LONGER_AVAILABLE","TEMPORARILY_NOT_AVAILABLE","APPROVED_FOR_MARKETING","WITHHELD","UNKNOWN"],"title":"Status"},"UsageSummary":{"properties":{"day":{"type":"string","title":"Day","description":"The UTC day.","examples":["2026-10-24"]},"calls":{"type":"integer","title":"Calls","description":"AI calls today.","examples":[412]},"cost_usd":{"type":"number","title":"Cost Usd","description":"Cost today in USD.","examples":[0.731]},"unknown_cost_calls":{"type":"integer","title":"Unknown Cost Calls","description":"Calls whose model has no price.","examples":[0]},"fallback_calls":{"type":"integer","title":"Fallback Calls","description":"Calls answered by a fallback model.","examples":[3]},"by_model":{"additionalProperties":{"additionalProperties":{"type":"number"},"type":"object"},"type":"object","title":"By Model","description":"Calls and cost per model.","examples":[{"gpt-5.4-nano":{"calls":260,"cost_usd":0.104}}]},"budget_usd":{"type":"number","title":"Budget Usd","description":"Daily budget; at it, questions that need a model call get 503 `budget_exceeded` (cached answers are still served).","examples":[100.0]}},"type":"object","required":["day","calls","cost_usd","unknown_cost_calls","fallback_calls","by_model","budget_usd"],"title":"UsageSummary","description":"Today's AI calls and cost (UTC day)."},"Visualization":{"properties":{"type":{"$ref":"#/components/schemas/ChartType","description":"Chart type.","examples":["bar_chart"]},"title":{"type":"string","title":"Title","description":"Chart title, written by the AI narrator and checked against the data (a template title when the check fails).","examples":["ClinicalTrials.gov breast cancer trials by phase"]},"encoding":{"additionalProperties":{"$ref":"#/components/schemas/Channel"},"type":"object","title":"Encoding","description":"Visual channel name -> data key: every key a renderer needs is named here. Channels: `x`, `y` and an optional `color` for bar, grouped bar, time series, histogram and scatter charts; `value` for a metric; `node_id`, `node_label`, `node_size`, `node_color`, `edge_source`, `edge_target` and `edge_width` for a network.","examples":[{"x":{"field":"phase","label":"Phase","sort":"natural","type":"ordinal"},"y":{"field":"trial_count","label":"Number of trials","type":"quantitative","unit":"trials"}}]},"data":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"additionalProperties":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"type":"object"}],"title":"Data","description":"Flat records whose keys are named in `encoding`; a network has `{nodes: [...], edges: [...]}` instead. Every record, node and edge also has a stable `key` (for the citations endpoint), `citation_count` (all contributing trials), `citations` (up to `citations_per_datum` of them, each with `nct_id`, `url`, `title` and `evidence`: the record fields that place the trial in this data point) and `citations_truncated` (more exist than are inlined). Time series records also have `estimated_count`: trials placed by an estimated, not actual, date.","examples":[[{"citation_count":3546,"citations":[{"evidence":[{"excerpt":"PHASE2","field":"protocolSection.designModule.phases[0]"}],"nct_id":"NCT07729046","title":"Neu Direction: Testing the Efficacy of Adding HER Inhibition to Standard of Care in Metastatic MLH1-low Endocrine-resistant ER+/HER2- Breast Cancer","url":"https://clinicaltrials.gov/study/NCT07729046"}],"citations_truncated":true,"key":"PHASE2","phase":"Phase 2","trial_count":3546}]]}},"type":"object","required":["type","title","encoding","data"],"title":"Visualization","description":"The chart: its type, title, channel encoding and data records."}}},"tags":[{"name":"query","description":"Ask a question: get a chart specification with citations, or a background job for a broad question."},{"name":"jobs","description":"Poll or cancel the background job started by a broad question (202)."},{"name":"citations","description":"Every trial behind one data point of a stored result, paginated. Inline citations are a sample unless `citations: \"full\"` was asked."},{"name":"options","description":"The registry: dimensions, measures, chart types and filter values with labels, for building pickers."},{"name":"health","description":"Liveness and readiness, used by the container probes."},{"name":"admin","description":"Operator endpoints. Need the admin bearer token."},{"name":"debug","description":"Run a hand-written QueryPlan without the AI stages. Disabled in production (`ENABLE_DEBUG_ENDPOINTS=false`)."}]}