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

# Register a new therapeutic candidate

> Register a therapeutic candidate under a project.

The service creates the candidate row, the baseline variant (``v1``),
its chain rows, and any source-antibody / antigen junction rows —
atomically. Any failure after the candidate insert rolls the
candidate row back, so the DB is never left with an orphaned
candidate. Cross-org references (``source_antibody_ids``,
``antigen_ids``, chain-level ``source_antibody_id`` /
``constant_region_id``) surface as ``404`` before any mutation.

**Plan gate.** None — registering candidates is free. Plan gates
apply at submit time (humanization / structure / complex endpoints).

Cost: **write** — burns rate + quota. Does not debit credits.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/therapeutic-candidates
openapi: 3.1.0
info:
  title: Kallima API
  description: >-
    Antibody design API — humanization, structure, stability, immunogenicity,
    complex prediction, and codon optimization.
  version: 0.1.0
servers: []
security: []
tags:
  - name: identity
    description: >-
      Caller identity and credit balance — use ``GET /v1/me`` to inspect the
      resolved org, plan, and compute budget before submitting jobs.
  - name: projects
    description: >-
      Projects — top-level containers for source antibodies and therapeutic
      candidates.
  - name: source-antibodies
    description: Source (parental) antibody sequences registered under a project.
  - name: variants
    description: >-
      Variants descended from a therapeutic candidate — the unit of work for
      pipelines.
  - name: jobs
    description: >-
      Long-running pipeline jobs: humanization, structure, stability,
      immunogenicity. Submit and poll. Deprecated in favor of
      resource-per-job-type endpoints (``humanizations`` and the other Phase 3
      resources); scheduled for removal in ``/v2``.
  - name: humanizations
    description: >-
      Humanization pipeline runs — typed submit body and typed per-strategy
      results. First of the Phase 3 resource-per-job-type endpoints; the generic
      ``/v1/jobs`` shape is deprecated in favor of this.
  - name: structure-predictions
    description: >-
      ImmuneBuilder structure predictions — typed submit body and typed PDB /
      pLDDT / CDR results. Phase 3 resource-per-job-type endpoint.
  - name: stability-analyses
    description: >-
      Stability analyses — typed submit body and typed thermostability /
      aggregation / developability scorecard. Phase 3 resource-per-job-type
      endpoint.
  - name: immunogenicity-analyses
    description: >-
      Immunogenicity analyses — typed submit body and typed MHC-I / MHC-II /
      B-cell epitope + risk-score results. Phase 3 resource-per-job-type
      endpoint.
  - name: uploads
    description: >-
      Presigned Supabase Storage slots for caller-supplied files (e.g. antigen
      PDBs for complex prediction). The API never proxies bytes — clients PUT
      directly to the returned URL.
  - name: antigens
    description: >-
      Target protein sequences scoped to a project — the docking partner in a
      complex prediction. Register once, reference by ``antigen_id`` at submit
      time.
  - name: complex-predictions
    description: >-
      Boltz-2 antibody-antigen complex predictions — typed submit body and typed
      docked-PDB / iptm / interface-residues results. Phase 3
      resource-per-job-type endpoint. Complex runs are long-running (~20–40 min
      on GPU); always poll, never hold the connection.
  - name: therapeutic-candidates
    description: >-
      Therapeutic candidates — the top-of-lineage object under a project.
      Creating one auto-creates a baseline variant (``v1``) and its chain rows
      atomically; pipelines submit against the variant. Junction endpoints
      manage many-to-many links to source antibodies and antigens.
  - name: adc-designs
    description: >-
      ADC (antibody-drug conjugate) designs — catalog records attaching a linker
      + payload + conjugation method to a therapeutic candidate. Run the
      rule-based developability analysis via ``POST
      /v1/adc-designs/{id}/analysis``; pass ``structure_job_id`` to include
      SASA-based conjugation-site accessibility.
  - name: codon-exports
    description: >-
      Codon optimization exports — submit a batch of jobs (one per variant),
      poll until ``variable_cds`` is populated, then download the assembled CDS
      as FASTA, CSV, or GenBank+ZIP. Requires the Structure plan or above.
  - name: webhooks
    description: >-
      Webhook endpoint registration — register HTTPS URLs to receive signed
      event deliveries when jobs complete or fail. Signing uses HMAC-SHA256; see
      ``POST /v1/webhooks`` for verification details.
  - name: webhook-deliveries
    description: >-
      Webhook delivery log — inspect past delivery attempts and manually retry
      failed ones via ``POST /v1/webhook_deliveries/{id}/retry``.
paths:
  /v1/therapeutic-candidates:
    post:
      tags:
        - therapeutic-candidates
      summary: Register a new therapeutic candidate
      description: |-
        Register a therapeutic candidate under a project.

        The service creates the candidate row, the baseline variant (``v1``),
        its chain rows, and any source-antibody / antigen junction rows —
        atomically. Any failure after the candidate insert rolls the
        candidate row back, so the DB is never left with an orphaned
        candidate. Cross-org references (``source_antibody_ids``,
        ``antigen_ids``, chain-level ``source_antibody_id`` /
        ``constant_region_id``) surface as ``404`` before any mutation.

        **Plan gate.** None — registering candidates is free. Plan gates
        apply at submit time (humanization / structure / complex endpoints).

        Cost: **write** — burns rate + quota. Does not debit credits.
      operationId: create_therapeutic_candidate_v1_therapeutic_candidates_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TherapeuticCandidateCreate'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TherapeuticCandidate'
        '400':
          description: Malformed request body or parameter.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Missing or invalid API token.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '402':
          description: >-
            Payment required — insufficient credits or the caller's plan is
            below the required tier.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Resource does not exist in the caller's organization.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '422':
          description: Request failed validation.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: >-
            Rate limit or monthly write quota exceeded. `Retry-After` holds the
            number of seconds until the next admitted request.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
          headers:
            Retry-After:
              description: Seconds until the caller may retry. Present on 429 responses.
              schema:
                type: integer
                minimum: 1
            X-RateLimit-Limit:
              description: Per-minute rate ceiling for this API token's plan.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests remaining in the current rate window.
              schema:
                type: integer
            X-RateLimit-Reset:
              description: HTTP-date when the rate window resets.
              schema:
                type: string
                format: http-date
            X-Quota-Limit:
              description: Monthly write ceiling for this API token's plan.
              schema:
                type: integer
            X-Quota-Remaining:
              description: Writes remaining in the current monthly window.
              schema:
                type: integer
            X-Quota-Reset:
              description: >-
                HTTP-date when the monthly write quota resets (always the 1st of
                next month UTC).
              schema:
                type: string
                format: http-date
      security:
        - HTTPBearer: []
components:
  schemas:
    TherapeuticCandidateCreate:
      properties:
        project_id:
          type: string
          title: Project Id
          description: Project the candidate belongs to. Must be owned by the caller's org.
          examples:
            - 7b4a3c0f-2e6d-4c7a-9e8f-1d3b5a2c4e6f
        name:
          type: string
          maxLength: 120
          minLength: 1
          title: Name
          description: Short human label (e.g. ``anti-HER2 mab``).
          examples:
            - anti-HER2 mab
        format:
          type: string
          enum:
            - mab
            - nanobody
            - scfv
            - fc_fusion
            - bispecific_kih
            - bispecific_crossmab
            - bispecific_common_lc
            - bite
            - dart
            - dvd_ig
            - tandem_scfv
            - trispecific_tandem_scfv
            - trispecific_igg_scfv
            - trispecific_knh_scfv
          title: Format
          description: Molecular format — see the envelope's ``format`` field.
        drug_class:
          type: string
          enum:
            - naked_antibody
            - adc
            - car
            - radioconjugate
            - t_cell_engager
          title: Drug Class
          description: Therapeutic modality. Defaults to ``naked_antibody``.
          default: naked_antibody
        format_metadata:
          additionalProperties: true
          type: object
          title: Format Metadata
          description: Format-specific metadata (bispecific arm assignments, etc.).
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: Optional freeform note.
        source_antibody_ids:
          items:
            type: string
          type: array
          title: Source Antibody Ids
          description: >-
            IDs of parental antibodies to link at create time. Every id must
            walk back to the caller's org; cross-org ids return 404.
        antigen_ids:
          items:
            type: string
          type: array
          title: Antigen Ids
          description: IDs of antigens this candidate targets. Cross-org ids return 404.
        initial_chains:
          items:
            $ref: '#/components/schemas/VariantChainSpec'
          type: array
          minItems: 1
          title: Initial Chains
          description: >-
            Chain specs used to build the baseline variant (``v1``). At least
            one chain is required. References in the chain specs
            (``source_antibody_id``, ``constant_region_id``) are scope-checked
            before insert; custom constant-region rows must belong to the
            caller's org, but the built-in library (``org_id IS NULL``) is
            always accessible.
      type: object
      required:
        - project_id
        - name
        - format
        - initial_chains
      title: TherapeuticCandidateCreate
      description: |-
        Body for ``POST /v1/therapeutic-candidates``.

        Mirrors :class:`app.schemas.candidates.CandidateCreate` but annotated
        for the /v1 OpenAPI surface. ``initial_chains`` is required — the
        service auto-creates the baseline variant (``v1``) and its chains
        atomically; failures roll the candidate row back, so the DB never
        ends up with a candidate missing its baseline.
      example:
        antigen_ids:
          - a1b2c3d4-e5f6-7890-abcd-ef1234567890
        description: Humanized anti-HER2 lead
        drug_class: naked_antibody
        format: mab
        initial_chains:
          - chain_id: H
            role: heavy
            variable_sequence: QVQLV...
          - chain_id: L
            role: light
            variable_sequence: DIQMTQ...
        name: anti-HER2 mab
        project_id: 7b4a3c0f-2e6d-4c7a-9e8f-1d3b5a2c4e6f
        source_antibody_ids:
          - 1111aaaa-2222-3333-4444-5555bbbbcccc
    TherapeuticCandidate:
      properties:
        id:
          type: string
          title: Id
          description: Opaque therapeutic-candidate identifier (UUID).
          examples:
            - c0f5e4b1-a7d2-4e0b-9f8c-1b2d3e4f5a6b
        object:
          type: string
          const: therapeutic_candidate
          title: Object
          description: Polymorphic discriminator. Always ``therapeutic_candidate``.
          default: therapeutic_candidate
        project_id:
          type: string
          title: Project Id
          description: Project this candidate belongs to.
          examples:
            - 7b4a3c0f-2e6d-4c7a-9e8f-1d3b5a2c4e6f
        name:
          type: string
          title: Name
          description: Short human label shown in dashboards and logs.
        format:
          type: string
          enum:
            - mab
            - nanobody
            - scfv
            - fc_fusion
            - bispecific_kih
            - bispecific_crossmab
            - bispecific_common_lc
            - bite
            - dart
            - dvd_ig
            - tandem_scfv
            - trispecific_tandem_scfv
            - trispecific_igg_scfv
            - trispecific_knh_scfv
          title: Format
          description: >-
            Molecular format. Single-arm (``mab``, ``nanobody``, ``scfv``,
            ``fc_fusion``) require one H+L pair or a single-chain spec.
            Multi-arm formats require all arms' chain specs at create time.
        drug_class:
          type: string
          enum:
            - naked_antibody
            - adc
            - car
            - radioconjugate
            - t_cell_engager
          title: Drug Class
          description: >-
            Therapeutic modality. ``naked_antibody`` is the default; ``adc`` and
            ``radioconjugate`` require a subsequent ADC-design record before
            payload synthesis.
        format_metadata:
          additionalProperties: true
          type: object
          title: Format Metadata
          description: >-
            Free-form metadata bag — the bispecific formats use this for arm
            assignments; other formats leave it empty.
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: Optional freeform note shown alongside the candidate.
        source_antibody_ids:
          items:
            type: string
          type: array
          title: Source Antibody Ids
          description: >-
            Source (parental) antibodies linked to this candidate. Maintained
            via the
            ``/v1/therapeutic-candidates/{id}/source-antibodies/{sa_id}``
            endpoints.
        antigen_ids:
          items:
            type: string
          type: array
          title: Antigen Ids
          description: >-
            Antigens this candidate targets. Maintained via the
            ``/v1/therapeutic-candidates/{id}/antigens/{antigen_id}`` endpoints.
        initial_variant_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Initial Variant Id
          description: >-
            The baseline variant (``v1``) auto-created alongside this candidate.
            Populated on create responses; ``null`` on read responses — to walk
            variants post-creation, list them via the variants resource (not yet
            exposed in /v1, Phase 3 follow-up).
        created_at:
          type: string
          title: Created At
          description: ISO-8601 timestamp (UTC) when the candidate was registered.
        updated_at:
          type: string
          title: Updated At
          description: ISO-8601 timestamp (UTC) of the most recent mutation.
      type: object
      required:
        - id
        - project_id
        - name
        - format
        - drug_class
        - created_at
        - updated_at
      title: TherapeuticCandidate
      description: |-
        A therapeutic candidate as returned by /v1.

        Carries the junction-table IDs (source antibodies, antigens) and the
        ``initial_variant_id`` surfaced by ``create_candidate`` so a caller
        can submit pipelines against it without a second round-trip.
      example:
        antigen_ids:
          - a1b2c3d4-e5f6-7890-abcd-ef1234567890
        created_at: '2026-04-23T14:15:00+00:00'
        drug_class: naked_antibody
        format: mab
        format_metadata: {}
        id: c0f5e4b1-a7d2-4e0b-9f8c-1b2d3e4f5a6b
        initial_variant_id: 9999eeee-8888-dddd-7777-cccc66665555
        name: anti-HER2 mab
        object: therapeutic_candidate
        project_id: 7b4a3c0f-2e6d-4c7a-9e8f-1d3b5a2c4e6f
        source_antibody_ids:
          - 1111aaaa-2222-3333-4444-5555bbbbcccc
        updated_at: '2026-04-23T14:15:00+00:00'
    ProblemDetails:
      additionalProperties: true
      description: RFC 9457 problem+json body returned by every non-2xx response.
      example:
        code: insufficient_credits
        credit_balance: 0
        credit_cost: 1
        detail: Humanization costs 1 credit; balance is 0.
        instance: /v1/jobs
        request_id: req_01JBX6Y6ZK6N8Q7YJ0F5VX2C3D
        status: 402
        title: Insufficient credits
        type: https://docs.kallima.bio/errors/insufficient_credits
      properties:
        type:
          description: >-
            Stable URI identifying the error class. Dereferenceable at
            docs.kallima.bio/errors/{code}.
          examples:
            - https://docs.kallima.bio/errors/insufficient_credits
          title: Type
          type: string
        title:
          description: Short human-readable summary of the error class.
          examples:
            - Insufficient credits
          title: Title
          type: string
        status:
          description: HTTP status code. Matches the response status line.
          examples:
            - 402
          title: Status
          type: integer
        detail:
          description: Human-readable explanation with values substituted.
          examples:
            - Humanization costs 1 credit; balance is 0.
          title: Detail
          type: string
        instance:
          description: The specific request URI that failed.
          examples:
            - /v1/jobs
          title: Instance
          type: string
        code:
          description: >-
            Machine-readable short code. SDKs switch on this, not on `title`.
            See app.errors.ErrorCode for the full taxonomy.
          examples:
            - insufficient_credits
          title: Code
          type: string
        request_id:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: ULID stamped on every request. Include when contacting support.
          examples:
            - req_01JBX6Y6ZK6N8Q7YJ0F5VX2C3D
          title: Request Id
      required:
        - type
        - title
        - status
        - detail
        - instance
        - code
      title: ProblemDetails
      type: object
    VariantChainSpec:
      properties:
        chain_id:
          type: string
          maxLength: 8
          minLength: 1
          title: Chain Id
          description: 'Short label: H, L, H1, H2, L1, L2, scFv, etc.'
        role:
          type: string
          enum:
            - heavy
            - light
            - vhh
            - scfv
            - fc_only
            - peptide_linker
            - targeting_domain
          title: Role
        variable_sequence:
          anyOf:
            - type: string
            - type: 'null'
          title: Variable Sequence
        constant_region_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Constant Region Id
        source_antibody_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Source Antibody Id
      type: object
      required:
        - chain_id
        - role
      title: VariantChainSpec
      description: >-
        Specification for one chain within a variant.


        variable_sequence is required for roles that carry a sequence (heavy,
        light,

        vhh, scfv, fc_only, targeting_domain). peptide_linker rows may omit it.
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````