API reference¶
Integrate Aurora's spatial gene expression predictions into your research workflows through the API. Call Aurora API from the Python package, the command line, an agent over MCP, or plain HTTP.
Every endpoint is below, with what it takes, what it returns and the credential it needs. Access is granted per account, and Get access is the first step.
Every path on this page is relative to /v1 on https://api.auroraomics.org. /api-keys is https://api.auroraomics.org/v1/api-keys. A breaking change gets a new prefix. Within one prefix, changes are additive.
The schema itself is at https://api.auroraomics.org/v1/openapi.json (OpenAPI 3.1.0), for a client generator or an HTTP tool.
GET /, POST /auth/request-code and POST /auth/verify-code answer without a credential. The /api-keys routes take the session token that POST /auth/verify-code returns, and GET /api-keys/terms takes an API key as well. Every other route takes an API key, sent as Authorization: Bearer aok_…, holding the scope its entry names. A refusal is an application/problem+json document whose code is in the error catalogue.
From slide to result runs one prediction. Integration guide covers HTTP requests, retries and agent tools.
Two DeepSpot-M releases are published: deepspot-h/global/all@1.0.0 reads embeddings and deepspot-h/global/patches@1.0.0 reads patches, both on the hosted cpu runtime. Cutting and checking tiles needs no key. Running DeepSpot-H on your own machine needs one, and so does every submission.
Platform status is at https://auroraomics.org/api/health, and GET /v1/ on the API reports which runtimes are accepting work.
Credentials and rotation¶
What a key is¶
The secret is shown once, when the key is minted, and never again.
| Property | Value |
|---|---|
| Prefix | aok_ |
| Scopes | submit, read, manage:keys |
| Expires | 90 days after it is minted, by default |
| Lifetime you may ask for | 1 to 365 days, as ttl_days at mint |
| Warns from | 14 days before it expires |
| Overlap when rotated | 7 days |
Store the secret in an environment variable or a secret manager. Keep it out of
a notebook, a repository and a shell history. Use one key per machine, so
revoking one does not stop the others. If a key is lost, revoke it and run
login again to mint another.
Each key carries only the scopes it needs, and an operation outside them is
refused with forbidden. A missing or unusable
credential is unauthorized.
Before it expires¶
Keys expire on their own, and expiry is not optional. You are told in advance: inside the warning window, every response the key authenticates carries two extra headers.
| Header | Meaning |
|---|---|
API-Key-Expires-At |
The exact instant the key stops working (ISO 8601). |
API-Key-Days-Remaining |
Whole days remaining, rounded down: eleven hours is reported as 0, not 1. |
Both appear once the key is within 14 days of expiring, and not before.
Log or surface them: they are the only notice sent before a key expires.
GET /v1/me reports the same at any time.
POST /v1/api-keys/{key_id}/rotate mints a replacement. The old key keeps
working for the overlap above, so a running job finishes and the new key can be
deployed at your own pace. Rotation needs the email-code credential, so a
stolen key cannot mint its own successor.
Published models¶
| Identifier | Name | Observations | Covariates | Hosted runtime |
|---|---|---|---|---|
deepspot-h/global/all@1.0.0 |
DeepSpot-M | embeddings |
bulk_rna |
cpu |
deepspot-h/global/patches@1.0.0 |
DeepSpot-M | patches |
bulk_rna |
cpu |
Submission inputs¶
A covariate is a fact about the sample that its image does not carry.
| Field | Kinds | Containers |
|---|---|---|
observation — exactly one |
patches, embeddings |
npz, zip |
covariates — any accepted subset |
bulk_rna, tissue, disease |
enum, table |
| Kind | Container | Charges | Item cap | Size cap |
|---|---|---|---|---|
bulk_rna |
table |
— | — | 64 MiB |
tissue |
enum |
— | — | — |
disease |
enum |
— | — | — |
Endpoints¶
Discovery¶
What the service is and which models it runs.
GET /¶
Service discovery
Needs: no credential.
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | Discovery |
default |
Refused. The code says why. |
Problem |
GET /encoders¶
The encoders a client may run locally
The encoders a caller may run on their own machine to turn tiles into embeddings, each pinned so that two machines compute the same embedding. The Python package reads this list when it embeds locally.
Needs: an API key with the read scope.
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | object |
default |
Refused. The code says why. |
Problem |
GET /models¶
The models this deployment serves
Every model this deployment serves: its id, what it accepts, the runtime it runs on and its gene output.
Needs: an API key with the read scope.
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | array of ModelCardView |
default |
Refused. The code says why. |
Problem |
Uploads¶
Get an input onto the service, resumably.
POST /uploads¶
Start an upload
Declare a file by its kind, name, size and tree hash. The response gives the signed URL to send it to, the chunk size, and when that URL expires.
Needs: an API key with the submit scope.
Request body: application/json — UploadInitBody
| Status | Meaning | Body |
|---|---|---|
201 |
Successful Response | UploadInit |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
POST /uploads/{upload_id}/complete¶
Finalise an upload and read its verdict
Close an upload once every chunk is sent. A valid file is verified and charged; anything else is refused with the reason.
Needs: an API key with the submit scope.
| Parameter | In | Required | Type |
|---|---|---|---|
upload_id |
path | yes | string |
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | UploadVerdict |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
Jobs¶
Create a job from a model, an observation and any covariates, follow it, take its result, cancel or purge it.
GET /jobs¶
List my jobs
The account's jobs, newest first, one page at a time.
Needs: an API key with the read scope.
| Parameter | In | Required | Type |
|---|---|---|---|
limit |
query | no | integer |
cursor |
query | no | string |
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | JobPage |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
POST /jobs¶
Create a job
Start a prediction from a model id, an uploaded observation and any
covariates. The response is the job. Follow it with GET /jobs/{job_id}.
Needs: an API key with the submit scope.
| Parameter | In | Required | Type |
|---|---|---|---|
Idempotency-Key |
header | no | string or null |
Request body: application/json — PredictionBody
| Status | Meaning | Body |
|---|---|---|
202 |
Successful Response | Job |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
DELETE /jobs/{job_id}¶
Purge a job
Delete a job, its result and the job's own copy of what it read. A result already imported into a workspace stays there. It cannot be undone.
Needs: an API key with the submit scope.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id |
path | yes | string |
| Status | Meaning | Body |
|---|---|---|
204 |
Successful Response | — |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
GET /jobs/{job_id}¶
Read one job
Needs: an API key with the read scope.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id |
path | yes | string |
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | Job |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
POST /jobs/{job_id}/cancel¶
Cancel a job
Stop a job. A waiting job is canceled at once; a running one keeps its
state until it stops. A finished job refuses with job_not_cancelable.
Needs: an API key with the submit scope.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id |
path | yes | string |
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | Job |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
GET /jobs/{job_id}/result¶
Download the result
A signed link to the finished result, its size, and when the result
expires. Asked of a job that has not succeeded, it refuses with
result_not_ready. Once the result is past its window, it refuses with
result_expired.
Needs: an API key with the read scope.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id |
path | yes | string |
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | JobResult |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
Genes¶
Search and resolve the gene identifiers every result is keyed by.
GET /genes¶
Search the gene set
Needs: an API key with the read scope.
| Parameter | In | Required | Type |
|---|---|---|---|
q |
query | no | string |
limit |
query | no | integer |
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | GeneSetOut |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
POST /genes/resolve¶
Resolve names to Ensembl ids
Needs: an API key with the read scope.
Request body: application/json — ResolveBody
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | ResolveOut |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
Account¶
Sign in, mint and revoke API keys, and read what the calling key may do.
GET /api-keys¶
List my API keys
Needs: a session token.
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | array of KeyRow |
default |
Refused. The code says why. |
Problem |
POST /api-keys¶
Mint an API key
Needs: a session token.
Request body: application/json — MintKeyBody
| Status | Meaning | Body |
|---|---|---|
201 |
Successful Response | MintedKey |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
GET /api-keys/terms¶
The terms a mint must accept, and where to read them
Read them with the session token before minting a key, or with an API key, including one refused because the Terms changed after it was minted.
Needs: a session token or an API key.
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | TermsOut |
default |
Refused. The code says why. |
Problem |
DELETE /api-keys/{key_id}¶
Revoke one of my API keys
Needs: a session token.
| Parameter | In | Required | Type |
|---|---|---|---|
key_id |
path | yes | integer |
Request body: application/json — RevokeBody or null
| Status | Meaning | Body |
|---|---|---|
204 |
Successful Response | — |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
POST /api-keys/{key_id}/rotate¶
Rotate one of my API keys
Needs: a session token.
| Parameter | In | Required | Type |
|---|---|---|---|
key_id |
path | yes | integer |
Request body: application/json — RotateBody
| Status | Meaning | Body |
|---|---|---|
201 |
Successful Response | RotatedKey |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
POST /auth/request-code¶
Request a sign-in code
Needs: no credential.
Request body: application/json — RequestCodeBody
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | RequestCodeOut |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
POST /auth/verify-code¶
Exchange the code for a short-lived token
Needs: no credential.
Request body: application/json — VerifyCodeBody
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | VerifyCodeOut |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
GET /me¶
The calling key and its remaining life
The calling key: whose it is, what it may do, and when it expires. Inside the warning window, every response the key authenticates also carries its expiry headers.
Needs: an API key with the read scope.
| Status | Meaning | Body |
|---|---|---|
200 |
Successful Response | Me |
default |
Refused. The code says why. |
Problem |
Predictions¶
The first name of POST /jobs, deprecated and still answered.
POST /predictions¶
Deprecated.
Submit a prediction
Use POST /jobs instead: it takes the same body and answers the same way.
A job created through this route is the one POST /jobs would create, so a
retry under the same Idempotency-Key through either route returns it.
Needs: an API key with the submit scope.
| Parameter | In | Required | Type |
|---|---|---|---|
Idempotency-Key |
header | no | string or null |
Request body: application/json — PredictionBody
| Status | Meaning | Body |
|---|---|---|
202 |
Successful Response | Job |
422 |
The request does not match this schema. | Problem |
default |
Refused. The code says why. |
Problem |
Schemas¶
Discovery¶
| Property | Type | Required | Description |
|---|---|---|---|
access_request |
string |
yes | |
api_version |
string |
yes | |
docs |
string |
yes | |
lanes |
array of string |
yes | The runtimes accepting work. |
llms_txt |
string |
yes | |
models |
string |
yes | |
openapi |
string |
yes | |
qc |
object |
yes | |
retention |
object |
yes | |
service |
string |
yes |
No other properties are accepted.
GeneOut¶
| Property | Type | Required |
|---|---|---|
biotype |
string or null |
yes |
ensembl_gene_id |
string or null |
yes |
hgnc_id |
string or null |
yes |
in_ensembl |
boolean |
yes |
symbol |
string |
yes |
No other properties are accepted.
GeneSetOut¶
| Property | Type | Required |
|---|---|---|
ensembl_release |
integer |
yes |
fetch_date |
string |
yes |
matches |
array of GeneOut |
yes |
n_genes |
integer |
yes |
No other properties are accepted.
Job¶
| Property | Type | Required | Description |
|---|---|---|---|
created_at |
string |
yes | |
error |
object or null |
yes | Why the job failed, as a code and a detail; null otherwise. |
eta_seconds |
integer or null |
yes | The service's estimate of the seconds until the result exists; null when it has none. |
events |
array of JobEvent |
no | |
expires_at |
string or null |
yes | |
finished_at |
string or null |
yes | |
id |
string |
yes | |
items |
integer or null |
yes | How many tiles or rows the observation holds; null when they were not counted. |
landed |
boolean |
yes | Whether the result was offered to the submitter's workspace. |
lane |
string |
yes | The runtime the job runs on. |
model |
string |
yes | The id of the model the job runs. |
observation |
string |
yes | Deprecated. Read observation_kind instead; it carries the same value. |
observation_kind |
string |
yes | The kind of the observation the job reads. |
queue_position |
integer or null |
yes | Its place in its runtime's queue while it waits, 1 being next; 0 while it runs; null once it is over. |
started_at |
string or null |
yes | |
state |
string |
yes | One of queued, validating, running, succeeded, failed, canceled, expired. |
updated_at |
string |
yes |
No other properties are accepted.
JobEvent¶
| Property | Type | Required |
|---|---|---|
at |
string |
yes |
name |
string |
yes |
seconds |
number or null |
yes |
No other properties are accepted.
JobPage¶
| Property | Type | Required | Description |
|---|---|---|---|
jobs |
array of Job |
yes | |
next_cursor |
string or null |
yes | Send it back as cursor for the next page; null on the last. |
No other properties are accepted.
JobResult¶
| Property | Type | Required | Description |
|---|---|---|---|
expires_at |
string or null |
yes | When the result stops being available. |
format |
string |
yes | |
size_bytes |
integer |
yes | |
url |
string |
yes | A signed link to the result file. |
No other properties are accepted.
KeyRow¶
| Property | Type | Required |
|---|---|---|
created_at |
string |
yes |
days_remaining |
integer |
yes |
expires_at |
string |
yes |
expiring_soon |
boolean |
yes |
id |
integer |
yes |
last_used_at |
string or null |
yes |
name |
string |
yes |
prefix |
string |
yes |
replaced_by |
integer or null |
yes |
revoked_at |
string or null |
yes |
rotated_at |
string or null |
yes |
scopes |
array of string |
yes |
terms_version |
string |
yes |
tier |
string |
yes |
No other properties are accepted.
Me¶
Who the calling key belongs to, what it may do, and how long it has left.
| Property | Type | Required | Description |
|---|---|---|---|
api_access |
string |
yes | |
days_remaining |
integer |
yes | |
email |
string |
yes | |
expires_at |
string |
yes | |
expiring_soon |
boolean |
yes | |
key_prefix |
string |
yes | |
scopes |
array of string |
yes | |
tier |
string |
yes | |
warning_days |
integer |
yes | How many days before expiry expiring_soon turns true. |
No other properties are accepted.
MintKeyBody¶
| Property | Type | Required | Description |
|---|---|---|---|
accept_terms_version |
string |
yes | The version of the Terms you accept, as GET /api-keys/terms gives it. |
name |
string |
no | A label for the key, for your own records. |
scopes |
array of string |
no | What the key may do. Every scope when omitted. |
ttl_days |
integer |
no | How many days the key lives. |
No other properties are accepted.
MintedKey¶
| Property | Type | Required | Description |
|---|---|---|---|
created_at |
string |
yes | |
expires_at |
string |
yes | |
id |
integer |
yes | |
key |
string |
yes | The key itself. It is shown in this response only. |
name |
string |
yes | |
prefix |
string |
yes | |
scopes |
array of string |
yes | |
terms_version |
string |
yes | |
tier |
string |
yes |
No other properties are accepted.
ModelCardView¶
A model as the catalogue lists it: what a caller needs to choose one and prepare its input.
| Property | Type | Required | Description |
|---|---|---|---|
accepts |
object |
yes | |
family |
string |
yes | |
id |
string |
yes | The id a submission names as its model. |
input_spec |
object |
yes | |
lane |
string or null |
yes | The runtime the model runs on. |
name |
string |
yes | |
output |
ModelOutputView |
yes | |
postprocess |
array of string |
yes | |
released_at |
string |
yes | |
sunset |
string or null |
no |
No other properties are accepted.
ModelOutputView¶
| Property | Type | Required | Description |
|---|---|---|---|
gene_table |
string |
yes | |
n_genes |
integer |
yes | |
n_genes_measured |
integer |
yes | |
panel_sha256 |
string or null |
no | |
transform |
object or null |
no | The space the returned values are in. |
No other properties are accepted.
PredictionBody¶
| Property | Type | Required | Description |
|---|---|---|---|
covariates |
object |
no | Further inputs the model accepts, as {kind: upload_id} or {kind: value}. |
model |
string |
yes | The id of the model to run, as GET /models lists it. |
observation |
string or null |
no | The upload id of the one observation to predict from. Its kind is the kind it was uploaded as. Required unless the deprecated observations is sent instead. |
observations |
object or null |
no | Deprecated. Send observation instead. The one observation to predict from, as {kind: upload_id}. |
options |
PredictionOptions |
no |
No other properties are accepted.
PredictionOptions¶
What a caller may ask for beyond the prediction itself.
| Property | Type | Required | Description |
|---|---|---|---|
land_in_workspace |
boolean |
no | Offer the result to the submitter's workspace when it succeeds. |
No other properties are accepted.
Problem¶
Every refusal, as a problem document (RFC 9457) served as application/problem+json.
| Property | Type | Required | Description |
|---|---|---|---|
code |
string |
yes | What was refused, as a code from the error catalogue. |
detail |
string or null |
yes | What was refused, when there is more to say than the code. |
hint |
string or null |
yes | What to do next. |
param |
string or null |
yes | The field the refusal is about, when there is one. |
request_id |
string |
yes | This request's id, also sent as X-Request-Id. Quote it when you get in touch. |
status |
integer |
yes | The HTTP status, the one this code is always sent with. |
title |
string |
yes | The code, in words. |
type |
string |
yes | The address of this code's entry in the error catalogue. |
No other properties are accepted.
ReplacedKey¶
The key a rotation replaced, and when it now stops working.
| Property | Type | Required | Description |
|---|---|---|---|
days_remaining |
integer |
yes | |
expires_at |
string |
yes | When the replaced key stops working: the end of the overlap. |
id |
integer |
yes | |
prefix |
string |
yes | |
rotated_at |
string |
yes |
No other properties are accepted.
RequestCodeBody¶
| Property | Type | Required |
|---|---|---|
email |
string |
yes |
RequestCodeOut¶
| Property | Type | Required |
|---|---|---|
sent |
boolean |
no |
No other properties are accepted.
ResolveBody¶
| Property | Type | Required |
|---|---|---|
genes |
array of string |
yes |
No other properties are accepted.
ResolveOut¶
| Property | Type | Required |
|---|---|---|
genes |
array of GeneOut |
yes |
No other properties are accepted.
RevokeBody¶
| Property | Type | Required | Description |
|---|---|---|---|
reason |
string |
no | Why the key is revoked. |
No other properties are accepted.
RotateBody¶
| Property | Type | Required | Description |
|---|---|---|---|
accept_terms_version |
string |
yes | The version of the Terms you accept, as GET /api-keys/terms gives it. |
name |
string or null |
no | The replacement's label. The old key's when omitted. |
ttl_days |
integer |
no | How many days the replacement lives. |
No other properties are accepted.
RotatedKey¶
| Property | Type | Required | Description |
|---|---|---|---|
created_at |
string |
yes | |
expires_at |
string |
yes | |
id |
integer |
yes | |
key |
string |
yes | The key itself. It is shown in this response only. |
name |
string |
yes | |
prefix |
string |
yes | |
replaces |
ReplacedKey |
yes | |
scopes |
array of string |
yes | |
terms_version |
string |
yes | |
tier |
string |
yes |
No other properties are accepted.
TermsOut¶
| Property | Type | Required |
|---|---|---|
terms_url |
string |
yes |
terms_version |
string |
yes |
No other properties are accepted.
UploadInit¶
| Property | Type | Required | Description |
|---|---|---|---|
chunk_size_bytes |
integer |
yes | The chunk size to send, every chunk but the last. |
expires_at |
string |
yes | When url stops accepting chunks. |
upload_id |
string |
yes | |
url |
string |
yes | Where to send the file, in chunks. |
No other properties are accepted.
UploadInitBody¶
| Property | Type | Required | Description |
|---|---|---|---|
filename |
string |
yes | The file's name. |
kind |
string |
yes | The input kind this file is. A model's accepts names the kinds it reads. |
sha256 |
string |
yes | The file's tree hash, in hex: the sha256 over the raw sha256 digests of the chunks it will be sent in, in order. It is not the sha256 of the file. |
size_bytes |
integer |
yes | The file's exact size in bytes. |
No other properties are accepted.
UploadVerdict¶
| Property | Type | Required |
|---|---|---|
completed_at |
string or null |
yes |
kind |
string |
yes |
size_bytes |
integer |
yes |
status |
string |
yes |
upload_id |
string |
yes |
verdict |
object |
yes |
No other properties are accepted.
VerifyCodeBody¶
| Property | Type | Required |
|---|---|---|
code |
string |
yes |
email |
string |
yes |
VerifyCodeOut¶
| Property | Type | Required |
|---|---|---|
approved |
boolean |
yes |
token |
string |
yes |
No other properties are accepted.
Where processing runs¶
DeepSpot-H turns each tile of your slide into one embedding. It can run in your environment or on Aurora infrastructure. DeepSpot-M turns those embeddings into spatial gene expression. It runs on Aurora infrastructure.
The routes differ in what leaves your machine, not in where the prediction happens.