Base URL: https://foundry-api-public.adaptyvbio.com/api/v1
OpenAPI spec: GET /openapi.json
Creates a new experiment. Starts in Draft status by default.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Human-readable name |
experiment_spec |
ExperimentSpec | Yes | Experiment definition (see below) |
skip_draft |
boolean | No (default false) | Bypass Draft, go straight to WaitingForConfirmation |
auto_accept_quote |
boolean | No (default false) | Auto-accept quote and create invoice |
webhook_url |
string/null | No | URL for status-change POST notifications |
ExperimentSpec:
| Field | Type | Required | Description |
|---|---|---|---|
experiment_type |
string | Yes | affinity, screening, thermostability, fluorescence, or expression |
method |
string | Required for binding types | bli or spr |
target_id |
uuid | Required for binding types | Target UUID from catalog |
sequences |
object | Yes | Map of name → amino acid string or rich object |
n_replicates |
integer | Recommended (default 3) | Technical replicates (min 1) |
antigen_concentrations |
number[] | No (affinity only) | Defaults to [1000.0, 316.2, 100.0, 31.6, 0.0] nM |
parameters |
object | No | Experiment-specific settings |
Field requirements by experiment type:
| Field | Affinity | Screening | Thermostability | Fluorescence | Expression |
|---|---|---|---|---|---|
experiment_type |
required | required | required | required | required |
method |
required | required | — | — | — |
target_id |
required | required | — | — | — |
sequences |
required | required | required | required | required |
n_replicates |
recommended | recommended | optional | optional | optional |
antigen_concentrations |
optional | — | — | — | — |
Response (201):
| Field | Type | Description |
|---|---|---|
experiment_id |
string | UUID of new experiment |
error |
string/null | Error message if validation fails |
stripe_hosted_invoice_url |
string/null | Present when auto_accept_quote created an invoice |
stripe_invoice_id |
string/null | Stripe invoice ID |
Status codes: 201, 400, 401, 403, 404
Lists experiments accessible to caller, sorted by creation date (newest first).
Query params: limit, offset, filter, search, sort
Response item:
| Field | Type | Description |
|---|---|---|
id |
uuid | Unique identifier |
code |
string | e.g., "EXP-2024-001" |
name |
string/null | Human-readable name |
status |
ExperimentStatus | Current lifecycle status |
experiment_type |
ExperimentType | affinity/screening/thermostability/fluorescence/expression |
results_status |
ResultsStatus | none/partial/all |
created_at |
datetime | ISO 8601 |
experiment_url |
string | URL to Foundry portal |
stripe_invoice_url |
string/null | Invoice URL |
stripe_quote_url |
string/null | Quote URL |
Status codes: 200, 401
Returns full metadata for a single experiment.
Path param: experiment_id (uuid)
Response:
| Field | Type | Description |
|---|---|---|
id |
uuid | Unique identifier |
code |
string | Experiment code |
status |
ExperimentStatus | Current status |
experiment_spec |
ExperimentSpec | Full experiment definition |
results_status |
ResultsStatus | none/partial/all |
created_at |
datetime | ISO 8601 |
experiment_url |
string | Portal URL |
costs |
object | Cost breakdown |
Status codes: 200, 401, 404, 500
Modify an existing experiment. Draft experiments allow full edits; after quote generation, only name, description, and webhook_url are editable.
Path param: experiment_id (uuid)
Request body: All fields optional — only provided fields are updated.
Status codes: 200, 400, 401, 404, 409
Submits a draft experiment for review. Advances from Draft to WaitingForConfirmation.
Path param: experiment_id (uuid)
Response:
| Field | Type | Description |
|---|---|---|
experiment_id |
string | Experiment UUID |
Status codes: 200, 401, 403, 404, 409, 500
Calculates cost without creating an experiment.
Request body:
{
"experiment_spec": {
"experiment_type": "screening",
"method": "bli",
"target_id": "...",
"sequences": {"seq1": "MKTL..."},
"n_replicates": 3
}
}
Response:
| Field | Type | Description |
|---|---|---|
pricing_version |
string | e.g., "v1_2026-01-20" |
assay |
object | Per-type costs with base and replicate pricing |
materials |
object | Target material costs (binding experiments) |
total_cents |
integer | Sum in USD cents |
All prices exclude VAT; taxes calculated at invoicing. Targets without self-service pricing return incomplete estimates.
Status codes: 200, 400, 401
Returns quote metadata (totals, currency, status, expiration).
Path param: experiment_id (uuid)
Response:
| Field | Type | Description |
|---|---|---|
experiment_id |
string | Experiment UUID |
stripe_quote_url |
string | Stripe quote URL |
amount_total |
int64 | Total in smallest currency unit |
amount_subtotal |
int64 | Subtotal |
currency |
string | ISO currency code (e.g., "usd") |
status |
string | Quote status |
expires_at |
datetime/null | Expiration time |
Status codes: 200, 401, 403, 404, 500
Returns the quote as a PDF file (application/pdf).
Path param: experiment_id (uuid)
Status codes: 200, 401, 403, 404, 500
Accepts Stripe quote, creates draft invoice, transitions to WaitingForMaterials.
Path param: experiment_id (uuid)
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
purchase_order_number |
string/null | No | PO number for your records |
notes |
string/null | No | Reserved |
Response:
| Field | Type | Description |
|---|---|---|
id |
string | Quote ID |
status |
StripeQuoteStatus | New status |
hosted_invoice_url |
string/null | Stripe payment URL |
invoice_id |
string/null | Generated invoice ID |
Status codes: 200, 401, 403, 404, 409
Returns invoice metadata including hosted payment URL.
Path param: experiment_id (uuid)
Status codes: 200, 401, 403, 404, 500
Returns all analysis results for a specific experiment.
Path param: experiment_id (uuid)
Query params: limit, offset, filter, sort
Status codes: 200, 400, 401, 403, 404
Returns all sequences for a specific experiment, sorted newest first.
Path param: experiment_id (uuid)
Query params: limit, offset, search, sort
Status codes: 200, 400, 401, 403, 404
Returns updates for one experiment, oldest first. Types: status_change, progress, error.
Path param: experiment_id (uuid)
Query params: limit, offset, filter, sort
Filter example: filter=eq(type,status_change)
Returns sequences from all experiments, sorted newest first.
Query params: limit, offset, search, sort, experiment_id (filter by experiment UUID)
Response item:
| Field | Type | Description |
|---|---|---|
id |
uuid | Unique identifier |
name |
string/null | Optional name |
aa_preview |
string/null | Truncated preview (first 50 chars) |
length |
int32 | Sequence length in amino acids |
experiment_id |
uuid | Parent experiment |
experiment_code |
string | Human-readable experiment code |
is_control |
boolean | Whether this is a control |
created_at |
datetime | Creation timestamp |
Status codes: 200, 401
Returns full details including complete amino acid string.
Path param: sequence_id (uuid)
Response:
| Field | Type | Description |
|---|---|---|
id |
uuid | Unique identifier |
aa_string |
string/null | Complete amino acid sequence |
length |
int32 | Length in amino acids |
is_control |
boolean | Control flag |
metadata |
object | Sequence-level annotations |
experiment |
object | Parent experiment reference |
created_at |
datetime | Creation timestamp |
Status codes: 200, 401, 403, 404, 500
Appends sequences to a Draft experiment identified by its human-readable code.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
experiment_code |
string | Yes | e.g., "PROJ-001" |
sequences |
array | Yes | Array of sequence entries |
Each sequence entry:
| Field | Type | Required | Description |
|---|---|---|---|
aa_string |
string | Yes | Amino acid sequence |
name |
string | No | Human-readable name |
control |
boolean | No | Whether this is a control |
metadata |
object | No | Annotations |
Response (201):
| Field | Type | Description |
|---|---|---|
added_count |
int32 | Number of sequences added |
experiment_id |
string | Experiment UUID |
experiment_code |
string | Experiment code |
sequence_ids |
array | IDs of added sequences |
Status codes: 201, 400, 404, 409 (experiment not in Draft), 500
Lists completed analysis results, sorted newest first. Results appear when results_status reaches partial or all.
Query params: limit, offset, filter, search, sort
Response item:
| Field | Type | Description |
|---|---|---|
id |
uuid | Result identifier |
title |
string | Human-readable title |
experiment_id |
uuid | Associated experiment |
result_type |
string | e.g., "affinity", "thermostability" |
summary |
array | Key results (type-specific, see below) |
metadata |
object | Extended metadata (e.g., instrument info) |
data_package_url |
string/null | Download URL for raw data package |
created_at |
datetime | When result was generated |
AffinityResult summary fields: kd_mean, kd_std, kon_mean, kon_log_std, koff_mean, koff_std, replicates (array with per-replicate kd, kon, koff, binding_strength, kon_method, koff_method, replicate index), sequence, target_id
ThermostabilityResult summary fields: Tm values and melting curves
Status codes: 200, 401
Returns detailed result data including full summary array.
Path param: result_id (uuid)
Status codes: 200, 401, 403, 404, 500
Lists validated antigens available for experiments.
Query params:
| Parameter | Type | Description |
|---|---|---|
limit |
int | Max items (1-100, default 50) |
offset |
int | Skip count |
search |
string | Free-text search on product name |
sort |
string | Sort expression |
selfservice_only |
boolean | Only targets with self-service pricing |
show_conjugated |
boolean | Include conjugated targets (default: unconjugated only) |
detailed |
boolean | Populate details block with enrichment data |
Response item:
| Field | Type | Description |
|---|---|---|
id |
uuid | Target UUID (use as experiment_spec.target_id) |
name |
string | Target name |
vendor_name |
string | Vendor name |
catalog_number |
string | Vendor catalog/SKU number |
url |
string | Target URL |
pricing |
object/null | Self-service pricing (null = custom quote required) |
details |
object/null | Enrichment data (gene names, structures, sequence, bioactivity) |
Status codes: 200, 401
Returns catalog record for a single target.
Path param: target_id (uuid)
Status codes: 200, 400, 401, 403, 404, 500
Submit a new custom target for staff review. At least one of sequence or pdb_id must be provided.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display name |
product_id |
string | Yes | Must be unique within organization |
sequence |
string/null | At least one | Amino acid sequence |
pdb_id |
string/null | At least one | PDB identifier |
pdb_file |
string/null | No | PDB file content |
molecular_weight |
number/null | No | Weight in kDa |
note |
string/null | No | Additional notes |
Status codes: 201, 400, 401, 403, 500
Returns custom target requests for your organization, sorted newest first.
Query params: limit, offset, filter, sort
Filter example: filter=eq(status,pending_review)
Path param: request_id (uuid)
Response:
| Field | Type | Description |
|---|---|---|
id |
uuid | Request identifier |
name |
string | Target name |
product_id |
string | Your product ID |
status |
string | e.g., "pending_review" |
material_id |
string/null | Linked catalog ID if approved |
molecular_weight |
number/null | Weight in kDa |
note |
string/null | User notes |
created_at |
datetime | Created |
updated_at |
datetime | Last updated |
Status codes: 200, 401, 403, 404, 500
Returns all quotes for caller's organization.
Query params: limit, offset, filter, sort
Response item:
| Field | Type | Description |
|---|---|---|
id |
string | Quote identifier |
quote_number |
string | Human-readable quote number |
organization_id |
uuid | Organization |
amount_cents |
int | Amount in cents |
currency |
string | ISO 4217 code |
status |
StripeQuoteStatus | Quote status |
valid_until |
datetime | Expiration |
created_at |
datetime | Creation timestamp |
Returns full quote document with itemized pricing.
Path param: quote_id (string, e.g., "qt_1Abc2DefGhi")
Response:
| Field | Type | Description |
|---|---|---|
id |
string | Quote identifier |
quote_number |
string | Reference number |
organization_id |
uuid | Organization |
organization_name |
string | Organization name |
line_items |
array | Itemized pricing |
subtotal_cents |
int | Subtotal in cents |
tax_cents |
int | Tax in cents |
total_cents |
int | Total in cents |
currency |
string | ISO 4217 |
status |
StripeQuoteStatus | Current status |
valid_until |
datetime | Expiration |
notes |
string | Special pricing info |
terms_and_conditions |
string | Terms |
stripe_quote_url |
string | Stripe URL |
created_at |
datetime | Created |
Status codes: 200, 401, 403, 404, 500
Finalizes quote, creates draft invoice, advances experiment to WaitingForMaterials.
Path param: quote_id (string)
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
purchase_order_number |
string/null | No | PO number |
notes |
string/null | No | Reserved |
Response: id, status, hosted_invoice_url, invoice_id
Status codes: 200, 403, 404, 409, 500
Cancels quote; linked experiment reverts to Draft.
Path param: quote_id (string)
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
reason |
QuoteRejectionReason | Yes | Primary reason |
feedback |
string/null | No | Additional feedback |
Response: id, status (canceled)
Status codes: 200, 403, 404, 409, 500
Returns all tokens (root and attenuated) the caller owns.
Query params: limit, offset
Response item:
| Field | Type | Description |
|---|---|---|
id |
string | Token identifier |
name |
string | Human-readable label |
kind |
string | "root" or "attenuated" |
created_at |
datetime | Created |
expires_at |
datetime/null | Expiration (null = no expiry) |
revoked_at |
datetime/null | Revocation timestamp |
parent_token_id |
string/null | Parent (null for root) |
root_token_id |
string/null | Root of derivation tree |
attenuation_spec |
object/null | Restrictions (null for root) |
Creates a restricted version of an existing token using Biscuit cryptographic attenuation.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
token |
string | Yes | Existing token (abs0_{slug}{biscuit_base64}) |
attenuation |
AttenuationSpec | Yes | Restrictions to apply |
name |
string | Yes | Human-readable label |
attenuated_parent_token_id |
uuid/null | No | Parent ID for chained attenuation |
Restriction types: Organization, Resource (experiments/results), Action (read/create/update), Expiry
Response (201): id (database ID), token (new attenuated token string)
Status codes: 201, 400, 401, 403
Revokes the calling token's root and all attenuated descendants. Idempotent.
Response:
| Field | Type | Description |
|---|---|---|
token_id |
string | Root token ID revoked |
revoked_at |
datetime | Revocation timestamp |
children_revoked |
int64 | Child tokens newly revoked |
Status codes: 200, 403, 404
Returns the experiment update feed (newest first): status changes, progress, errors.
Query params: limit, offset, filter, sort
Filter examples:
- filter=eq(experiment_id,<uuid>)
- filter=in(experiment_id,uuid1,uuid2)
- filter=eq(type,status_change)
Response item:
| Field | Type | Description |
|---|---|---|
id |
string | Update identifier |
experiment_id |
uuid | Associated experiment |
experiment_code |
string | Human-readable code |
name |
string | Update description |
timestamp |
datetime | When the update occurred |
For bug reports, feature requests, or general feedback.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
request_uuid |
uuid | Yes | UUID from the problematic API request |
feedback_type |
FeedbackType | Yes | feature_request, feedback, or bug_report |
title |
string/null | No | Short title |
json_body |
object/null | At least one | Structured error details |
human_note |
string/null | At least one | Free-form description |
Response (201): reference (feedback reference), message (confirmation)
Status codes: 201, 400, 401, 500