Every path below is relative to https://blueprint.love. The API is not versioned, so an endpoint can change without notice.
This page was last checked against the server code on .
Conventions
Requests and responses are JSON unless an endpoint says it returns a file. JSON responses share one envelope:
code
The HTTP status as a number. A queued job answers HTTP 202 but still carries 200 here. One exception: a busy /api/plot/generate answers 503 with the string "PLOT_BUSY".
message
A short summary: usually success, otherwise what happened or what went wrong. Check code or the HTTP status, not this text.
data
The result. Absent on errors.
timestamp
Server time in Unix seconds. On a job-creation answer it is the job's creation time as an RFC 3339 string instead, so do not rely on its type.
Lists answer with data set to { items, total, page, pageSize, totalPages }. Projects and samples take page and pageSize; job lists take limit and offset.
Jobs
Creating a plot or analysis job answers HTTP 202 with the job in data. Poll it no more often than every 2 seconds until its status is completed, failed or cancelled, then download the result. By default you can hold 20 unfinished plot jobs and 20 unfinished analysis jobs.
Files and tracing
Figure, table and export endpoints return the file itself, so check the HTTP status before reading the body. Every response from the API server carries an X-Request-ID header; quote it when you report a problem.
Where to call from
Browsers accept API responses only on this site's own pages, so call the API from a script, a notebook or a server rather than from another website.
Authentication
Endpoints marked Token required need the access token in a header. Replace ACCESS_TOKEN with yours:
HTTP header
Authorization: Bearer ACCESS_TOKEN
Access tokens last 15 minutes by default. There are no long-lived API keys.
For a quick test, copy the token from your Profile page. A script should sign in by itself and refresh.
Signing in also sets a refresh_token cookie that lasts 30 days by default. Each refresh replaces it, so keep the newest one.
Accounts with two-factor authentication get a pending_token at sign-in and exchange it, with a code, within 5 minutes.
Signing out ends every session of the account, in browsers as well as scripts.
Rate limits
Limits are token buckets: a burst can go through at once, then requests refill at the listed rate. A refused request gets HTTP 429 with a Retry-After header giving the seconds to wait. Reads such as project lists and job status have no limit of their own. Where one limit covers two routes, they share one budget when the server runs with Redis, and each counts separately without it.
Applies to
Rate
Burst
Counted per
Sign-in, token refresh, registration and password-reset requests
3 per second
6
IP address
Two-factor code checks
1 per second
2
IP address
Gene lookups under /api/genes
30 per second
60
IP address
Plot submissions (POST /api/plot/jobs and /api/plot/generate)
30 per minute
60
user
Analysis submissions (POST /api/analysis/jobs)
10 per minute
20
user
File uploads
20 per minute
40
user, or IP address without a token
Download catalogue listings
60 per minute
120
IP address
Download links (also 120 per minute per IP address)
30 per minute
30
user
Status codes
Status
Meaning
200
Success. The body is the JSON envelope, or a file for downloads.
202
A job was queued. The envelope's code is still 200; poll the job for its result.
400
The request was refused as invalid. message says what was wrong.
401
On sign-in and two-factor checks: wrong credentials or code, so sign in again. Elsewhere: the access token is missing, malformed, expired or revoked, so refresh it or sign in again.
403
The account may not do this, or the file is not openly published.
404
Nothing with that id exists, or it belongs to another account.
408
A plot render took longer than its limit, 30 seconds by default.
409
The resource is in the wrong state: a job not finished yet or already finished, two token refreshes raced, or a download file is waiting to be re-verified.
410
The endpoint or export has been retired or has expired.
413
The upload is larger than the proxy accepts. This one comes as an HTML page, not JSON; the API itself answers 400 for a file over its limit.
429
Too many requests, or too many unfinished jobs. Wait the number of seconds in Retry-After.
500
An unexpected server error. Quote the X-Request-ID response header when you report it.
502
An analysis engine failed while running the request.
503
The service or an engine is busy or unavailable. Retry after the seconds in Retry-After, when present.
30 endpoints
Sign-in and sessions
Sign in to get a short-lived access token. The refresh token arrives as an httpOnly cookie, so keep a cookie jar if your script refreshes.
data is { access_token, token, user }, where token repeats access_token for older clients. The refresh token is set as the refresh_token cookie.
Rate limit
3 per second per IP address, bursts of up to 6.
Notes
An account with two-factor authentication gets { requires_2fa: true, pending_token } instead. Finish with POST /api/auth/2fa/verify.
A 401 here means the username or password is wrong. Do not refresh: fix the credentials.
10 failed attempts for one username or email address, each within 30 minutes of the one before, lock sign-in with it for 15 minutes (429 with Retry-After).
A 401 here means the email address or password is wrong. Do not refresh: fix the credentials.
10 failed attempts for one username or email address, each within 30 minutes of the one before, lock sign-in with it for 15 minutes (429 with Retry-After).
Exchanges the refresh token for a new access token.
Parameters
refresh_tokenstring, cookieSent automatically by a cookie jar. A JSON body { refresh_token } is accepted when no cookie is sent.
Returns
data is { access_token, token }. The refresh token is rotated: a new cookie replaces the old one, which stops working. Refresh tokens last 30 days by default.
Rate limit
3 per second per IP address, bursts of up to 6.
Notes
A 401 means the refresh token is expired or revoked: sign in again.
A 409 means two refreshes raced with the same cookie: retry once.
pageSizeinteger, queryProjects per page. Default 20.
programstring, queryExact program, e.g. TCGA. Omit it, or pass all, for every program.
primary_sitestring, queryExact primary site. Values come from /api/projects/filters.
disease_typestring, queryExact disease type. Values come from /api/projects/filters.
searchstring, querySubstring matched against name, disease type, program and primary site. Case-sensitive: BRCA matches, brca does not.
sortBystring, queryname (default), case_count, file_count or created_at.
sortOrderstring, queryasc (default) or desc.
Returns
data is { items, total, page, pageSize, totalPages }. Each item has id, name, disease_type, primary_site, program, case_count, file_count, description, tissue_type, created_at and updated_at. The identifier is id, e.g. TCGA-BRCA.
idstring, path, requiredA project id, e.g. TCGA-BRCA.
Returns
data has the project fields plus distribution: sample counts by age_region, definition, gender and tissue_type, each an array of { key, sample_count }.
Notes
An unknown id is not a 404: the answer is 200 with empty fields. Check that data.id is not empty.
Lists a project's samples with their clinical fields.
Parameters
idstring, path, requiredA project id, e.g. TCGA-BRCA.
pageinteger, queryPage number. Default 1.
pageSizeinteger, querySamples per page. Default 20, at most 500.
Returns
data is { items, total, page, pageSize, totalPages }. Items are ordered by barcode and carry fields such as barcode, sample_type, tissue_type, gender, vital_status, days_to_death and days_to_last_follow_up.
Notes
An unknown project id answers 404.
Genes
Lookups for gene symbols and Ensembl ids, for building plot and analysis requests.
bodyobject, body, requiredThe same fields as POST /api/plot/jobs, without engine.
Returns
The image bytes, with X-Image-Format and X-Plot-Metadata headers.
Rate limit
30 per minute per user, bursts of up to 60.
Notes
The render is cut off after 30 seconds by default (408). An operator can raise plot.timeout, but not past the route's two minutes. When the engines are busy it answers 503 with code set to the string "PLOT_BUSY", not a number.
Plot jobs give each render the same 30-second limit and retry one that times out; a whole job stops after 5 minutes by default. A busy queue answers 429 at submission instead of 503.
Analysis jobs
PCA, differential expression, survival signatures and single-cell pipelines run as jobs. Sending the same request while your earlier job is queued, running or completed returns that job instead of running it again.
analysisTypestring, body, requiredpca, deseq2, limma, limma_voom, edger, survival or scrna.
projectIdstring, body, requiredA project id from /api/projects, or a fileId from /api/upload.
expressionTypestring, bodyFor TCGA projects with pca or limma: count (default), vstd, tpm or fpkm. deseq2, limma_voom and edger always use count, and survival uses tpm.
pca, deseq2, limma, limmaVoom, edger, survival, scrnaobject, bodyOne options object named after the analysis, e.g. pca: { nComponents: 5 }.
enginestring, bodyr or python, where the analysis runs on both.
Returns (HTTP 202)
data is the job: { id, status, engine, analysis_type, progress, created_at }. data.reused is true when your earlier identical job was returned; after a failed or cancelled job the same request runs again.
Rate limit
10 per minute per user, bursts of up to 20.
Notes
scrna runs on single-cell datasets, not TCGA projects, as a chain of stages: qc starts from a dataset, and each later stage needs a completed parent job.
A 429 with Retry-After also means you already have 20 unfinished analysis jobs, or the queue is full.
idstring, path, requiredThe job id returned when the job was created.
Returns
A success envelope.
Notes
A 409 means the job has already finished.
Uploads
Upload your own table and use its fileId wherever a request takes a projectId. Send a valid token: a missing, expired or revoked one is not refused, so the file is stored anonymously and your jobs cannot use it.
filefile, form, requiredA multipart/form-data field. At most 50 MiB by default.
Returns
data is { fileId, fileName, fileSize, uploadTime, columns }; columns is filled for delimited text such as CSV or TSV. Uploading the same file again returns the existing fileId.
Rate limit
20 per minute per user, or IP address without a token, bursts of up to 40.
Notes
Refresh first if your token may have lapsed: an expired token uploads anonymously.
fileIdstring, path, requiredThe fileId from the upload response.
Returns
A success envelope.
Downloads
The published TCGA files: per-cohort count, TPM and FPKM matrices, sample information and a gene annotation. Listing them is public; asking for a download link needs a token.