REST API
The Genomic Intelligence API runs six DNA sequence analysis tasks built on transformer language models. Each task is a single HTTP endpoint: POST /v1/tasks/{task}/predict. The same six tasks are also reachable over MCP; the REST API and MCP server are peer interfaces over one contract.
This page covers the REST API: authentication, a quickstart, the six tasks, model selection, and error handling.
Base URL: https://api.genomicintelligence.ai
Overview
Every endpoint shares one contract:
- Six tasks, each at
POST /v1/tasks/{task}/predict:promoter,splice,enhancer,chromatin,annotation,expression. - Bearer authentication on every
/v1/*route. Public routes (no key):/health,/docs,/redoc,/v1/openapi.json. - One success envelope:
{data, meta}on every 2xx and 202.datacarries task-specific fields;metais uniform across tasks. - One error envelope:
{error: {code, message, request_id, details?}}. - Synchronous by default, asynchronous on request. Add
Prefer: respond-asyncto submit a job: the call returns202with ajob_id, and you pollGET /v1/tasks/jobs/{job_id}until it reaches a terminal state.
The live OpenAPI document at https://api.genomicintelligence.ai/v1/openapi.json is the machine-readable source of truth. It carries oneOf discriminators on data.task and on error.details, so generated typed clients (Python pydantic, TypeScript zod) narrow correctly. A rendered view is at https://api.genomicintelligence.ai/redoc.
Authentication
All /v1/* routes require a bearer token:
Authorization: Bearer gi_…
Each authenticated 2xx response and every 429 carries IETF RateLimit-* headers so you can pace requests:
RateLimit-Limit: <token-bucket capacity>
RateLimit-Remaining: <tokens left>
RateLimit-Reset: <seconds to full bucket>
RateLimit-Policy: <capacity>;w=60
The concurrency cap and the rate cap are independent, so a 429 can come from either. Per-key caps are in reference/limits.md.
Verify connectivity before integrating:
curl -sS https://api.genomicintelligence.ai/health
# {"status":"healthy","version":"YYYY.MM.DD.iter (commit)"}
curl -sS -H "Authorization: Bearer $GI_API_KEY" \
https://api.genomicintelligence.ai/v1/tasks/promoter/models
# 200 with {task, default_model, models: [...]}
Model-listing endpoints return a flat object, not the {data, meta} envelope used by predict endpoints.
Quickstart
A single prediction with curl:
curl -sS -X POST https://api.genomicintelligence.ai/v1/tasks/promoter/predict \
-H "Authorization: Bearer $GI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sequence": "ACGT...", "sequence_name": "demo"}'
The response is {data, meta}: data holds the predicted regions for this task, meta holds fields such as the inference time and the model used.
The repository bundles a runnable client and quickstart that exercise all six tasks against real biological sequences:
cd client/
pip install -r requirements.txt
GI_API_KEY=$GI_API_KEY python3 quickstart.py
To embed the contract directly, drop client/gi_client.py into your codebase. It depends only on requests and wraps both the sync and async paths:
from gi_client import Client, GIError
client = Client(api_key=os.environ["GI_API_KEY"])
# Synchronous
body = client.predict("promoter", sequence="ACGT" * 500, sequence_name="demo")
print(body["data"]["regions"], body["meta"]["inference_time_ms"])
# Asynchronous
job_id = client.submit_async(
"annotation", sequence=long_sequence, sequence_name="chr8:1-120000",
options={"batch_size": 8},
)
result = client.wait_for_job(job_id, on_progress=lambda p: print(p))
Every non-2xx raises GIError with .code, .message, .request_id, and .details.
For more integration shapes, the recipes/ directory has self-contained scripts: predicting promoters across a list of gene symbols, async annotation polling, rate-limit-aware retry, and typed error handling.
Using with an AI coding agent
If you are integrating from inside an AI coding agent, point it at this page and the llms.txt index so it works from the same contract. snippets/AGENTS.partner.md is a short AGENTS.md (or CLAUDE.md) fragment that captures the contract rules and the bug-report format, so an agent inherits them across sessions without re-reading this guide. If your agent runs in an MCP client such as Claude Desktop, Cursor, or Claude Code, the MCP server reaches the same six tasks with typed tools.
The six tasks
Each task accepts a DNA sequence (and a sequence_name label) and returns task-specific fields under data. Sequence-length limits per task are in reference/limits.md.
| Task | Endpoint | Output |
|---|---|---|
promoter | POST /v1/tasks/promoter/predict | Promoter-region probabilities (binary classification). Default model: 2000 bp context. |
splice | POST /v1/tasks/splice/predict | Per-token acceptor and donor splice-site predictions over a sliding window (up to 15000 bp context). |
enhancer | POST /v1/tasks/enhancer/predict | Developmental and housekeeping enhancer-activity scores (regression). |
chromatin | POST /v1/tasks/chromatin/predict | Multi-label chromatin features grouped into tracks (DNase, CTCF, Pol2, c-Myc, H3K27ac, H3K27me3, H3K4me1, Other). |
annotation | POST /v1/tasks/annotation/predict | Gene-finding transcript intervals (TSS/PolyA detection) over long sequences, up to 100000 bp. |
expression | POST /v1/tasks/expression/predict | Predicted gene expression in log(TPM+1) scale, from sequence plus an experimental description. |
Expression requires a description
The expression task is multi-modal: it predicts expression from the DNA sequence and an experimental context, so it requires a description alongside the sequence. Supply it in options.description:
curl -sS -X POST https://api.genomicintelligence.ai/v1/tasks/expression/predict \
-H "Authorization: Bearer $GI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sequence": "ACGT...",
"sequence_name": "MYC",
"options": {"description": "K562 cell line, RNA-seq"}
}'
A request without options.description is rejected with a 422 validation_failed error. The other five tasks do not take a description.
Model selection
Each task has a default model and may offer alternatives. List the models for a task with:
curl -sS -H "Authorization: Bearer $GI_API_KEY" \
https://api.genomicintelligence.ai/v1/tasks/promoter/models
The response is a flat object:
{
"task": "promoter",
"default_model": "g0-promoter-2000bp",
"models": [
{"name": "g0-promoter-2000bp", "description": "G0 Large Promoter (2000bp)"},
{"name": "g0-promoter-large-300bp", "description": "G0 Large Promoter (300bp)"}
]
}
If you do not name a model, the task uses default_model. To pick a specific one, pass its name in options.model:
curl -sS -X POST https://api.genomicintelligence.ai/v1/tasks/promoter/predict \
-H "Authorization: Bearer $GI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sequence": "ACGT...",
"sequence_name": "demo",
"options": {"model": "g0-promoter-large-300bp"}
}'
Beyond the default human models, the promoter task also offers species-specific models (Drosophila, yeast, Arabidopsis) and DNABERT k-mer variants for promoter, enhancer, and chromatin. The model list endpoint is authoritative for what each task currently serves.
Error handling
Every error uses the envelope {error: {code, message, request_id, details?}}. Switch on error.code, not on error.message. The code is the authoritative discriminator; the message is for human-readable logs and can change without notice. The full catalogue is in reference/errors.md.
Map every code to one of three actions:
| Category | Codes | Action |
|---|---|---|
| Retryable transient | 429 too_many_requests, 503 model_loading, 503 service_unavailable | Honour Retry-After. If absent, back off exponentially, capped near 30 s. |
| Permanent client error | 4xx other than 429, including 400 bad_request, 401 unauthorized, 403 forbidden, 404 not_found, 404 model_not_found, 409 conflict, 410 job_expired, 413 payload_too_large, 413 sync_too_large, 415 unsupported_format, 422 validation_failed, 422 task_not_supported_by_model | Surface error.message to the caller. Do not retry. 422 messages are deterministic and safe to echo. |
| Server error | 500 internal_error, other 5xx | Capture request_id, retry once at most, then escalate. |
504 gateway_timeout is the one response that does not use the envelope, because it comes from the edge proxy rather than the application. Treat it as a signal to switch to async: retry the request with Prefer: respond-async.
Sync timeout and async
Synchronous delivery is bounded by a 300 s upstream proxy timeout. For inputs above the per-task recommended threshold (see reference/limits.md), submit asynchronously with Prefer: respond-async, capture the job_id, and poll GET /v1/tasks/jobs/{job_id}. The poll body is the same {data, meta} shape; HTTP status discriminates progress (202) from terminal states (200, or 4xx/5xx).
Filing a bug
Email contact@genomicintelligence.ai with the error.request_id from the response body (also on the X-Request-Id header) and the X-Job-Id set on every successful POST.
Where to look next
- getting-started.md — auth, sync, and async with curl and Python, in narrative form.
- reference/errors.md — every
error.code. - reference/limits.md — per-task caps, rate quotas, and async job TTL.
- mcp.md — the same six tasks over Model Context Protocol.
https://api.genomicintelligence.ai/v1/openapi.json— live machine-readable contract.https://api.genomicintelligence.ai/redoc— rendered OpenAPI for browsing.