---
title: "Get experiment"
method: GET
path: "/api/v1/experiments/{experiment_id}"
tags: ["experiments"]
---

# Get experiment

`GET /api/v1/experiments/{experiment_id}`

## Request

- Base URL: `https://devs.adaptyvbio.com`
- URL: `https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}`
- Auth: HTTP bearer

Returns full metadata for an experiment: workflow status, target and
sequence details, assay parameters, and billing references.

Poll this endpoint to track progress. When `stripe_quote_url` appears,
fetch quote details via `/experiments/{id}/quote`. After confirmation,
`stripe_invoice_url` provides a direct link to the invoice. The `results_status` field
signals data availability: `None` (pending), `Partial` (preliminary),
or `All` (complete). Query `/results` filtered by experiment to retrieve
data once results are available.

## Path parameters

- `experiment_id` string, uuid, required

## Response `200`

Experiment details

- ExpInfo: Detailed information about a specific experiment. Contains all data needed to understand experiment configuration and track progress.
  - `code` string, required: Unique experiment code (e.g., "EXP-2024-001") or request ID if not fulfilled
  - `costs` union: Dynamic cost information for an experiment. Represents the current cost state based on experiment lifecycle: - `Estimate`: Computed from experiment spec (no Stripe quote yet) - `Quoted`: Real quote from Stripe (awaiting acceptance) - `Invoiced`: Invoice created (payment pending or complete) Resolution order: If `stripe_invoice_url` exists, returns `Invoiced`. Otherwise, if `stripe_quote_url` exists, returns `Quoted`. Otherwise computes `Estimate`.
    - object: Computed estimate before Stripe quote generation.
      - `breakdown` CostBreakdown, required: Complete cost breakdown for an experiment. Aggregates assay costs and optional material costs into a total estimate. Used for both cost estimation endpoint responses and dynamic experiment costs. All amounts are in USD cents and **exclude VAT**.
        - `assay` AssayCost, required: Assay cost breakdown for a specific experiment type. # Pricing Formula ```text per_sequence_cost = unit_price + max(0, n_replicates - 1) × replicate_price subtotal = sequence_count × per_sequence_cost ``` The first replicate is included in the base unit price; additional replicates are charged at `replicate_price` each. For experiment types without replicate pricing (e.g., thermostability), `replicate_price_cents` is 0.
          - `experiment_type` string, required: Experiment type (e.g., "screening", "affinity", "thermostability", "fluorescence", "expression")
          - `n_replicates` integer, required: Number of technical replicates
          - `replicate_price_cents` integer, required: Price per additional replicate (beyond first) in USD cents. Zero for experiment types without replicate pricing.
          - `sequence_count` integer, required: Number of sequences in the experiment
          - `subtotal_cents` integer, required: Subtotal for assay costs in USD cents. Calculated as: `sequence_count × (unit_price + max(0, n_replicates - 1) × replicate_price)`
          - `unit_price_cents` integer, required: Base price per sequence in USD cents. Includes the first replicate.
        - `materials` union: Material cost for target antigens, discriminated by pricing model.
          - object: Per-sequence pricing: fixed cost per sequence.
            - `price_per_sequence_cents` integer, required: Price per sequence in USD cents
            - `sequence_count` integer, required: Number of sequences requiring material
            - `subtotal_cents` integer, required: Subtotal: sequence_count * price_per_sequence_cents
            - `target` TargetReference, required: A resolved reference to an experiment's target, as shown in the Foundry Portal. This is the single shape every API response uses to name a target: the experiment spec, result readouts, cost-estimate line items, and the internal minimum-sequence admin config all embed it instead of a bare id string. `name` is always present. `target_catalog_id` is present when the target is a catalog product — fetch its full details from `GET /targets/{target_catalog_id}`; its absence indicates a custom target. `sequence` and `supplier_url` are included when available.
              - …
            - `type` 'per_sequence', required
          - object: Broken-lot pricing: customer pays for one or more full lots. The greedy allocator picks the cheapest combination of vendor lots that covers the required material. Single-lot orders have one entry; larger orders may combine multiple lot sizes.
            - `lots` LotAllocation[], required: Lot allocations covering the order
              - …
            - `sequence_count` integer, required: Number of sequences in the experiment
            - `subtotal_cents` integer, required: Total material cost in USD cents (sum of lot_price_cents × quantity)
            - `target` TargetReference, required: A resolved reference to an experiment's target, as shown in the Foundry Portal. This is the single shape every API response uses to name a target: the experiment spec, result readouts, cost-estimate line items, and the internal minimum-sequence admin config all embed it instead of a bare id string. `name` is always present. `target_catalog_id` is present when the target is a catalog product — fetch its full details from `GET /targets/{target_catalog_id}`; its absence indicates a custom target. `sequence` and `supplier_url` are included when available.
              - …
            - `type` 'per_broken_lot', required
        - `pricing_version` string, required
        - `total_cents` integer, required: Total estimated cost in USD cents
      - `type` 'estimate', required
    - object: Partial estimate when materials pricing is unavailable. Returned when the experiment references a target that lacks self-service pricing. Assay costs are always calculable, but the total cannot be determined without material pricing.
      - `assay` AssayCost, required: Assay cost breakdown for a specific experiment type. # Pricing Formula ```text per_sequence_cost = unit_price + max(0, n_replicates - 1) × replicate_price subtotal = sequence_count × per_sequence_cost ``` The first replicate is included in the base unit price; additional replicates are charged at `replicate_price` each. For experiment types without replicate pricing (e.g., thermostability), `replicate_price_cents` is 0.
        - `experiment_type` string, required: Experiment type (e.g., "screening", "affinity", "thermostability", "fluorescence", "expression")
        - `n_replicates` integer, required: Number of technical replicates
        - `replicate_price_cents` integer, required: Price per additional replicate (beyond first) in USD cents. Zero for experiment types without replicate pricing.
        - `sequence_count` integer, required: Number of sequences in the experiment
        - `subtotal_cents` integer, required: Subtotal for assay costs in USD cents. Calculated as: `sequence_count × (unit_price + max(0, n_replicates - 1) × replicate_price)`
        - `unit_price_cents` integer, required: Base price per sequence in USD cents. Includes the first replicate.
      - `materials_unavailable` MaterialsUnavailable, required: Explains why materials pricing is unavailable for a target. Returned as part of an incomplete cost estimate when the target is not configured for self-service pricing.
        - `reason` string, required: Human-readable explanation for why pricing is unavailable
        - `target` TargetReference, required: A resolved reference to an experiment's target, as shown in the Foundry Portal. This is the single shape every API response uses to name a target: the experiment spec, result readouts, cost-estimate line items, and the internal minimum-sequence admin config all embed it instead of a bare id string. `name` is always present. `target_catalog_id` is present when the target is a catalog product — fetch its full details from `GET /targets/{target_catalog_id}`; its absence indicates a custom target. `sequence` and `supplier_url` are included when available.
          - `name` string, required: The target's display name, as shown in the Foundry Portal.
          - `sequence` string, nullable: The target's amino-acid sequence, when available.
          - `supplier_url` string, nullable: Link to the target's vendor product page, when available.
          - `target_catalog_id` string, uuid, nullable: Identifier of the matching catalog product, when the target is in the catalog; absent for custom targets. Resolve full details via `GET /targets/{target_catalog_id}`.
      - `pricing_version` string, required
      - `total_cents` unknown, required
      - `type` 'incomplete_estimate', required
    - object: Stripe quote has been generated.
      - `amount_cents` integer, required: Quote amount in smallest currency unit (cents)
      - `currency` string, required: Currency code (ISO 4217)
      - `expires_at` string, date-time, nullable: Quote expiration timestamp (ISO 8601). Omitted if the quote has no expiration.
      - `status` 'draft' | 'open' | 'accepted' | 'canceled' | 'stale', required: Quote status from Stripe's API.
      - `stripe_quote_url` string, required: Direct link to the quote in the Stripe Dashboard
      - `type` 'quoted', required
    - object: Stripe invoice has been created.
      - `amount_cents` integer, required: Invoice amount in smallest currency unit (cents)
      - `currency` string, required: Currency code (ISO 4217)
      - `status` 'draft' | 'open' | 'paid' | 'void' | 'uncollectible', required: Invoice status from Stripe's API.
      - `stripe_invoice_url` string, nullable: Hosted invoice payment URL from Stripe. Omitted if not available (e.g., draft invoices).
      - `type` 'invoiced', required
  - `created_at` string, date-time, required: ISO 8601 timestamp of experiment creation
  - `experiment_spec` ExperimentSpecInfo, required: An experiment's specification, as returned by `GET /experiments/{id}`: the assay type and method, the sequences under test, the replicate plan, and the resolved `target`.
    - `antigen_concentrations` number[], nullable: Antigen concentrations to test (in nanoMolar)
    - `experiment_type` 'affinity' | 'screening' | 'thermostability' | 'fluorescence' | 'expression' | 'epitope_binning' | 'enzyme_activity', required: Experiment type determining the assay workflow.
    - `method` 'bli' | 'spr': The measurement method (BLI or SPR). Required for affinity and screening; must be omitted for all other types.
    - `n_replicates` integer, nullable: Number of technical replicates (minimum 1, recommended 3+)
    - `parameters` object, nullable: Advanced experiment-specific settings. Most experiments leave this null. When provided, the object round-trips through the experiment detail with one addition: the read path merges the `experiment_type` discriminator into it, so a submitted `{"note":"x"}` reads back as `{"experiment_type":"...","note":"x"}`. A user-supplied `experiment_type` key is preserved as-is — the discriminator is only inserted when absent.
    - `sequences` object: Sequences keyed by a human readable name. Accepts either simple amino acid strings or rich objects with control flags and metadata.
    - `target` TargetReference: A resolved reference to an experiment's target, as shown in the Foundry Portal. This is the single shape every API response uses to name a target: the experiment spec, result readouts, cost-estimate line items, and the internal minimum-sequence admin config all embed it instead of a bare id string. `name` is always present. `target_catalog_id` is present when the target is a catalog product — fetch its full details from `GET /targets/{target_catalog_id}`; its absence indicates a custom target. `sequence` and `supplier_url` are included when available.
      - `name` string, required: The target's display name, as shown in the Foundry Portal.
      - `sequence` string, nullable: The target's amino-acid sequence, when available.
      - `supplier_url` string, nullable: Link to the target's vendor product page, when available.
      - `target_catalog_id` string, uuid, nullable: Identifier of the matching catalog product, when the target is in the catalog; absent for custom targets. Resolve full details via `GET /targets/{target_catalog_id}`.
  - `experiment_url` string, required: URL to view the experiment in the Foundry portal
  - `id` string, uuid, required: Unique identifier for the experiment
  - `name` string, nullable: Human-readable name for the experiment (nullable in database)
  - `results_status` 'none' | 'partial' | 'all', required: Indicates the availability of results for an experiment.
  - `status` 'draft' | 'waiting_for_confirmation' | 'canceled' | 'waiting_for_materials' | 'in_production' | 'quote_sent' | 'in_queue' | 'data_analysis' | 'in_review' | 'done', required: Current lifecycle stage of an experiment. Status values indicate where an experiment is in the submission-to-results pipeline. Some transitions require user action (such as accepting a quote), while others occur automatically as work progresses.
  - `stripe_invoice_url` string, nullable: URL to view/pay invoice
  - `stripe_quote_id` string, nullable: Stripe quote identifier (e.g. `qt_1Abc2Def`), when a quote exists. Exposed so integrations can call the `/quotes/{quote_id}` family of endpoints without parsing the ID out of `stripe_quote_url`. Tracks the upstream Stripe quote; changes if the quote is regenerated (rare).
  - `stripe_quote_url` string, nullable: URL to view quote in payment provider dashboard

## Other responses

- `401`: Invalid or missing authentication token
- `404`: Experiment not found or access denied
- `500`: Internal server error

---

[API](https://skmtc.dev/adaptyvbio/apis/adaptyv-foundry-api.md) - [All operations](https://skmtc.dev/adaptyvbio/apis/adaptyv-foundry-api/llms.txt) - [OpenAPI document](https://skmtc.dev/adaptyvbio/apis/adaptyv-foundry-api/revisions/5a2228f4bd59?raw)
