# REST API

Call the REST API from any language: post a sequence to `POST /v1/tasks/{task}/predict` with an API key, get back typed JSON. This page walks the contract, then the [integration kit](#3-get-the-kit) — a single-file Python client and runnable recipes that let you reproduce every call in a few minutes.

Base URL: `https://api.genomicintelligence.ai`

## 1. The contract

Every endpoint shares one shape:

- **Six tasks**, each at `POST /v1/tasks/{task}/predict`: `promoter`, `splice`, `enhancer`, `chromatin`, `annotation`, `expression`.
- **API key** on every `/v1/*` route, sent as `Authorization: Bearer gi_…`. Public (no key): `/health`, `/docs`, `/redoc`, `/v1/openapi.json`.
- **One success envelope** — `{data, meta}` on every 2xx and 202. `data` is task-specific; `meta` is uniform across tasks.
- **One error envelope** — `{error: {code, message, request_id, details?}}`. Switch on `error.code`, never the message.
- **Sync by default, async on request** — add `Prefer: respond-async` for long inputs: the call returns `202` with a `job_id`, and you poll `GET /v1/tasks/jobs/{job_id}`.

The live [OpenAPI schema](https://api.genomicintelligence.ai/v1/openapi.json) (browse it in [ReDoc](https://api.genomicintelligence.ai/redoc)) is the machine-readable source of truth for every field.

## 2. Get a key

Email [contact@genomicintelligence.ai](mailto:contact@genomicintelligence.ai) for a `gi_…` API key. The same key works for the REST API and the [MCP server](mcp.md).

Verify it in one call:

```bash
curl -sS https://api.genomicintelligence.ai/health
# {"status":"healthy","version":"YYYY.MM.DD.iter (commit)"}
```

## 3. Get the kit

Browse the code in your browser — the [Python client](/integration-kit/client)
and [recipes](/integration-kit/recipes) render with syntax highlighting — or
**[download the integration kit](https://docs.genomicintelligence.ai/integration-kit.tar.gz)**
(`.tar.gz`) to run it locally. Fetch it inline:

```bash
curl -L https://docs.genomicintelligence.ai/integration-kit.tar.gz | tar -xz
cd integration-kit/
```

Inside:

| Path | What it is |
|---|---|
| `client/gi_client.py` | Single-file client. Depends only on `requests`. Drop it into your project. |
| `client/quickstart.py` | Runs every task end to end on real bundled sequences. |
| `client/sequences/` | Real FASTA fixtures, one per task. |
| `recipes/` | Five self-contained integration patterns (see [Recipes](#6-recipes)). |

## 4. Run the quickstart

This hits every task with a real biological sequence and prints the result — the fastest way to see the API work:

```bash
cd integration-kit/client
pip install -r requirements.txt
export GI_API_KEY=gi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
python quickstart.py
```

## 5. Call a task

Drop `gi_client.py` into your project and call a task. Every prediction returns the full `{data, meta}` body:

```python
import os
from gi_client import Client

client = Client(api_key=os.environ["GI_API_KEY"])

body = client.predict("promoter", sequence="ACGT" * 500, sequence_name="demo")
print(body["meta"]["model"], body["meta"]["inference_time_ms"], "ms")
print(body["data"]["regions"])
```

The `expression` task also takes an experimental-context description:

```python
body = client.predict(
    "expression",
    sequence=tss_window,                 # 9,198 bp centered on the TSS
    sequence_name="HBB",
    options={"description": "polyA plus RNA-seq; Homo sapiens K562"},
)
print(body["data"]["prediction"]["expression_log_tpm"], "log(TPM+1)")
```

Per-task inputs, options, and outputs are on the [Tasks](tasks.md) page.

### Asynchronous jobs

For long inputs, submit asynchronously and poll. The client handles both steps — submit returns a `job_id`, and `wait_for_job` polls until the job is done:

```python
job_id = client.submit_async(
    "annotation", sequence=long_sequence, sequence_name="chr8:1-120000",
)
result = client.wait_for_job(job_id, on_progress=print)
print(len(result["data"].get("transcripts", [])), "transcripts")
```

Use async above the per-task size thresholds in [Limits](reference/limits.md); below them, sync is simplest.

### Error handling

Every non-2xx raises `GIError`, carrying the envelope's fields. Switch on `code`, not HTTP status:

```python
from gi_client import Client, GIError

try:
    client.predict("promoter", sequence="ACGT" * 500, sequence_name="demo")
except GIError as exc:
    print(exc.code, exc.message, exc.request_id)
```

Every `error.code` and how to handle it is in [Errors](reference/errors.md).

## 6. Recipes

Self-contained scripts that each show one pattern. [Read them all in the
browser](/integration-kit/recipes), or link straight to the raw source:

| Intent | Recipe |
|---|---|
| Verify connectivity and key | [`01_health_probe.py`](https://docs.genomicintelligence.ai/recipes/01_health_probe.py) |
| Promoters across a gene list | [`02_promoters_for_gene_list.py`](https://docs.genomicintelligence.ai/recipes/02_promoters_for_gene_list.py) |
| Async annotation with polling | [`03_async_annotation_polling.py`](https://docs.genomicintelligence.ai/recipes/03_async_annotation_polling.py) |
| Rate-limit-aware retry | [`04_ratelimit_aware_retry.py`](https://docs.genomicintelligence.ai/recipes/04_ratelimit_aware_retry.py) |
| Typed error handling | [`05_typed_error_handling.py`](https://docs.genomicintelligence.ai/recipes/05_typed_error_handling.py) |

## Client reference

`gi_client.py` exposes:

- `Client(api_key, base_url=…, timeout=…)` — session configured with your key.
- `predict(task, sequence, sequence_name, model=None, options=None)` — synchronous; returns `{data, meta}`.
- `submit_async(...)` — submit with `Prefer: respond-async`; returns a `job_id`.
- `wait_for_job(job_id, poll_interval=2.0, on_progress=None)` — poll until terminal.
- `list_models(task)`, `list_jobs(limit=…)`, `health()` — supporting calls.
- `GIError` — raised on any non-2xx, carrying `code`, `message`, `request_id`, `details`.

## Output formats

Predictions return JSON in the `{data, meta}` envelope by default. Tasks that also emit text tracks (BED, bedGraph, GFF3) expose them via the `Accept` header or a `?format=` query parameter; the [Tasks](tasks.md) page lists the formats each one supports.

## Next steps

- [Tasks](tasks.md): per-task input sizes, options, outputs, and strand-sensitivity.
- [Errors](reference/errors.md): every `error.code` and how to handle it.
- [Limits](reference/limits.md): per-task length caps, rate quotas, async TTL.
- [MCP server](mcp.md): the same six tasks as agent tools.
- [OpenAPI schema](https://api.genomicintelligence.ai/v1/openapi.json) · [ReDoc](https://api.genomicintelligence.ai/redoc): the full machine-readable contract.
