{"openapi":"3.1.0","info":{"title":"cito","summary":"Self-hosted semantic + keyword search over ~148M academic papers.","description":"**Cito** is a self-hosted semantic + keyword search API over ~148M academic papers\n(Semantic Scholar), built to escape the 1-request-per-second public API limit.\n\n- **Semantic** retrieval uses SPECTER2 embeddings (asymmetric query/document encoders)\n  over a Qdrant vector index.\n- **Keyword** retrieval is BM25 (tantivy) over title + abstract.\n- **Hybrid** (the default) fuses both legs with Reciprocal Rank Fusion; the response's\n  `fused` flag reports whether the BM25 leg contributed or the query degraded to\n  dense-only.\n- Results carry Semantic Scholar CorpusIDs and are enriched with title/abstract/authors.\n\nAuth is by API key when enabled (`Authorization: Bearer sk_…` or `X-API-Key: sk_…`).\nAccount endpoints under `/me` always require a key.\n\nAn MCP endpoint lives at `/mcp` (streamable HTTP) for agent clients such as Claude\nCode — anonymous use shares the per-IP limit; pass the same `Authorization` header\nfor the per-key tier.\n","contact":{"name":"FIM","url":"https://fim.ai/"},"version":"0.1.0"},"paths":{"/me":{"get":{"tags":["account"],"summary":"Your account and API keys","description":"Return the authenticated user with all of their API keys (prefixes only —\nraw keys are never recoverable). The key used for this request is flagged.","operationId":"me_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/me/usage":{"get":{"tags":["account"],"summary":"Your recent usage","description":"Aggregate request counts (total, last 24h, average latency) across all of the\nuser's searches — API-key and logged-in website alike — plus the recent requests.","operationId":"usage_me_usage_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"How many recent requests to return","default":20,"title":"Limit"},"description":"How many recent requests to return"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["meta"],"summary":"Liveness probe","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/":{"get":{"tags":["meta"],"summary":"Service info","operationId":"index__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceInfo"}}}}}}},"/status":{"get":{"tags":["meta"],"summary":"Index & feature status","description":"Readiness/info: whether Qdrant is reachable, the collection's index counts\n(so a client can show 'index building'), and which features are enabled.","operationId":"status__status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}}}}},"/stats":{"get":{"tags":["meta"],"summary":"Corpus statistics","description":"Newest per-release corpus statistics. 404 until the first post-sync stats\nrun has landed; 503 when Postgres is unreachable (search still works).","operationId":"stats_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}}}}},"/paper":{"get":{"tags":["search"],"summary":"Fetch one paper by CorpusID, DOI, or arXiv id","description":"Resolve one paper by an exact identifier. Direct DOI/arXiv lookup is precise\n(no fuzzy title matching) and reads the local metadata store only — one indexed\nSQLite lookup, no network. Exactly one of `corpusid`/`doi`/`arxiv` must be given.","operationId":"paper_by_identifier_paper_get","parameters":[{"name":"corpusid","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Semantic Scholar CorpusID (same as /paper/{corpusid}).","title":"Corpusid"},"description":"Semantic Scholar CorpusID (same as /paper/{corpusid})."},{"name":"doi","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"DOI, e.g. `10.18653/v1/2020.emnlp-main.550` (case-insensitive, exact). Resolved via meta.db's reverse index — no fuzzy matching.","title":"Doi"},"description":"DOI, e.g. `10.18653/v1/2020.emnlp-main.550` (case-insensitive, exact). Resolved via meta.db's reverse index — no fuzzy matching."},{"name":"arxiv","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"arXiv id, e.g. `2104.08821` or `hep-th/9901001` (case-insensitive, exact). Needs a v2 meta.db with the arxiv column and its reverse index.","title":"Arxiv"},"description":"arXiv id, e.g. `2104.08821` or `hep-th/9901001` (case-insensitive, exact). Needs a v2 meta.db with the arxiv column and its reverse index."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Paper"}}}},"404":{"description":"No paper matched the given identifier."},"422":{"description":"Not exactly one of corpusid / doi / arxiv was given."},"501":{"description":"DOI/arXiv reverse lookup unsupported on this deployment."}}}},"/paper/{corpusid}":{"get":{"tags":["search"],"summary":"Fetch one paper's metadata","description":"Resolve a single Semantic Scholar CorpusID to its metadata (title, abstract,\nauthors, links). Independent of the search index: it reads the local metadata\nstore directly, so a detail page costs one SQLite lookup and no network call.","operationId":"paper_paper__corpusid__get","parameters":[{"name":"corpusid","in":"path","required":true,"schema":{"type":"string","title":"Corpusid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Paper"}}}},"404":{"description":"No metadata found for this CorpusID."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/search":{"get":{"tags":["search"],"summary":"Search papers","operationId":"search_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"Search query (natural language or keywords). Required unless `author` is given.","title":"Q"},"description":"Search query (natural language or keywords). Required unless `author` is given."},{"name":"author","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"Author name filter, e.g. `Geoffrey Hinton` or `G. Hinton`. Routed to the BM25 authors field and enforced against hydrated metadata, so initials disambiguate (`G. Hinton` only matches Hintons whose given name starts with G). Alone it lists a person's papers; with `q` it restricts the topic search to that author.","title":"Author"},"description":"Author name filter, e.g. `Geoffrey Hinton` or `G. Hinton`. Routed to the BM25 authors field and enforced against hydrated metadata, so initials disambiguate (`G. Hinton` only matches Hintons whose given name starts with G). Alone it lists a person's papers; with `q` it restricts the topic search to that author."},{"name":"mode","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Mode","description":"Retrieval mode: `hybrid` (RRF fusion of dense + BM25, the default), `semantic` (SPECTER2 dense only), or `keyword` (BM25 only).","default":"hybrid"},"description":"Retrieval mode: `hybrid` (RRF fusion of dense + BM25, the default), `semantic` (SPECTER2 dense only), or `keyword` (BM25 only)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Max results to return.","default":20,"title":"Limit"},"description":"Max results to return."},{"name":"enrich","in":"query","required":false,"schema":{"type":"boolean","description":"Attach title/abstract/authors from the local metadata store.","default":true,"title":"Enrich"},"description":"Attach title/abstract/authors from the local metadata store."},{"name":"published_before","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Leak-safe date gate (YYYY-MM-DD): only papers published strictly before this date. Filtering happens before the pool is cut to `limit`, so `limit` valid results come back when the corpus has them. Papers with only a year are kept iff the year is strictly earlier; same-year and undated papers are excluded unless `include_imprecise`.","title":"Published Before"},"description":"Leak-safe date gate (YYYY-MM-DD): only papers published strictly before this date. Filtering happens before the pool is cut to `limit`, so `limit` valid results come back when the corpus has them. Papers with only a year are kept iff the year is strictly earlier; same-year and undated papers are excluded unless `include_imprecise`."},{"name":"published_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Date gate (YYYY-MM-DD): only papers published on or after this date. Combine with `published_before` for a half-open window [after, before). A year-only paper clears a Jan-1 bound outright (its earliest possible day is Jan 1); a bound inside its year is undecidable, so it is excluded unless `include_imprecise`, as are undated papers.","title":"Published After"},"description":"Date gate (YYYY-MM-DD): only papers published on or after this date. Combine with `published_before` for a half-open window [after, before). A year-only paper clears a Jan-1 bound outright (its earliest possible day is Jan 1); a bound inside its year is undecidable, so it is excluded unless `include_imprecise`, as are undated papers."},{"name":"include_imprecise","in":"query","required":false,"schema":{"type":"boolean","description":"With `published_before`/`published_after`: also keep papers whose date is too coarse to place against the bound (year-granularity papers whose year straddles it, or papers with no date at all).","default":false,"title":"Include Imprecise"},"description":"With `published_before`/`published_after`: also keep papers whose date is too coarse to place against the bound (year-granularity papers whose year straddles it, or papers with no date at all)."},{"name":"expand","in":"query","required":false,"schema":{"type":"boolean","description":"Cross-domain query expansion: an LLM rewrites `q` into the terms-of-art adjacent fields use for the same concept, every variant is retrieved, and the result lists are RRF-fused. Finds prior work that phrases the idea differently. Adds one LLM call (~1–2 s) plus one retrieval per variant; the variants used are echoed in the response's `expansion` field. Needs the expansion LLM configured server-side — otherwise the search silently runs unexpanded.","default":false,"title":"Expand"},"description":"Cross-domain query expansion: an LLM rewrites `q` into the terms-of-art adjacent fields use for the same concept, every variant is retrieved, and the result lists are RRF-fused. Finds prior work that phrases the idea differently. Adds one LLM call (~1–2 s) plus one retrieval per variant; the variants used are echoed in the response's `expansion` field. Needs the expansion LLM configured server-side — otherwise the search silently runs unexpanded."},{"name":"rerank","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Override the cross-encoder rerank stage for this request. `false` skips it — retrieval-order results, no per-query model pass, lower latency; use for existence/lookup checks that don't need precision reordering. Omitted (the default) or `true` keeps the server default; `true` cannot force reranking on where the server has no reranker configured.","title":"Rerank"},"description":"Override the cross-encoder rerank stage for this request. `false` skips it — retrieval-order results, no per-query model pass, lower latency; use for existence/lookup checks that don't need precision reordering. Omitted (the default) or `true` keeps the server default; `true` cannot force reranking on where the server has no reranker configured."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"X-Service-Token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}},{"name":"X-Client-Subject","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Client-Subject"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"401":{"description":"Missing or invalid API key (when auth is enabled)."},"422":{"description":"Malformed `published_before`/`published_after` (must be YYYY-MM-DD), or an inverted window (`after` >= `before`)."},"429":{"description":"Rate limit exceeded for this caller tier."},"503":{"description":"Search backend (index/encoder) temporarily unavailable."}}}},"/paper/batch":{"post":{"tags":["search"],"summary":"Resolve many papers in one call","description":"Bulk sibling of `/paper`: resolve up to MAX_BATCH_IDS papers by CorpusID,\nDOI, and/or arXiv id in one request. Built for reference-matching / verify\nworkloads that would otherwise be tens of thousands of round trips. Results are\nkeyed by the identifier asked with; misses are absent, not errors.","operationId":"paper_batch_paper_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaperBatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaperBatchResponse"}}}},"422":{"description":"Empty request, or more than MAX_BATCH_IDS ids."},"501":{"description":"DOI/arXiv reverse lookup unsupported on this deployment."}}}},"/search/batch":{"post":{"tags":["search"],"summary":"Run several searches in one call","description":"Run several independent searches over one HTTP request, cutting the round\ntrips a large sweep would otherwise make. Each query is the same as a `/search`\ncall — same parameters, same metering (one rate-limit token and one usage-log\nrow per query) — so a batch of N spends N tokens. Fail-fast: a query that would\n422/429 on its own aborts the batch with that status.","operationId":"search_batch_search_batch_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"X-Service-Token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}},{"name":"X-Client-Subject","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Client-Subject"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchBatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchBatchResponse"}}}},"401":{"description":"Missing or invalid API key (when auth is enabled)."},"422":{"description":"Empty query list, more than MAX_BATCH_QUERIES, or a bad query."},"429":{"description":"Rate limit exceeded (a batch spends one token per query)."}}}}},"components":{"schemas":{"Account":{"properties":{"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"keys":{"items":{"$ref":"#/components/schemas/KeyInfo"},"type":"array","title":"Keys"}},"type":"object","required":["email","created_at","keys"],"title":"Account"},"AuthorHint":{"properties":{"author":{"type":"string","title":"Author"},"q":{"type":"string","title":"Q"}},"type":"object","required":["author","q"],"title":"AuthorHint","description":"Non-binding query-understanding suggestion: `query` looked like topic words\nplus a person name (\"capsule networks hinton\"). `author`/`q` is the proposed\nsplit for re-running with the author filter. Never applied silently -- the\nresults in the same response are still for the query as typed."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"HealthResponse"},"Hit":{"properties":{"id":{"type":"string","title":"Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"abstract":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abstract"},"authors":{"items":{"type":"string"},"type":"array","title":"Authors","default":[]},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"publication_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Publication Date"},"date_granularity":{"anyOf":[{"type":"string","enum":["day","year"]},{"type":"null"}],"title":"Date Granularity"},"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"},"arxiv_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Arxiv Id"},"external_ids":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"External Ids"},"url":{"type":"string","title":"Url"},"pdf_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdf Url"},"cites":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cites"},"influential_cites":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Influential Cites"},"references":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"References"},"is_open_access":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Open Access"},"fields_of_study":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Fields Of Study"},"publication_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Publication Types"},"journal":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Journal"},"fwci":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fwci"},"citation_percentile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Citation Percentile"},"topic":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Topic"},"keywords":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Keywords"},"oa_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oa Status"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"work_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Work Type"},"retracted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Retracted"},"institutions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Institutions"},"countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Countries"},"funders":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Funders"},"score":{"type":"number","title":"Score"}},"type":"object","required":["id","url","score"],"title":"Hit"},"IndexStatus":{"properties":{"qdrant_ok":{"type":"boolean","title":"Qdrant Ok"},"collection":{"type":"string","title":"Collection"},"collection_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Collection Status"},"points_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Points Count"},"indexed_vectors_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Indexed Vectors Count"},"ready":{"type":"boolean","title":"Ready"}},"type":"object","required":["qdrant_ok","collection","ready"],"title":"IndexStatus"},"KeyInfo":{"properties":{"prefix":{"type":"string","title":"Prefix"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"rate_limit_per_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Limit Per Min"},"effective_rate_limit_per_min":{"type":"integer","title":"Effective Rate Limit Per Min","default":0},"revoked":{"type":"boolean","title":"Revoked"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"current":{"type":"boolean","title":"Current","default":false}},"type":"object","required":["prefix","revoked","created_at"],"title":"KeyInfo"},"Mode":{"type":"string","enum":["hybrid","keyword","semantic"],"title":"Mode"},"Paper":{"properties":{"id":{"type":"string","title":"Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"abstract":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abstract"},"authors":{"items":{"type":"string"},"type":"array","title":"Authors","default":[]},"author_ids":{"anyOf":[{"items":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"array"},{"type":"null"}],"title":"Author Ids"},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"publication_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Publication Date"},"date_granularity":{"anyOf":[{"type":"string","enum":["day","year"]},{"type":"null"}],"title":"Date Granularity"},"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"},"arxiv_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Arxiv Id"},"external_ids":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"External Ids"},"url":{"type":"string","title":"Url"},"pdf_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdf Url"},"cites":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cites"},"influential_cites":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Influential Cites"},"references":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"References"},"is_open_access":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Open Access"},"fields_of_study":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Fields Of Study"},"publication_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Publication Types"},"journal":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Journal"},"fwci":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fwci"},"citation_percentile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Citation Percentile"},"topic":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Topic"},"keywords":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Keywords"},"oa_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oa Status"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"work_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Work Type"},"retracted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Retracted"},"institutions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Institutions"},"countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Countries"},"funders":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Funders"},"attribution":{"type":"string","title":"Attribution","default":"Data from Semantic Scholar"}},"type":"object","required":["id","url"],"title":"Paper","description":"A single paper's metadata (no search score). Powers detail pages.\nField semantics match Hit exactly."},"PaperBatchRequest":{"properties":{"corpus_ids":{"items":{"type":"string"},"type":"array","title":"Corpus Ids","default":[]},"dois":{"items":{"type":"string"},"type":"array","title":"Dois","default":[]},"arxiv_ids":{"items":{"type":"string"},"type":"array","title":"Arxiv Ids","default":[]}},"type":"object","title":"PaperBatchRequest","description":"Resolve many papers in one call. Any mix of the three id kinds; the totals\nacross all three lists are capped at MAX_BATCH_IDS. DOIs and arXiv ids are\nreverse-resolved (case-insensitive) via meta.db's indexes — a 501 comes back\nwhen the deployment's meta.db lacks them."},"PaperBatchResponse":{"properties":{"by_corpusid":{"additionalProperties":{"$ref":"#/components/schemas/Paper"},"type":"object","title":"By Corpusid","default":{}},"by_doi":{"additionalProperties":{"$ref":"#/components/schemas/Paper"},"type":"object","title":"By Doi","default":{}},"by_arxiv":{"additionalProperties":{"$ref":"#/components/schemas/Paper"},"type":"object","title":"By Arxiv","default":{}},"attribution":{"type":"string","title":"Attribution","default":"Data from Semantic Scholar"}},"type":"object","title":"PaperBatchResponse","description":"Papers keyed by the identifier the caller asked with, so a batch can be\naligned back to its request. Ids that matched no row are simply absent from\ntheir map (never an error), the same contract as single-paper hydration."},"SearchBatchRequest":{"properties":{"queries":{"items":{"$ref":"#/components/schemas/SearchQuery"},"type":"array","title":"Queries"}},"type":"object","required":["queries"],"title":"SearchBatchRequest"},"SearchBatchResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/SearchResponse"},"type":"array","title":"Results"}},"type":"object","required":["results"],"title":"SearchBatchResponse"},"SearchQuery":{"properties":{"q":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"},"author":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author"},"mode":{"$ref":"#/components/schemas/Mode","default":"hybrid"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","default":20},"enrich":{"type":"boolean","title":"Enrich","default":true},"published_before":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published Before"},"published_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published After"},"include_imprecise":{"type":"boolean","title":"Include Imprecise","default":false},"expand":{"type":"boolean","title":"Expand","default":false},"rerank":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Rerank"}},"type":"object","title":"SearchQuery","description":"One query in a /search/batch request. Fields mirror the /search query\nparameters (same defaults and semantics); each item is run as its own search."},"SearchResponse":{"properties":{"query":{"type":"string","title":"Query"},"author":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author"},"mode":{"$ref":"#/components/schemas/Mode"},"took_ms":{"type":"integer","title":"Took Ms"},"fused":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Fused"},"author_hint":{"anyOf":[{"$ref":"#/components/schemas/AuthorHint"},{"type":"null"}]},"expansion":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Expansion"},"truncated":{"type":"boolean","title":"Truncated","default":false},"hits":{"items":{"$ref":"#/components/schemas/Hit"},"type":"array","title":"Hits"},"corpus_release":{"type":"string","title":"Corpus Release"},"attribution":{"type":"string","title":"Attribution","default":"Data from Semantic Scholar"}},"type":"object","required":["query","mode","took_ms","hits","corpus_release"],"title":"SearchResponse"},"ServiceInfo":{"properties":{"service":{"type":"string","title":"Service"},"docs":{"type":"string","title":"Docs"},"search":{"type":"string","title":"Search"},"mcp":{"type":"string","title":"Mcp"}},"type":"object","required":["service","docs","search","mcp"],"title":"ServiceInfo"},"StatsResponse":{"properties":{"corpus_release":{"type":"string","title":"Corpus Release"},"computed_at":{"type":"string","format":"date-time","title":"Computed At"},"total":{"type":"integer","title":"Total"},"with_doi":{"type":"integer","title":"With Doi"},"with_abstract":{"type":"integer","title":"With Abstract"},"abstract_s2":{"type":"integer","title":"Abstract S2"},"abstract_oa":{"type":"integer","title":"Abstract Oa"},"with_pdf":{"type":"integer","title":"With Pdf"},"years":{"items":{"prefixItems":[{"type":"integer"},{"type":"integer"}],"type":"array","maxItems":2,"minItems":2},"type":"array","title":"Years"},"year_unknown":{"type":"integer","title":"Year Unknown"},"with_arxiv":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"With Arxiv"},"external_ids":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"External Ids"},"open_access":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Open Access"},"with_fwci":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"With Fwci"},"with_topic":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"With Topic"},"retracted":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Retracted"},"fields_of_study":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Fields Of Study"},"publication_types":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Publication Types"}},"type":"object","required":["corpus_release","computed_at","total","with_doi","with_abstract","abstract_s2","abstract_oa","with_pdf","years","year_unknown"],"title":"StatsResponse","description":"Corpus-wide aggregates, recomputed after each biweekly sync (see\ncore/ingest/corpus_stats.py). `years` is an ascending [year, count] histogram;\nyears outside a sane window and NULLs are folded into `year_unknown`."},"StatusResponse":{"properties":{"service":{"type":"string","title":"Service"},"auth_required":{"type":"boolean","title":"Auth Required"},"rerank_enabled":{"type":"boolean","title":"Rerank Enabled"},"corpus_release":{"type":"string","title":"Corpus Release"},"index":{"$ref":"#/components/schemas/IndexStatus"}},"type":"object","required":["service","auth_required","rerank_enabled","corpus_release","index"],"title":"StatusResponse"},"UsageItem":{"properties":{"ts":{"type":"string","format":"date-time","title":"Ts"},"endpoint":{"type":"string","title":"Endpoint"},"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query"},"took_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Took Ms"},"num_results":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Num Results"},"status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status"}},"type":"object","required":["ts","endpoint"],"title":"UsageItem"},"UsageSummary":{"properties":{"total_requests":{"type":"integer","title":"Total Requests"},"requests_24h":{"type":"integer","title":"Requests 24H"},"avg_took_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Took Ms"},"recent":{"items":{"$ref":"#/components/schemas/UsageItem"},"type":"array","title":"Recent"}},"type":"object","required":["total_requests","requests_24h","recent"],"title":"UsageSummary"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"search","description":"Query the paper index."},{"name":"account","description":"Your own API keys and usage (key-authenticated)."},{"name":"meta","description":"Service info and liveness."}]}