> ## 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.

# Estimate experiment cost

> Calculates the estimated cost for an experiment without creating it.
Useful for previewing costs before submission.

# Request Body

Accepts an `experiment_spec` matching the creation endpoint format:

```json
{
  "experiment_spec": {
    "experiment_type": "screening",
    "method": "bli",
    "target_id": "019a03da-b87f-7e15-8b02-cef171c9871d",
    "sequences": {
      "seq1": "MKTL...",
      "seq2": "EVQL..."
    },
    "n_replicates": 3
  }
}
```

# Response

Returns a detailed cost breakdown including:
- `pricing_version`: The pricing rules applied (e.g., "v1_2026-01-20")
- `assay`: Per-experiment-type costs with base and replicate pricing
- `materials`: Target material costs (for binding experiments)
- `total_cents`: Sum of all costs in USD cents

# Complete Estimate Response

When the target has self-service pricing:
```json
{
  "breakdown": {
    "pricing_version": "v1_2026-01-20",
    "assay": { "name": "screening", "base_cents": 14900, "replicate_addon_cents": 5800, "subtotal_cents": 103500 },
    "materials": { "target": { "name": "Human PD-L1", "target_catalog_id": "019a03da-b87f-7e15-8b02-cef171c9871d" }, "price_per_sequence_cents": 500, "subtotal_cents": 2500 },
    "total_cents": 106000
  },
  "incomplete": null,
  "warnings": []
}
```

# Incomplete Estimate Response

When the target lacks self-service pricing (e.g., custom proteins), you'll
receive an incomplete estimate with assay costs but `materials_unavailable`:
```json
{
  "breakdown": null,
  "incomplete": {
    "pricing_version": "v1_2026-01-20",
    "assay": { "name": "screening", "base_cents": 14900, "replicate_addon_cents": 5800, "subtotal_cents": 103500 },
    "materials_unavailable": {
      "target": { "name": "This target", "target_catalog_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" },
      "reason": "This target is not yet onboarded to self-service pricing. You'll receive a quote with full price information."
    }
  },
  "warnings": []
}
```

Use `GET /targets?selfservice_only=true` to list targets with complete pricing.

# Notes

- **All prices exclude VAT**; taxes calculated at invoicing based on jurisdiction
- Requires authentication with experiment read permission
- Does not create an experiment
- Pricing is based on the current date (not a future experiment date)
- Targets without self-service pricing return incomplete estimates (not errors)
- Experiments created before pricing v1 (2026-01-20) cannot be estimated



## OpenAPI

````yaml https://devs.adaptyvbio.com/api/v1/openapi.json post /api/v1/experiments/cost-estimate
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://devs.adaptyvbio.com` |


    ## Support


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

    - **Documentation**: [docs.adaptyvbio.com](https://docs.adaptyvbio.com)
  version: 0.0.2
servers:
  - url: https://devs.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/cost-estimate:
    post:
      tags:
        - experiments
      summary: Estimate experiment cost
      description: >-
        Calculates the estimated cost for an experiment without creating it.

        Useful for previewing costs before submission.


        # Request Body


        Accepts an `experiment_spec` matching the creation endpoint format:


        ```json

        {
          "experiment_spec": {
            "experiment_type": "screening",
            "method": "bli",
            "target_id": "019a03da-b87f-7e15-8b02-cef171c9871d",
            "sequences": {
              "seq1": "MKTL...",
              "seq2": "EVQL..."
            },
            "n_replicates": 3
          }
        }

        ```


        # Response


        Returns a detailed cost breakdown including:

        - `pricing_version`: The pricing rules applied (e.g., "v1_2026-01-20")

        - `assay`: Per-experiment-type costs with base and replicate pricing

        - `materials`: Target material costs (for binding experiments)

        - `total_cents`: Sum of all costs in USD cents


        # Complete Estimate Response


        When the target has self-service pricing:

        ```json

        {
          "breakdown": {
            "pricing_version": "v1_2026-01-20",
            "assay": { "name": "screening", "base_cents": 14900, "replicate_addon_cents": 5800, "subtotal_cents": 103500 },
            "materials": { "target": { "name": "Human PD-L1", "target_catalog_id": "019a03da-b87f-7e15-8b02-cef171c9871d" }, "price_per_sequence_cents": 500, "subtotal_cents": 2500 },
            "total_cents": 106000
          },
          "incomplete": null,
          "warnings": []
        }

        ```


        # Incomplete Estimate Response


        When the target lacks self-service pricing (e.g., custom proteins),
        you'll

        receive an incomplete estimate with assay costs but
        `materials_unavailable`:

        ```json

        {
          "breakdown": null,
          "incomplete": {
            "pricing_version": "v1_2026-01-20",
            "assay": { "name": "screening", "base_cents": 14900, "replicate_addon_cents": 5800, "subtotal_cents": 103500 },
            "materials_unavailable": {
              "target": { "name": "This target", "target_catalog_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" },
              "reason": "This target is not yet onboarded to self-service pricing. You'll receive a quote with full price information."
            }
          },
          "warnings": []
        }

        ```


        Use `GET /targets?selfservice_only=true` to list targets with complete
        pricing.


        # Notes


        - **All prices exclude VAT**; taxes calculated at invoicing based on
        jurisdiction

        - Requires authentication with experiment read permission

        - Does not create an experiment

        - Pricing is based on the current date (not a future experiment date)

        - Targets without self-service pricing return incomplete estimates (not
        errors)

        - Experiments created before pricing v1 (2026-01-20) cannot be estimated
      operationId: cost_estimate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CostEstimateRequest'
        required: true
      responses:
        '200':
          description: Cost estimate calculated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CostEstimateResponse'
        '400':
          description: Invalid experiment specification
          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: Insufficient permissions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Pricing unavailable (unknown target or pre-v1 date)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    CostEstimateRequest:
      type: object
      description: |-
        Request payload for cost estimation.

        Contains the same experiment specification fields as creation,
        but does not require a name or project association.

        # Example

        ```json
        {
          "experiment_spec": {
            "experiment_type": "screening",
            "method": "bli",
            "target_id": "019a03da-b87f-7e15-8b02-cef171c9871d",
            "sequences": {
              "seq1": "EVQLVESGGGLVQPGGSLRLSCAASGFTFS...",
              "seq2": "MKTLVLLALLVGAALA..."
            },
            "n_replicates": 3
          }
        }
        ```
      required:
        - experiment_spec
      properties:
        experiment_spec:
          $ref: '#/components/schemas/ExperimentSpec'
          description: >-
            Experiment specification for cost calculation (see ExperimentSpec
            for field details)
    CostEstimateResponse:
      type: object
      description: >-
        Response wrapper for cost estimation endpoint.


        Contains either a complete breakdown (when all pricing is available) or
        an

        incomplete estimate (when target lacks self-service pricing).
      properties:
        breakdown:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/CostBreakdown'
              description: >-
                Detailed cost breakdown. Present when pricing is fully
                available.
        incomplete:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/IncompleteCostEstimate'
              description: >-
                Partial estimate. Present when target lacks self-service
                pricing.
        warnings:
          type: array
          items:
            type: string
          description: >-
            Warnings about the estimate (e.g., unknown target, pricing
            limitations)
    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
    ExperimentSpec:
      allOf:
        - $ref: '#/components/schemas/ExperimentSpecCommon'
        - type: object
          properties:
            target_id:
              type:
                - string
                - 'null'
              format: uuid
              description: >-
                UUID of the target antigen from the catalog, required when
                creating

                binding experiments (affinity, screening, epitope binning); only
                catalog

                targets can be specified. On the experiment read response the
                resolved

                target is returned as `target` (see `target.target_catalog_id`).
              example: 019a03da-b87f-7e15-8b02-cef171c9871d
      description: >-
        Request body for creating an experiment (`POST /experiments`).


        Required fields differ by experiment type. The matrix below is the

        authoritative contract; submissions that violate it are rejected with a
        400

        listing every problem at once.


        * `required` — must be set.

        * `rejected` — must not be set for this type.

        * `optional` / `≥1` / ranges — accepted as stated; the noted default
        applies
          when omitted.

        | Field                         | Affinity   | Screening |
        Thermostability | Fluorescence | Expression | EpitopeBinning           
        | EnzymeActivity |

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

        | `experiment_type`             | required   | required  |
        required        | required     | required   | required                 
        | required       |

        | `method` (`bli` \| `spr`)     | required   | required  |
        rejected        | rejected     | rejected   | rejected                 
        | rejected       |

        | `target_id` (UUID)            | required   | required  |
        rejected        | rejected     | rejected   | required                 
        | rejected       |

        | `sequences`                   | ≥1         | ≥1        |
        ≥1              | ≥1           | ≥1         | multiple of 4, range 4–28
        | ≥1             |

        | `n_replicates`                | optional   | optional  |
        optional        | optional     | optional   | rejected                 
        | optional       |

        | `antigen_concentrations`      | default `[1000.0, 316.2, 100.0, 31.6,
        0.0]` nM | — | — | — | — | — | — |

        | `parameters` (free-form JSON) | optional   | optional  |
        optional        | optional     | optional   | optional                 
        | optional       |


        # Example


        ```json

        {
          "experiment_type": "screening",
          "method": "bli",
          "target_id": "019a03da-b87f-7e15-8b02-cef171c9871d",
          "sequences": {
            "mAb1": "EVQLVESGGGLVQPGGSLRLSCAASGFTFS...",
            "control": {"aa_string": "MKTLVLLALLV...", "control": true}
          },
          "n_replicates": 3
        }

        ```
    CostBreakdown:
      type: object
      description: >-
        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**.
      required:
        - pricing_version
        - assay
        - total_cents
      properties:
        assay:
          $ref: '#/components/schemas/AssayCost'
          description: Assay-related costs
        materials:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/MaterialCost'
              description: >-
                Material costs for target antigens.


                Present only for binding experiments (screening, affinity) that
                have an

                associated target. Non-binding experiments (thermostability,
                fluorescence,

                expression) do not incur material costs and this field is
                omitted.
        pricing_version:
          $ref: '#/components/schemas/String'
          description: Pricing version applied (e.g., "v1_2026-01-20")
        total_cents:
          type: integer
          format: int64
          description: Total estimated cost in USD cents
          example: 106000
    IncompleteCostEstimate:
      type: object
      description: |-
        Partial cost estimate when materials pricing is unavailable.

        Used in the `incomplete` field of `CostEstimateResponse` when the target
        is not configured for self-service pricing.
      required:
        - pricing_version
        - assay
        - materials_unavailable
        - total_cents
      properties:
        assay:
          $ref: '#/components/schemas/AssayCost'
          description: Assay costs (always calculable)
        materials_unavailable:
          $ref: '#/components/schemas/MaterialsUnavailable'
          description: Explanation for missing materials pricing
        pricing_version:
          $ref: '#/components/schemas/String'
          description: Pricing version applied (e.g., "v1_2026-01-20")
        total_cents:
          default: null
    ExperimentSpecCommon:
      type: object
      description: >-
        Fields an experiment carries on both create and read: the assay type and

        method, the sequences under test, the replicate plan, and optional
        parameters.
      required:
        - experiment_type
      properties:
        antigen_concentrations:
          type:
            - array
            - 'null'
          items:
            type: number
            format: double
          description: Antigen concentrations to test (in nanoMolar)
          example:
            - 1000
            - 316.2
            - 100
            - 31.6
            - 0
        experiment_type:
          $ref: '#/components/schemas/ExperimentType'
          description: >-
            Assay type: `affinity`, `screening`, `thermostability`,
            `fluorescence`, `expression`, `epitope_binning`, or
            `enzyme_activity`
        method:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/Method'
              description: >-
                Measurement method (BLI or SPR). Required for binding types
                (affinity,

                screening); omitting it for those types is an error. Absent in

                requests and responses for non-binding types (thermostability,

                fluorescence, expression).
        n_replicates:
          type:
            - integer
            - 'null'
          format: int32
          description: Number of technical replicates (minimum 1, recommended 3+)
          example: 3
          minimum: 0
        parameters:
          type:
            - object
            - 'null'
          description: >-
            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:
          type: object
          description: >-
            Sequences keyed by a human readable name. Accepts either simple
            amino acid strings

            or rich objects with control flags and metadata.
          additionalProperties:
            $ref: '#/components/schemas/SequenceValue'
          propertyNames:
            type: string
    AssayCost:
      type: object
      description: >-
        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.
      required:
        - experiment_type
        - sequence_count
        - n_replicates
        - unit_price_cents
        - replicate_price_cents
        - subtotal_cents
      properties:
        experiment_type:
          type: string
          description: |-
            Experiment type (e.g., "screening", "affinity", "thermostability",
            "fluorescence", "expression")
          example: screening
        n_replicates:
          type: integer
          format: int32
          description: Number of technical replicates
          example: 3
          minimum: 0
        replicate_price_cents:
          type: integer
          format: int64
          description: |-
            Price per additional replicate (beyond first) in USD cents.
            Zero for experiment types without replicate pricing.
          example: 2900
        sequence_count:
          type: integer
          format: int32
          description: Number of sequences in the experiment
          example: 5
          minimum: 0
        subtotal_cents:
          type: integer
          format: int64
          description: >-
            Subtotal for assay costs in USD cents.

            Calculated as: `sequence_count × (unit_price + max(0, n_replicates -
            1) × replicate_price)`
          example: 103500
        unit_price_cents:
          type: integer
          format: int64
          description: |-
            Base price per sequence in USD cents.
            Includes the first replicate.
          example: 14900
    MaterialCost:
      oneOf:
        - type: object
          description: 'Per-sequence pricing: fixed cost per sequence.'
          required:
            - target
            - sequence_count
            - price_per_sequence_cents
            - subtotal_cents
            - type
          properties:
            price_per_sequence_cents:
              type: integer
              format: int64
              description: Price per sequence in USD cents
              example: 500
            sequence_count:
              type: integer
              format: int32
              description: Number of sequences requiring material
              example: 5
              minimum: 0
            subtotal_cents:
              type: integer
              format: int64
              description: 'Subtotal: sequence_count * price_per_sequence_cents'
              example: 2500
            target:
              $ref: '#/components/schemas/TargetReference'
              description: The target these materials are for (catalog id + display name).
            type:
              type: string
              enum:
                - per_sequence
        - type: object
          description: |-
            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.
          required:
            - target
            - sequence_count
            - lots
            - subtotal_cents
            - type
          properties:
            lots:
              type: array
              items:
                $ref: '#/components/schemas/LotAllocation'
              description: Lot allocations covering the order
            sequence_count:
              type: integer
              format: int32
              description: Number of sequences in the experiment
              example: 10
              minimum: 0
            subtotal_cents:
              type: integer
              format: int64
              description: >-
                Total material cost in USD cents (sum of lot_price_cents ×
                quantity)
              example: 30000
            target:
              $ref: '#/components/schemas/TargetReference'
              description: The target these materials are for (catalog id + display name).
            type:
              type: string
              enum:
                - per_broken_lot
      description: Material cost for target antigens, discriminated by pricing model.
    String:
      type: string
    MaterialsUnavailable:
      type: object
      description: |-
        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.
      required:
        - target
        - reason
      properties:
        reason:
          type: string
          description: Human-readable explanation for why pricing is unavailable
          example: >-
            Human PD-L1 is not yet onboarded to self-service pricing. You'll
            receive a quote with full price information.
        target:
          $ref: '#/components/schemas/TargetReference'
          description: >-
            The target that lacks self-service pricing (catalog id + display
            name).
    ExperimentType:
      type: string
      description: Experiment type determining the assay workflow.
      enum:
        - affinity
        - screening
        - thermostability
        - fluorescence
        - expression
        - epitope_binning
        - enzyme_activity
    Method:
      type: string
      description: >-
        The measurement method (BLI or SPR).


        Required for affinity and screening; must be omitted for all other
        types.
      enum:
        - bli
        - spr
    SequenceValue:
      oneOf:
        - $ref: '#/components/schemas/AAString'
          description: 'Simple format: amino acid sequence string'
        - $ref: '#/components/schemas/SequenceInput'
          description: 'Rich format: sequence with optional control flag and metadata'
      description: >-
        Flexible sequence input for experiment creation.


        Accepts a simple amino acid string or a rich object with control flag
        and metadata.
    TargetReference:
      type: object
      description: >-
        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.
      required:
        - name
      properties:
        name:
          type: string
          description: The target's display name, as shown in the Foundry Portal.
          example: Human PD-L1
        sequence:
          type:
            - string
            - 'null'
          description: The target's amino-acid sequence, when available.
        supplier_url:
          type:
            - string
            - 'null'
          description: Link to the target's vendor product page, when available.
        target_catalog_id:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            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}`.
          example: 019a03da-b87f-7e15-8b02-cef171c9871d
    LotAllocation:
      type: object
      description: |-
        A single lot within a multi-lot allocation.

        When an order requires more material than any single lot provides,
        the greedy allocator combines lots. Each entry records the lot size,
        unit price, and how many of that lot are needed.
      required:
        - lot_size_ug
        - lot_price_cents
        - quantity
      properties:
        lot_price_cents:
          type: integer
          format: int64
          description: Price of one unit of this lot in USD cents
          example: 80000
        lot_size_ug:
          type: number
          format: double
          description: Size of this lot in micrograms
          example: 200
        quantity:
          type: integer
          format: int32
          description: Number of this lot needed
          example: 2
          minimum: 0
    AAString:
      type: string
      description: >-
        A validated amino acid sequence string.


        Contains only the 20 natural amino acids (single-letter codes: A, C, D,
        E,

        F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y) and colons for
        multichain

        notation. Input is case-insensitive; stored uppercase.


        Multichain sequences use colon separators (e.g., `MVLS:EVQL` for a

        two-chain construct). Invalid characters or empty strings are rejected.
      example: EVQLVESGGGLVQPGGSLRLSCAAS
    SequenceInput:
      type: object
      description: Rich sequence input with control flag and optional structural metadata.
      required:
        - aa_string
      properties:
        aa_string:
          $ref: '#/components/schemas/AAString'
          description: >-
            Protein/peptide sequence in standard single-letter amino acid
            format.


            Valid characters: A,C,D,E,F,G,H,I,K,L,M,N,P,Q,R,S,T,V,W,Y and colon
            for multichain.
        control:
          type: boolean
          description: Whether the sequence should be treated as a control well
        metadata:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/SequenceMetadata'
              description: >-
                Structural metadata about the sequence (antibody type, tag
                location, etc.)
    SequenceMetadata:
      type: object
      description: >-
        Structural metadata for antibody sequences.


        The `type` field determines which other fields are required:


        | Type | Required | Optional |

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

        | `sc_fv` | `vh`, `vl` | `linker` (defaults to `GGGGSGGGGSGGGGS`),
        `tag_location` |

        | `fab` | `framework_regions.ch`, `framework_regions.cl` |
        `tag_location` |

        | `single_chain` | (none) | `tag_location` |

        | `igg` | (none) | `tag_location` |


        When `type` is omitted, validation is skipped for backwards
        compatibility.


        # Examples


        ScFv with minimal required fields:

        ```json

        {
          "type": "sc_fv",
          "tag_location": "C",
          "vh": "EVQLVESGGGLVQPGGSLRLSCAASGFTFS",
          "vl": "DIQMTQSPSSLSASVGDRVTITC"
        }

        ```


        FAB with explicit constant regions:

        ```json

        {
          "type": "fab",
          "tag_location": "N",
          "framework_regions": {
            "ch": "ASTKGPSVFPLAPSSKSTSGGTAALGCLVK...",
            "cl": "RTVAAPSVFIFPPSDEQLKSGTASVVCLL..."
          }
        }

        ```
      properties:
        VH:
          type:
            - string
            - 'null'
          description: Variable heavy chain sequence (required for ScFv).
          example: EVQLVESGGGLVQPGGSLRLSCAASGFTFS
        VL:
          type:
            - string
            - 'null'
          description: Variable light chain sequence (required for ScFv).
          example: DIQMTQSPSSLSASVGDRVTITC
        chain_order:
          type:
            - array
            - 'null'
          items:
            type: string
          description: Chain ordering for complex multi-chain formats.
        framework_regions:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/FrameworkRegions'
              description: Constant region framework sequences (required for FAB).
        linker:
          type:
            - string
            - 'null'
          description: |-
            Flexible peptide linker connecting VH and VL domains.

            If omitted for ScFv, defaults to `GGGGSGGGGSGGGGS` (Gly₄Ser)₃.
          example: GGGGSGGGGSGGGGS
        tag_location:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/TagLocation'
              description: |-
                His-tag location for purification.

                `N` for N-terminal, `C` for C-terminal.
        type:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/SequenceType'
              description: >-
                Antibody format type determining required fields.


                Accepted values: `ScFv`, `FAB`, `SingleChain`, `IgG`
                (Portal-style).

                Also accepts: `sc_fv`, `fab`, `single_chain`, `igg` (API-style).
      additionalProperties: false
    FrameworkRegions:
      type: object
      description: >-
        Constant region framework sequences for FAB antibody format.


        Both `ch` and `cl` are required when the parent metadata has `type:
        fab`.


        # Example


        ```json

        {
          "ch": "ASTKGPSVFPLAPSSKSTSGGTAALGCLVK...",
          "cl": "RTVAAPSVFIFPPSDEQLKSGTASVVCLL..."
        }

        ```
      properties:
        ch:
          type:
            - string
            - 'null'
          description: |-
            Constant heavy chain (CH1) region sequence.

            Typically the human IgG1 CH1 domain (~100 amino acids).
          example: >-
            ASTKGPSVFPLAPSSKSTSGGTAALGCLVKDYFPEPVTVSWNSGALTSGVHTFPAVLQSSGLYSLSSVVTVPSSSLGTQTYICNVNHKPSNTKVDKKVEPKSC
        cl:
          type:
            - string
            - 'null'
          description: |-
            Constant light chain (CL) region sequence.

            Either kappa (~60% of human antibodies) or lambda (~40%).
          example: >-
            RTVAAPSVFIFPPSDEQLKSGTASVVCLLNNFYPREAKVQWKVDNALQSGNSQESVTEQDSKDSTYSLSSTLTLSKADYEKHKVYACEVTHQGLSSPVTKSFNRGEC
    TagLocation:
      type: string
      description: His-tag location on the expressed protein.
      enum:
        - 'N'
        - C
    SequenceType:
      type: string
      description: >-
        Antibody format types.


        Determines validation requirements and expected metadata fields.


        Serializes in Portal-style naming (`ScFv`, `FAB`, `SingleChain`, `IgG`)
        for

        consistency with existing database data. Deserializes both Portal-style
        and

        API-style (`sc_fv`, `fab`, `single_chain`, `igg`) for backwards
        compatibility.
      enum:
        - ScFv
        - FAB
        - SingleChain
        - IgG
  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.

````