> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adaptyvbio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit experiment

> Submits a draft experiment for review. Advances from Draft to
WaitingForConfirmation by finalizing the Stripe quote. To accept an
already-submitted quote, use `POST /experiments/{id}/quote/confirm`.



## OpenAPI

````yaml https://devs.adaptyvbio.com/api/v1/openapi.json post /api/v1/experiments/{experiment_id}/submit
openapi: 3.1.0
info:
  title: Adaptyv Foundry API
  description: >

    The Foundry API enables programmatic access to Adaptyv Bio's protein
    characterization services.


    ## Getting Started


    1. **Obtain an API token** from the [Adaptyv
    Portal](https://foundry.adaptyvbio.com) or by
       contacting Adaptyv directly
    2. **Authenticate requests** using Bearer token in the Authorization header

    3. **Create experiments** to submit protein sequences for characterization

    4. **Monitor status** via webhooks or polling the experiment detail endpoint


    ## Authentication


    All requests require a Bearer token:


    ```

    Authorization: Bearer <your-token>

    ```


    Tokens can be attenuated (restricted) to specific organizations or
    capabilities via the `/tokens` endpoint.


    ## Pagination


    List endpoints support offset-based pagination:


    | Parameter | Description | Default |

    |-----------|-------------|---------|

    | `limit` | Maximum items per page | 50 |

    | `offset` | Number of items to skip | 0 |


    ## Filtering


    Most list endpoints support filtering via query parameters using comparison
    operators:


    - `equ(field)=value` — equals

    - `geq(field)=value` — greater than or equal

    - `gtr(field)=value` — greater than

    - `leq(field)=value` — less than or equal

    - `lss(field)=value` — less than


    Example: `GET /experiments?geq(created_at)=2025-01-01&status=draft`


    ## Environments


    | Environment | Base URL |

    |-------------|----------|

    | Production | `https://foundry-api-public.adaptyvbio.com` |


    ## Support


    - **Email**: support@adaptyvbio.com

    - **Documentation**: [docs.adaptyvbio.com](https://docs.adaptyvbio.com)
  version: 0.0.2
servers:
  - url: https://foundry-api-public.adaptyvbio.com/
    description: Production API (Public)
security:
  - adaptyv_biscuits_v0: []
tags:
  - name: experiments
    description: >

      Experiments are the core resource for submitting protein sequences to
      Adaptyv's characterization services.


      ## Lifecycle


      Experiments progress through these stages:


      1. **Draft** — Initial state for designing your experiment

      2. **In Review** — Submitted for validation and quote generation

      3. **Quote Sent** — Adaptyv has sent a pricing quote

      4. **Waiting for Confirmation** — Quote ready, awaiting acceptance

      5. **In Queue** — Confirmed and queued for lab scheduling

      6. **Waiting for Materials** — Confirmed, waiting for samples

      7. **In Production** — Lab work in progress

      8. **Data Analysis** — Characterization complete, processing results

      9. **Done** — Results available for download


      **Canceled** is a terminal state reachable from Draft, In Review, Waiting
      for Confirmation, or In Queue.


      ## Experiment Types


      | Type | Description | Target Required |

      |------|-------------|-----------------|

      | `screening` | High-throughput binding assessment | Yes |

      | `affinity` | Kinetic characterization (KD, kon, koff) | Yes |

      | `thermostability` | Thermal stability measurement (Tm) | No |

      | `expression` | Expression yield assessment | No |

      | `fluorescence` | Fluorescence-based characterization | No |


      ## Typical Workflow


      ```

      POST /experiments                    # Create experiment

      POST /experiments/cost-estimate      # Preview pricing

      POST /experiments/{id}/submit        # Submit for review

      GET /experiments/{id}/quote          # Retrieve quote when ready

      POST /experiments/{id}/quote/confirm # Accept quote

      GET /experiments/{id}                # Monitor progress

      GET /results?experiment_id={id}      # Retrieve results when done

      ```


      ## Related Resources


      - [Results](#tag/results) — Characterization data from completed
      experiments

      - [Sequences](#tag/sequences) — Individual sequences within experiments

      - [Targets](#tag/targets) — Target proteins for binding experiments
  - name: feedback
    description: >-
      Use this endpoint to give us feedback, report bugs that are not already
      caught by our observability or request features (or have your agents do
      it).
  - name: info
    description: >-
      Programmatic discovery and health probes. Anonymous-eligible liveness and
      database connectivity probes; admin-only assay-type catalog (internal
      builds).
  - name: quotes
    description: >-
      Stripe quote lifecycle: list, retrieve, confirm, and reject quotes for
      experiment pricing.
  - name: results
    description: >

      Results contain the characterization data from completed experiments.


      ## Result Availability


      Results appear when an experiment reaches the **Done** status. Some
      experiment types provide partial results during **Data Analysis**.


      ## Result Types by Experiment


      | Experiment Type | Result Data |

      |-----------------|-------------|

      | Affinity | KD, kon, koff, sensorgrams |

      | Screening | Binding yes/no, response units |

      | Thermostability | Tm values, melting curves |

      | Expression | Yield measurements |


      ## Downloading Results


      Use the result `id` to fetch detailed data. Result downloads may include:


      - Raw sensorgram data

      - Fitted kinetic parameters

      - Quality metrics

      - Summary reports


      ## Related Resources


      - [Experiments](#tag/experiments) — Parent resource that produces results
  - name: sequences
    description: >

      Sequences provide read-only access to protein sequences submitted across
      experiments.


      ## Sequence Format


      Sequences are amino acid strings in standard single-letter IUPAC format
      (e.g., `MKTLLLTLLV...`).


      ## Sequence Properties


      | Field | Description |

      |-------|-------------|

      | `aa_string` | The amino acid sequence |

      | `name` | Optional human-readable identifier |

      | `control` | Whether this is a control sequence |

      | `metadata` | Structural annotations (tag location, antibody type) |


      ## Querying Sequences


      Filter sequences by experiment or other criteria:


      ```

      GET /sequences?experiment_id={id}

      GET /sequences?name=mAb-001

      ```


      ## Related Resources


      - [Experiments](#tag/experiments) — Parent resource containing sequences
  - name: targets
    description: >

      Targets represent the molecules your samples will be tested against in
      binding experiments (affinity and screening).


      ## Target Catalog


      Adaptyv maintains a catalog of pre-validated target proteins with
      established pricing. Use `selfservice_only=true` to filter for targets
      with immediate pricing availability.


      ## Self-Service vs Custom Targets


      | Category | Description | Pricing |

      |----------|-------------|---------|

      | Self-service | Pre-validated catalog targets | Instant quote via cost
      estimate |

      | Custom | User-supplied or special request | Requires manual quote |


      ## Usage


      1. Browse targets with `GET /targets?selfservice_only=true`

      2. Use the target's `id` when creating an experiment

      3. For custom targets, provide a `requested_target` object in the
      experiment request


      ## Related Resources


      - [Experiments](#tag/experiments) — Create experiments using targets

      - [Cost Estimate](#operation/cost_estimate) — Preview pricing for
      self-service targets
  - name: tokens
    description: >

      Create restricted versions of your API token for delegation to team
      members or automated systems.


      ## Token Attenuation


      Attenuation **reduces** the permissions of your token—it cannot grant
      additional access. Attenuated tokens inherit a subset of the parent
      token's capabilities.


      ## Restriction Types


      | Restriction | Effect |

      |-------------|--------|

      | Organization | Limit access to specific organizations |

      | Resource | Limit to specific resource types (experiments, results) |

      | Action | Limit to specific actions (read, create, update) |

      | Expiry | Set a shorter expiration time |


      ## Security Best Practices


      - Create narrowly-scoped tokens for automated systems

      - Use short expiration times for temporary access

      - Revoke tokens promptly when no longer needed
  - name: updates
    description: >-
      Real-time feed of experiment status changes, progress notifications, and
      operational alerts. Supports cursor-based pagination for efficient
      polling.
  - name: whoami
    description: >-
      Identify yourself: the organizations your token can access (with the
      active one marked), your user id, the permissions your token grants, and
      its expiry.
paths:
  /api/v1/experiments/{experiment_id}/submit:
    post:
      tags:
        - experiments
      summary: Submit experiment
      description: |-
        Submits a draft experiment for review. Advances from Draft to
        WaitingForConfirmation by finalizing the Stripe quote. To accept an
        already-submitted quote, use `POST /experiments/{id}/quote/confirm`.
      operationId: submit_experiment
      parameters:
        - name: experiment_id
          in: path
          description: Experiment identifier
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Experiment submitted for review
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExperimentConfirmationResponse'
        '400':
          description: Unknown or inaccessible experiment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Invalid or missing authentication token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Caller does not have access to this experiment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            Experiment cannot transition out of its current state. When a prior
            `POST /experiments` attempted to create a Stripe quote and Stripe
            rejected it, the response includes `error_kind` and `hint` fields
            identifying the failure class (e.g. `customer_quote_cap`). Otherwise
            those fields are omitted (legacy shape).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmitConflictError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ExperimentConfirmationResponse:
      type: object
      description: >-
        Confirmation response returned after a status transition via `POST
        /confirm`.


        The confirm endpoint automatically advances the experiment through its
        lifecycle

        based on the current status. This response reports both the previous and
        new

        status so callers can verify what transition occurred.
      required:
        - experiment_id
        - previous_status
        - status
        - confirmed_at
      properties:
        confirmed_at:
          type: string
          format: date-time
          description: RFC3339 timestamp when confirmation completed
          example: '2026-02-15T14:30:00Z'
        experiment_id:
          type: string
          format: uuid
          description: Experiment identifier
          example: 019462a4-b1c2-7def-8901-23456789abcd
        previous_status:
          $ref: '#/components/schemas/ExperimentStatus'
          description: Status before the transition
        status:
          $ref: '#/components/schemas/ExperimentStatus'
          description: Status after the transition
        stripe_invoice_url:
          type:
            - string
            - 'null'
          description: >-
            Hosted invoice URL from Stripe (available after
            WaitingForConfirmation → WaitingForMaterials)
          example: https://invoice.stripe.com/i/acct_1234/test_5678
    ErrorResponse:
      type: object
      description: >-
        Error response body returned by all endpoints on 4xx/5xx failures.


        Every error response contains a human-readable message and the request
        ID

        for support correlation. The `request_id` is also returned in the

        `x-request-id` response header.
      required:
        - error
        - request_id
      properties:
        error:
          type: string
          description: Human-readable error description.
          example: experiment not found
        request_id:
          type: string
          description: >-
            Request identifier for support correlation (also in `x-request-id`
            header).
          example: req_019462a4-b1c2-7def-8901-23456789abcd
    SubmitConflictError:
      type: object
      description: >-
        409 response body returned by `POST /experiments/{id}/submit` when the

        experiment cannot transition out of its current state.


        Shape:


        | Field | When present | Notes |

        |-------|-------------|-------|

        | `error` | always | human-readable message (same shape as
        `ErrorResponse.error`) |

        | `request_id` | always | correlation id (same shape as
        `ErrorResponse.request_id`) |

        | `error_kind` | only when a prior `POST /experiments` attempted to
        create a Stripe quote and Stripe rejected it | discriminator from
        `QuoteCreationErrorKind` |

        | `hint` | only when `error_kind` is populated | retry / contact
        guidance |


        `error_kind` and `hint` are `null` for 409s unrelated to quote creation

        (e.g. the experiment is already submitted or in a terminal state).
      required:
        - error
        - request_id
      properties:
        error:
          type: string
          description: Human-readable message (matches `ErrorResponse.error`).
          example: 'Cannot submit draft experiment: Stripe quote creation failed.'
        error_kind:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/QuoteCreationErrorKind'
              description: >-
                Classifier of the quote-creation failure, or `null` when the
                conflict

                is unrelated to quote creation.
        hint:
          type:
            - string
            - 'null'
          description: Operator-facing hint corresponding to `error_kind`, or `null`.
          example: >-
            Stripe rejected the quote: this organization's customer has reached
            the draft-quote cap. Contact admin to cancel stale test-mode quotes.
        request_id:
          type: string
          description: Request correlation id (matches `ErrorResponse.request_id`).
          example: req_019462a4-b1c2-7def-8901-23456789abcd
    ExperimentStatus:
      type: string
      description: >-
        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.
      enum:
        - draft
        - waiting_for_confirmation
        - canceled
        - waiting_for_materials
        - in_production
        - quote_sent
        - in_queue
        - data_analysis
        - in_review
        - done
    QuoteCreationErrorKind:
      type: string
      description: >-
        Classification of a Stripe quote-creation failure during experiment
        creation.


        Returned in the `SubmitConflictError` response body on

        `POST /experiments/{id}/submit` so callers can distinguish transient
        failures

        (`rate_limited`, `upstream_server_error`) that are worth retrying from

        permanent ones (`customer_quote_cap`, `missing_customer`,
        `missing_product`)

        that need a different action.
      enum:
        - customer_quote_cap
        - rate_limited
        - upstream_server_error
        - missing_customer
        - missing_product
        - other
  securitySchemes:
    adaptyv_biscuits_v0:
      type: http
      scheme: bearer
      bearerFormat: Adaptyv Biscuits v0
      description: >-
        Biscuit-based bearer token. Obtain tokens from the Adaptyv Portal or via
        the `/tokens` endpoint. Tokens encode organization membership and
        role-based capabilities; the API verifies the token's cryptographic
        signature and authorization claims before processing requests. Use
        `/tokens/attenuate` to create restricted tokens for delegation.

````