{"openapi":"3.1.0","info":{"title":"fanta.bio REST API","version":"0.3.0","description":"\nREST API for accessing fanta.bio metadata, including Cis-Regulatory Elements (CREs), genes, and SNPs.\n\n## Response Format\n\nAll endpoints return responses in this format:\n\n```json\n{\n  \"success\": true,\n  \"data\": [...],\n  \"meta\": {\n    \"version\": \"v0\",\n    \"count\": 20,\n    \"limit\": 20,\n    \"offset\": 0,\n    \"hasMore\": true\n  },\n  \"rateLimit\": {\n    \"limit\": 1000,\n    \"remaining\": 847,\n    \"reset\": 1735689600\n  }\n}\n```\n\n## Rate Limits\n\n| Endpoint Type | Requests/Hour |\n|---------------|---------------|\n| Simple lookups (by ID) | 500 |\n| Search endpoints | 300 |\n| Expression/Antigen data | 300 |\n| Full-text search | 100 |\n| Batch operations | 50 |\n\n## Support\n\n- Website: [fanta.bio](https://fanta.bio)\n- Issues: [GitHub](https://github.com/fanta-bio/fanta-bio-web/issues)\n","contact":{"name":"fanta.bio","url":"https://fanta.bio"},"license":{"name":"MIT","url":"https://opensource.org/licenses/MIT"}},"servers":[{"url":"https://api.fanta.bio","description":"Production"}],"tags":[{"name":"Search","description":"Unified cross-entity search"},{"name":"Genes","description":"Gene search and gene-to-CRE relationships"},{"name":"SNPs","description":"SNP/GWAS search and SNP-to-CRE relationships"},{"name":"CREs","description":"CRE search, lookup, expression, and ChIP-Atlas data"},{"name":"Analysis","description":"Cross-database analysis (shared regulators, regulatory summaries)"},{"name":"Meta","description":"API information and health checks"}],"components":{"schemas":{"CRESearchResult":{"type":"object","properties":{"cre_id":{"type":"string","description":"CRE ID (e.g., FCHS_1)"},"cre_name":{"type":"string","nullable":true,"description":"CRE name"},"organism":{"type":"string","nullable":true,"description":"Organism"},"genome_assembly":{"type":"string","nullable":true,"description":"Genome assembly"},"nearest_gene_symbol":{"type":"string","nullable":true,"description":"Nearest gene symbol"},"antigens":{"type":"string","nullable":true,"description":"Bound antigens/TFs"}},"required":["cre_id","cre_name","organism","genome_assembly"]},"ApiMeta":{"type":"object","properties":{"version":{"type":"string","description":"API version"},"count":{"type":"number","description":"Number of items in this response (the current page). Combine with `hasMore` to paginate; there is no precomputed total match count."},"limit":{"type":"number","description":"Limit applied"},"offset":{"type":"number","description":"Offset applied"},"hasMore":{"type":"boolean","description":"Whether more results are available"}},"required":["version"]},"RateLimit":{"type":"object","properties":{"limit":{"type":"number","description":"Requests allowed per window"},"remaining":{"type":"number","description":"Requests remaining in window"},"reset":{"type":"number","description":"Unix timestamp when window resets"}},"required":["limit","remaining","reset"]},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"$ref":"#/components/schemas/ApiError"}},"required":["success","error"]},"ApiError":{"type":"object","properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Human-readable error message"},"details":{"nullable":true,"description":"Additional error details"}},"required":["code","message"]},"RateLimitErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["RATE_LIMIT_EXCEEDED"]},"message":{"type":"string"},"details":{"type":"object","properties":{"limit":{"type":"number","description":"Maximum requests allowed in the window"},"window":{"type":"string","description":"Window duration (e.g., \"1h\", \"1m\")"},"retryAfter":{"type":"number","description":"Seconds until the rate limit resets"}},"required":["limit","window","retryAfter"]}},"required":["code","message","details"]}},"required":["success","error"]},"CREDetail":{"type":"object","properties":{"cre_id":{"type":"string","description":"CRE ID"},"cre_name":{"type":"string","nullable":true,"description":"CRE name"},"organism":{"type":"string","nullable":true,"description":"Organism"},"genome_assembly":{"type":"string","nullable":true,"description":"Genome assembly"},"annotation":{"nullable":true,"description":"Full CRE annotation object"}},"required":["cre_id","cre_name","organism","genome_assembly"]},"ChipAtlasAntigen":{"type":"object","properties":{"antigen":{"type":"string","description":"Antigen/TF name"},"max_qscore":{"type":"number","description":"Maximum Q-score across experiments"},"experiments":{"type":"array","items":{"$ref":"#/components/schemas/ChipAtlasExperiment"},"description":"Individual experiments"}},"required":["antigen"]},"ChipAtlasExperiment":{"type":"object","properties":{"id":{"type":"string","description":"Experiment ID"},"qscore":{"type":"number","description":"Q-score"}},"required":["id","qscore"]},"Gene":{"type":"object","properties":{"gene_id":{"type":"string","description":"Ensembl gene ID (e.g., ENSG00000290825.2)"},"gene_symbol":{"type":"string","nullable":true,"description":"Gene symbol (e.g., DDX11L1)"},"gene_name":{"type":"string","nullable":true,"description":"Full gene name"},"organism":{"type":"string","description":"Organism (human or mouse)"},"genome_assembly":{"type":"string","nullable":true,"description":"Genome assembly (hg38 or mm39)"},"chr":{"type":"string","nullable":true,"description":"Chromosome"},"start_pos":{"type":"number","nullable":true,"description":"Start position"},"end_pos":{"type":"number","nullable":true,"description":"End position"},"entrez_gene_id":{"type":"string","nullable":true,"description":"Entrez Gene ID"},"hgnc_mgi_id":{"type":"string","nullable":true,"description":"HGNC/MGI ID"},"uniprot_id":{"type":"string","nullable":true,"description":"UniProt ID"},"synonyms":{"type":"string","nullable":true,"description":"Gene synonyms (space-separated; multi-word synonyms use `_` as space)"},"gene_source":{"type":"string","nullable":true,"description":"Gene annotation source"},"gene_type":{"type":"string","nullable":true,"description":"Gene type (e.g., protein_coding)"},"cre_count":{"type":"number","nullable":true,"description":"Number of associated CREs"}},"required":["gene_id","gene_symbol","gene_name","organism","genome_assembly","chr","start_pos","end_pos","cre_count"]},"GeneToCRE":{"type":"object","properties":{"gene_id":{"type":"string","description":"Gene ID"},"cre_id":{"type":"string","description":"CRE ID"},"distance":{"type":"number","description":"Distance from gene TSS in base pairs"},"organism":{"type":"string","nullable":true,"description":"Organism"},"genome_assembly":{"type":"string","nullable":true,"description":"Genome assembly"}},"required":["gene_id","cre_id","distance","organism","genome_assembly"]},"Expression":{"type":"object","properties":{"cre_id":{"type":"string","description":"CRE ID"},"expression":{"type":"array","items":{"type":"number"},"description":"Expression values array"},"sparse_data":{"nullable":true,"description":"Sparse expression data"}}},"SNP":{"type":"object","properties":{"snp_id":{"type":"string","description":"SNP rs ID (e.g., rs10001548)"},"organism":{"type":"string","description":"Organism"},"genome_assembly":{"type":"string","nullable":true,"description":"Genome assembly"},"trait":{"type":"string","nullable":true,"description":"Associated GWAS trait"},"chr":{"type":"string","nullable":true,"description":"Chromosome"},"start_pos":{"type":"number","nullable":true,"description":"Start position"},"end_pos":{"type":"number","nullable":true,"description":"End position"},"cre_count":{"type":"number","nullable":true,"description":"Number of associated CREs"}},"required":["snp_id","organism","genome_assembly","trait","chr","start_pos","end_pos","cre_count"]},"SNPToCRE":{"type":"object","properties":{"snp_id":{"type":"string","description":"SNP ID"},"cre_id":{"type":"string","description":"CRE ID"},"distance":{"type":"number","description":"Distance from SNP in base pairs"},"organism":{"type":"string","nullable":true,"description":"Organism"},"genome_assembly":{"type":"string","nullable":true,"description":"Genome assembly"}},"required":["snp_id","cre_id","distance","organism","genome_assembly"]}},"parameters":{}},"paths":{"/v0/cres/by-region":{"get":{"operationId":"getCREsByRegion","tags":["CREs"],"summary":"Search CREs by genomic region","description":"Find CREs whose coordinates fall fully within the given chr:start-end range.","parameters":[{"schema":{"type":"string","description":"Chromosome (e.g., chr1, chr17)","example":"chr17"},"required":true,"description":"Chromosome (e.g., chr1, chr17)","name":"chr","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Start position (0-based)","example":7500000},"required":false,"description":"Start position (0-based)","name":"start","in":"query"},{"schema":{"type":"integer","minimum":1,"description":"End position","example":7700000},"required":true,"description":"End position","name":"end","in":"query"},{"schema":{"type":"string","enum":["any","human","mouse","hg38","mm10","GRCh38","mm39"],"default":"any","description":"Filter by organism/assembly","example":"human"},"required":false,"description":"Filter by organism/assembly","name":"organism","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"Maximum results to return","example":50},"required":false,"description":"Maximum results to return","name":"limit","in":"query"}],"responses":{"200":{"description":"CREs in region","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/CRESearchResult"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/cres":{"get":{"operationId":"searchCREs","tags":["CREs"],"summary":"Search CREs with filters","description":"Search for CREs using filters: id, name, antigen, external_id. Supports wildcards (`*` matches zero or more characters; `?` matches a single character). At least one filter is required. Multiple filters AND together.","parameters":[{"schema":{"type":"string","maxLength":100,"description":"CRE ID filter (supports wildcards * and ?)","example":"FCHS_*"},"required":false,"description":"CRE ID filter (supports wildcards * and ?)","name":"id","in":"query"},{"schema":{"type":"string","maxLength":100,"description":"CRE name filter (supports wildcards * and ?)","example":"cp1@*"},"required":false,"description":"CRE name filter (supports wildcards * and ?)","name":"name","in":"query"},{"schema":{"type":"string","maxLength":100,"description":"Bound TF filter (supports wildcards * and ?)","example":"CTCF"},"required":false,"description":"Bound TF filter (supports wildcards * and ?)","name":"antigen","in":"query"},{"schema":{"type":"string","maxLength":100,"description":"External identifier filter","example":"TP53"},"required":false,"description":"External identifier filter","name":"external_id","in":"query"},{"schema":{"type":"string","enum":["any","human","mouse","hg38","mm39","GRCh38","mm10"],"default":"any","description":"Organism or genome assembly filter","example":"human"},"required":false,"description":"Organism or genome assembly filter","name":"organism","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Maximum number of results to return (1-100)","example":20},"required":false,"description":"Maximum number of results to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of results to skip","example":0},"required":false,"description":"Number of results to skip","name":"offset","in":"query"}],"responses":{"200":{"description":"Successful CRE search","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/CRESearchResult"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/cres/antigens":{"get":{"operationId":"getAntigensForCREs","tags":["CREs"],"summary":"Get unique antigens for CRE list","description":"Get list of unique antigens/TFs bound to any of the given CRE IDs. Pass IDs as a comma-separated list (max 200 unique).","parameters":[{"schema":{"type":"string","maxLength":10000,"description":"Comma-separated list of CRE IDs (max 200 unique)","example":"FCHS_1,FCHS_2,FCHS_3"},"required":true,"description":"Comma-separated list of CRE IDs (max 200 unique)","name":"cre_ids","in":"query"}],"responses":{"200":{"description":"Antigens list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"antigens":{"type":"array","items":{"type":"string"}}},"required":["antigens"]},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/cres/search":{"post":{"operationId":"searchCREsFulltext","tags":["CREs"],"summary":"Full-text keyword search","description":"Full-text keyword search across CRE IDs, names, gene symbols, gene names, antigens, and external IDs. Uses FTS5 with weighted BM25 ranking and exact-cre_id/cre_name boost.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Full-text search query","example":"TP53"},"organism":{"type":"string","enum":["any","human","mouse","hg38","mm39","GRCh38","mm10"],"default":"any","description":"Organism or genome assembly filter","example":"human"},"limit":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Maximum number of results to return (1-100)","example":20},"offset":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of results to skip","example":0}},"required":["query"],"example":{"query":"TP53","organism":"human","limit":20}}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/CRESearchResult"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload Too Large — request body exceeds 64 KB","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Request body exceeds the 64 KB limit"}]}}}},"415":{"description":"Unsupported Media Type — POST requests must use Content-Type: application/json","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Missing or non-JSON Content-Type header"}]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/cres/batch":{"post":{"operationId":"getCREsBatch","tags":["CREs"],"summary":"Batch CRE lookup","description":"Retrieve multiple CREs by ID in a single request. Duplicates in the input array are deduped server-side. Max 200 unique IDs.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"cre_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$"},"minItems":1,"maxItems":200,"description":"Array of CRE IDs to lookup (max 200 unique)"}},"required":["cre_ids"],"example":{"cre_ids":["FCHS_1","FCHS_2","FCHS_3"]}}}}},"responses":{"200":{"description":"CRE details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/CREDetail"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload Too Large — request body exceeds 64 KB","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Request body exceeds the 64 KB limit"}]}}}},"415":{"description":"Unsupported Media Type — POST requests must use Content-Type: application/json","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Missing or non-JSON Content-Type header"}]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/cres/{id}":{"get":{"operationId":"getCRE","tags":["CREs"],"summary":"Get CRE by ID","description":"Retrieve detailed annotation information about a specific CRE.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"CRE identifier (e.g., FCHS_1, FCMM_1)","example":"FCHS_1"},"required":true,"description":"CRE identifier (e.g., FCHS_1, FCMM_1)","name":"id","in":"path"}],"responses":{"200":{"description":"CRE details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/CREDetail"},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"CRE not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/cres/{id}/expression":{"get":{"operationId":"getCREExpression","tags":["CREs"],"summary":"Get CRE expression data","description":"Retrieve expression data for a specific CRE. The DB stores sparse `{i: [...], v: [...]}` form; this endpoint expands it to a dense array of length max(i) + 1.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"CRE identifier (e.g., FCHS_1, FCMM_1)","example":"FCHS_1"},"required":true,"description":"CRE identifier (e.g., FCHS_1, FCMM_1)","name":"id","in":"path"}],"responses":{"200":{"description":"Expression data","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"cre_id":{"type":"string"},"expression":{"type":"array","items":{"type":"number"}}},"required":["cre_id","expression"]},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"Expression data not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/cres/{id}/antigens":{"get":{"operationId":"getCREAntigens","tags":["CREs"],"summary":"Get CRE ChIP-Atlas antigens","description":"Retrieve antigens/TFs bound to a CRE with Q-scores from ChIP-Atlas experiments. Sorted by max_qscore descending; capped by `limit`.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"CRE identifier (e.g., FCHS_1, FCMM_1)","example":"FCHS_1"},"required":true,"description":"CRE identifier (e.g., FCHS_1, FCMM_1)","name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"Maximum results (1-200)","example":50},"required":false,"description":"Maximum results (1-200)","name":"limit","in":"query"}],"responses":{"200":{"description":"Antigen binding data","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/ChipAtlasAntigen"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"Antigen data not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/genes":{"get":{"operationId":"searchGenes","tags":["Genes"],"summary":"Search genes","description":"Search for genes by ID, symbol, name, or synonyms using FTS5 full-text search.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Search query (gene ID, symbol, name, or synonym)","example":"TP53"},"required":true,"description":"Search query (gene ID, symbol, name, or synonym)","name":"query","in":"query"},{"schema":{"type":"string","enum":["any","human","mouse","hg38","mm39","GRCh38","mm10"],"default":"any","description":"Organism or genome assembly filter","example":"human"},"required":false,"description":"Organism or genome assembly filter","name":"organism","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Maximum number of results to return (1-100)","example":20},"required":false,"description":"Maximum number of results to return (1-100)","name":"limit","in":"query"}],"responses":{"200":{"description":"Successful gene search","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Gene"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/genes/{id}":{"get":{"operationId":"getGene","tags":["Genes"],"summary":"Get gene by ID","description":"Retrieve detailed information about a gene by Ensembl ID, gene symbol (case-insensitive), or any registered synonym.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","example":"TP53"},"required":true,"description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","name":"id","in":"path"}],"responses":{"200":{"description":"Gene details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Gene"},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"Gene not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/genes/{id}/cres":{"get":{"operationId":"getGeneCREs","tags":["Genes"],"summary":"Find CREs for gene","description":"Find Cis-Regulatory Elements associated with a specific gene, sorted by distance from TSS. Accepts Ensembl IDs, symbols, or synonyms.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","example":"TP53"},"required":true,"description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","name":"id","in":"path"},{"schema":{"type":"string","maxLength":100,"description":"Filter by bound TF/antigen","example":"CTCF"},"required":false,"description":"Filter by bound TF/antigen","name":"antigen","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"Maximum results (1-200)","example":50},"required":false,"description":"Maximum results (1-200)","name":"limit","in":"query"}],"responses":{"200":{"description":"Gene-CRE relationships","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/GeneToCRE"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/genes/{id}/expression":{"get":{"operationId":"getGeneExpression","tags":["Genes"],"summary":"Get expression data for gene","description":"Retrieve sparse expression data for the CREs associated with a gene.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","example":"TP53"},"required":true,"description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":100,"description":"Maximum results (1-100)","example":100},"required":false,"description":"Maximum results (1-100)","name":"limit","in":"query"}],"responses":{"200":{"description":"Expression data","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Expression"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"No expression data found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/genes/{id}/antigens":{"get":{"operationId":"getGeneAntigens","tags":["Genes"],"summary":"Get antigens for gene","description":"Retrieve the list of unique antigens/TFs bound to CREs associated with this gene.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","example":"TP53"},"required":true,"description":"Gene ID, gene symbol, or synonym (e.g., ENSG00000141510.20, TP53, IFI15)","name":"id","in":"path"}],"responses":{"200":{"description":"Antigens list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"antigens":{"type":"array","items":{"type":"string"}}},"required":["antigens"]},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"No CREs found for gene","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/snps":{"get":{"operationId":"searchSNPs","tags":["SNPs"],"summary":"Search SNPs","description":"Search for SNPs by ID (rs number) or associated GWAS trait using FTS5 full-text search.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Search query (rs ID or trait name)","example":"rs10001548"},"required":true,"description":"Search query (rs ID or trait name)","name":"query","in":"query"},{"schema":{"type":"string","enum":["any","human","mouse","hg38","mm39","GRCh38","mm10"],"default":"any","description":"Organism or genome assembly filter","example":"human"},"required":false,"description":"Organism or genome assembly filter","name":"organism","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Maximum number of results to return (1-100)","example":20},"required":false,"description":"Maximum number of results to return (1-100)","name":"limit","in":"query"}],"responses":{"200":{"description":"Successful SNP search","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/SNP"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/snps/{id}":{"get":{"operationId":"getSNP","tags":["SNPs"],"summary":"Get SNP by ID","description":"Retrieve detailed information about a specific SNP by its rs ID.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"SNP rs identifier (e.g., rs10001548)","example":"rs10001548"},"required":true,"description":"SNP rs identifier (e.g., rs10001548)","name":"id","in":"path"}],"responses":{"200":{"description":"SNP details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/SNP"},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"SNP not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/snps/{id}/cres":{"get":{"operationId":"getSNPCREs","tags":["SNPs"],"summary":"Find CREs near SNP","description":"Find Cis-Regulatory Elements near a specific SNP, sorted by distance.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$","description":"SNP rs identifier (e.g., rs10001548)","example":"rs10001548"},"required":true,"description":"SNP rs identifier (e.g., rs10001548)","name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"Maximum results (1-200)","example":50},"required":false,"description":"Maximum results (1-200)","name":"limit","in":"query"}],"responses":{"200":{"description":"SNP-CRE relationships","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/SNPToCRE"}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/analysis/shared-regulators":{"post":{"operationId":"findSharedRegulators","tags":["Analysis"],"summary":"Find shared transcription factors","description":"Find transcription factors shared across multiple CREs or genes. Useful for identifying common regulatory programs.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"cre_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9._:-]+$"},"maxItems":500,"description":"CRE IDs to analyze (max 500)"},"gene_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9._:-]+$"},"maxItems":50,"description":"Gene symbols or Ensembl IDs (resolved to CREs first; max 50)"},"min_shared":{"type":"integer","minimum":1,"default":2,"description":"Minimum number of CREs a TF must be bound to"}},"example":{"gene_ids":["TP53","BRCA1"],"min_shared":2}}}}},"responses":{"200":{"description":"Shared regulators","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"antigen":{"type":"string"},"cre_count":{"type":"number"},"cre_ids":{"type":"string"}},"required":["antigen","cre_count","cre_ids"]}},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload Too Large — request body exceeds 64 KB","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Request body exceeds the 64 KB limit"}]}}}},"415":{"description":"Unsupported Media Type — POST requests must use Content-Type: application/json","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Missing or non-JSON Content-Type header"}]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/analysis/gene-regulatory-summary":{"post":{"operationId":"getGeneRegulatorySummary","tags":["Analysis"],"summary":"Get gene regulatory landscape summary","description":"Comprehensive regulatory summary for a gene: gene info, associated CREs, and top transcription factors.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"gene_id":{"type":"string","description":"Gene symbol (e.g., TP53) or Ensembl gene ID","example":"TP53"},"cre_limit":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"Maximum CREs to include","example":50}},"required":["gene_id"],"example":{"gene_id":"TP53","cre_limit":50}}}}},"responses":{"200":{"description":"Gene regulatory summary","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"gene":{"type":"object","properties":{},"additionalProperties":{"nullable":true}},"cres":{"type":"array","items":{"type":"object","properties":{},"additionalProperties":{"nullable":true}}},"summary":{"type":"object","properties":{"total_cres":{"type":"number"},"unique_tfs":{"type":"number"},"top_tfs":{"type":"array","items":{"type":"object","properties":{"antigen":{"type":"string"},"cre_count":{"type":"number"}},"required":["antigen","cre_count"]}}},"required":["total_cres","unique_tfs","top_tfs"]}},"required":["gene","cres","summary"]},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"Gene not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload Too Large — request body exceeds 64 KB","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Request body exceeds the 64 KB limit"}]}}}},"415":{"description":"Unsupported Media Type — POST requests must use Content-Type: application/json","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Missing or non-JSON Content-Type header"}]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/analysis/snp-regulatory-impact":{"post":{"operationId":"getSNPRegulatoryImpact","tags":["Analysis"],"summary":"Analyze SNP regulatory impact","description":"Analyze the regulatory impact of a SNP: SNP info, affected CREs, and transcription factors bound to those CREs.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"snp_id":{"type":"string","description":"SNP rs identifier (e.g., rs10001548)","example":"rs10001548"},"cre_limit":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"Maximum CREs to include","example":50}},"required":["snp_id"],"example":{"snp_id":"rs10001548","cre_limit":50}}}}},"responses":{"200":{"description":"SNP regulatory impact","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"snp":{"type":"object","properties":{},"additionalProperties":{"nullable":true}},"cres":{"type":"array","items":{"type":"object","properties":{},"additionalProperties":{"nullable":true}}},"summary":{"type":"object","properties":{"total_cres":{"type":"number"},"unique_tfs":{"type":"number"},"top_tfs":{"type":"array","items":{"type":"object","properties":{"antigen":{"type":"string"},"cre_count":{"type":"number"}},"required":["antigen","cre_count"]}}},"required":["total_cres","unique_tfs","top_tfs"]}},"required":["snp","cres","summary"]},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"404":{"description":"SNP not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload Too Large — request body exceeds 64 KB","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Request body exceeds the 64 KB limit"}]}}}},"415":{"description":"Unsupported Media Type — POST requests must use Content-Type: application/json","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Missing or non-JSON Content-Type header"}]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0/search":{"post":{"operationId":"unifiedSearch","tags":["Search"],"summary":"Unified cross-entity search","description":"Run gene, SNP, and CRE searches in parallel for a single query. By default the entity types are auto-detected from the query shape (`rs\\d+` → SNP, `ENS...G` → gene, `FCHS_/FCMM_` → CRE, otherwise all three). Pass `types` to override.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Search query","example":"TP53"},"organism":{"type":"string","enum":["any","human","mouse","hg38","mm39","GRCh38","mm10"],"default":"any","description":"Organism or genome assembly filter","example":"human"},"limit":{"type":"integer","minimum":1,"maximum":50,"default":10,"description":"Maximum results per entity type (genes/snps/cres). Total returned ≤ 3× this."},"types":{"type":"array","items":{"type":"string","enum":["gene","snp","cre"]},"minItems":1,"description":"Restrict fan-out to these entity types (default: auto-detect from query shape)","example":["gene","snp"]}},"required":["query"],"example":{"query":"TP53","organism":"human","limit":10}}}}},"responses":{"200":{"description":"Unified search results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"query":{"type":"string","description":"The original query"},"types":{"type":"array","items":{"type":"string","enum":["gene","snp","cre"]},"description":"The entity types actually searched (after auto-detect or explicit `types`)"},"genes":{"type":"array","items":{"$ref":"#/components/schemas/Gene"},"description":"Top gene hits (empty if `gene` was not searched)"},"snps":{"type":"array","items":{"$ref":"#/components/schemas/SNP"},"description":"Top SNP hits (empty if `snp` was not searched)"},"cres":{"type":"array","items":{"$ref":"#/components/schemas/CRESearchResult"},"description":"Top CRE hits (empty if `cre` was not searched)"}},"required":["query","types","genes","snps","cres"]},"meta":{"$ref":"#/components/schemas/ApiMeta"},"rateLimit":{"$ref":"#/components/schemas/RateLimit"}},"required":["success","data"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload Too Large — request body exceeds 64 KB","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Request body exceeds the 64 KB limit"}]}}}},"415":{"description":"Unsupported Media Type — POST requests must use Content-Type: application/json","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"description":"Missing or non-JSON Content-Type header"}]}}}},"429":{"description":"Too Many Requests — rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v0":{"get":{"operationId":"getV0Info","tags":["Meta"],"summary":"V0 API info","description":"Returns version information and the v0 endpoint map.","responses":{"200":{"description":"V0 API information","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string","enum":["v0"]},"status":{"type":"string"},"description":{"type":"string"},"database":{"type":"string"},"endpoints":{"type":"object","properties":{"cres":{"type":"string"},"genes":{"type":"string"},"snps":{"type":"string"},"analysis":{"type":"string"},"search":{"type":"string"},"docs":{"type":"string"}},"required":["cres","genes","snps","analysis","search","docs"]},"features":{"type":"object","properties":{"fullTextSearch":{"type":"string"},"wildcards":{"type":"string"},"pagination":{"type":"string"}},"required":["fullTextSearch","wildcards","pagination"]}},"required":["version","status","description","database","endpoints","features"]}}}}}}},"/":{"get":{"operationId":"getApiInfo","tags":["Meta"],"summary":"API information","description":"Returns the API name, version, environment, top-level endpoint map, and support links.","responses":{"200":{"description":"API information","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"database":{"type":"string"},"environment":{"type":"string"},"endpoints":{"type":"object","properties":{"v0":{"type":"object","properties":{"root":{"type":"string"},"cres":{"type":"string"},"genes":{"type":"string"},"snps":{"type":"string"},"analysis":{"type":"string"}},"required":["root","cres","genes","snps","analysis"]},"docs":{"type":"string"},"openapi":{"type":"string"}},"required":["v0","docs","openapi"]},"support":{"type":"object","properties":{"website":{"type":"string"},"issues":{"type":"string"}},"required":["website","issues"]}},"required":["name","description","version","database","environment","endpoints","support"]}}}}}}},"/health":{"get":{"operationId":"getHealth","tags":["Meta"],"summary":"Health check","description":"Liveness probe for monitoring services. Returns 200 with a healthy status when the worker is running.","responses":{"200":{"description":"Worker is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy"]},"timestamp":{"type":"string","description":"ISO 8601 timestamp"},"environment":{"type":"string"},"database":{"type":"string"}},"required":["status","timestamp","environment","database"]}}}}}}}}}