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

# Comprehensive Template Update

> Comprehensive update of template including properties, users, fields, and reminders. Supports user deletion with field reassignment or deletion. All sections are optional but at least one must be provided.

**Not atomic.** The parts of this call are not applied as one update. Each entry of `users` or `deleted_users` that adds, moves or removes a signer or an approver is saved on its own, in the order of the request. If one of these saves is refused, the call answers at once with that error: what was saved before it stays applied and the rest of the request is not processed. Other problems (for example a user that is not found, or an invalid field or reminder) are collected and answered as one 400 `VALIDATION_ERROR` at the end of the call. Once a problem was collected, some of the remaining changes are skipped (the `users`, `fields` and `reminders` entries that follow it) and others can still be applied before the 400, and what was saved before the problem stays applied. The 400 does not always say which entries failed. Read the template again after any non-2xx response. If the read of the template's seal participants for the response fails after the writes, the call answers 500 although the writes were applied.

**Seal participants.** The request property `seal_participants` sets the seal participants of the template. When the key is absent, the seal participants of the template are left unchanged. When it is an array, the array replaces the whole set: every seal participant the template had is removed together with the fields it owned, and one seal participant is created for each entry, so `[]` removes them all. Each entry is an object with `seal_id` (required, the ID of an organization seal), `order` (required, a positive integer that no other entry repeats and that is not greater than the number of recipients of the template plus the number of entries) and an optional `temp_id`. The recipients keep their relative order and each seal is placed at its `order`. `null`, any other value that is not an array and an entry without `seal_id` answer 400 `VALIDATION_ERROR`; an `order` that breaks the rules above answers 400 `INVALID_SIGNING_ORDER`; a `seal_id` that is not a UUID answers 404 `NOT_FOUND`; a seal of your company that is revoked or deleted answers 400 `SEAL_UNAVAILABLE`. Each of these answers is immediate and leaves the seal participants unchanged. `seal_participants` is processed after the other parts of the call, also when they collected problems, so it can be applied in a call that then answers 400 `VALIDATION_ERROR`.



## OpenAPI

````yaml api-reference/v01.39.01/openapi-v01.39.01.json put /templates/{id}
openapi: 3.0.3
info:
  title: Firma Partner API
  description: >-
    RESTful API for document signing and template management.


    **Authentication**: All endpoints require API key authentication via the
    `Authorization` header. Use your API key directly without any prefix (e.g.,
    `your-api-key`). The Bearer prefix is optional but not required.


    **Security Features**:

    - Input validation using Zod schemas with detailed field-level error
    messages

    - RSA-256 signed JWT tokens for embedded template access


    **Rate Limiting**: Rate limits are tiered based on operation type:

    - Read operations (GET): 200 requests per minute

    - Write operations (POST/PUT/PATCH/DELETE): 120 requests per minute

    - Webhook CRUD operations: 60 requests per minute

    - Webhook test: 10 requests per minute

    - API key regeneration/expiration: 1 request per minute

    - Webhook secret rotation: 1 request per minute


    When rate limits are exceeded, the API returns a `429 Too Many Requests`
    response with headers:

    - `X-RateLimit-Limit`: Maximum requests per minute for this endpoint

    - `X-RateLimit-Remaining`: Requests remaining in current window

    - `X-RateLimit-Reset`: Unix timestamp when limit resets

    - `Retry-After`: Seconds until retry is allowed


    **Error Handling**: All errors return structured JSON responses with `error`
    (human-readable message), `code` (machine-readable identifier), and
    `details` (field-level validation errors when applicable).


    **Embedded Template Integration**: The Firma Template Editor can be embedded
    in your application using a standalone JavaScript library.


    ```html

    <!-- Load the Firma Template Editor library -->

    <script
    src="https://api.firma.dev/functions/v1/embed-proxy/template-editor.js"></script>


    <script>

    // Generate JWT token via API first

    fetch('https://api.firma.dev/functions/v1/signing-request-api/generate-template-token',
    {
      method: 'POST',
      headers: {
        'Authorization': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        companies_workspaces_templates_id: 'template-id'
      })
    })

    .then(res => res.json())

    .then(data => {
      // Initialize editor with JWT token
      window.FirmaTemplateEditor.init({
        container: '#firma-editor-container',
        jwt: data.token,
        templateId: 'template-id',
        theme: 'dark',
        readOnly: false,
        onSave: (savedData) => {
          console.log('Template saved:', savedData);
        },
        onError: (error) => {
          console.error('Editor error:', error);
        },
        onLoad: (template) => {
          console.log('Template loaded:', template);
        }
      });
    });

    ```


    **X-Firma-Deprecation Header**: Some seal creation and image update
    operations return an `X-Firma-Deprecation` response header when called on
    the edge gateway, indicating the operation should be performed on the
    primary API host instead.


    **Multi-document documents (API 01.39.00, enablement required)**: a template
    or signing request can hold up to 20 documents. The `/documents`
    sub-resource routes and the `documents`, `documents_version` and
    `documents_layout_version` keys are served only for companies enabled for
    multi-document documents; for any other company the routes answer `404
    NOT_FOUND` and the keys are absent.


    **Template seals on create (API 01.39.01)**: creating a signing request from
    a template with `POST /signing-requests` or `POST
    /signing-requests/create-and-send` now inherits the template's seal
    participants, and the template fields that belong to them, when
    `seal_participants` is absent or `null`. This changes the behaviour of v1
    without a version bump; send `seal_participants: []` to create the request
    with no seals. `POST /templates/{id}/duplicate` also carries the template's
    seal participants over; see that operation for how it differs for companies
    enabled for multi-document documents. `GET /templates/{id}` returns
    `seal_participants`, and `POST /templates` answers `warnings` when its body
    contains keys it ignores.
  version: 01.39.01
  contact:
    name: API Support
    url: https://firma.com/support
servers:
  - url: https://api.firma.dev/functions/v1/signing-request-api
    description: Production API - Recommended (Current)
  - url: https://api.firma.dev/api/v1
    description: Production API - Planned
security:
  - ApiKeyAuth: []
tags:
  - name: Company
    description: Company information and settings
  - name: Workspaces
    description: Workspace management operations
  - name: Templates
    description: Template management operations
  - name: Signing Requests
    description: Document signing request operations
  - name: Custom Fields
    description: >-
      Custom field definition management for workspaces, templates, and signing
      requests
  - name: Webhooks
    description: Webhook configuration and management
  - name: JWT Management
    description: JWT token generation and revocation for embedded templates
  - name: Workspace Settings
    description: Workspace configuration and settings
  - name: Email Domains
    description: >-
      Email domain setup and verification for sending signing request emails
      from custom domains
  - name: Email Templates
    description: >-
      Email template management for workspace and company-level customization of
      signing request notifications
  - name: Organization Seals
    description: >-
      Organization seal management: create, update, revoke, and erase seals
      applied to signing requests
  - name: Signer Terms
    description: >-
      Custom signer terms-of-service / consent statements, company-level with
      per-language workspace overrides
paths:
  /templates/{id}:
    put:
      tags:
        - Templates
      summary: Comprehensive Template Update
      description: >-
        Comprehensive update of template including properties, users, fields,
        and reminders. Supports user deletion with field reassignment or
        deletion. All sections are optional but at least one must be provided.


        **Not atomic.** The parts of this call are not applied as one update.
        Each entry of `users` or `deleted_users` that adds, moves or removes a
        signer or an approver is saved on its own, in the order of the request.
        If one of these saves is refused, the call answers at once with that
        error: what was saved before it stays applied and the rest of the
        request is not processed. Other problems (for example a user that is not
        found, or an invalid field or reminder) are collected and answered as
        one 400 `VALIDATION_ERROR` at the end of the call. Once a problem was
        collected, some of the remaining changes are skipped (the `users`,
        `fields` and `reminders` entries that follow it) and others can still be
        applied before the 400, and what was saved before the problem stays
        applied. The 400 does not always say which entries failed. Read the
        template again after any non-2xx response. If the read of the template's
        seal participants for the response fails after the writes, the call
        answers 500 although the writes were applied.


        **Seal participants.** The request property `seal_participants` sets the
        seal participants of the template. When the key is absent, the seal
        participants of the template are left unchanged. When it is an array,
        the array replaces the whole set: every seal participant the template
        had is removed together with the fields it owned, and one seal
        participant is created for each entry, so `[]` removes them all. Each
        entry is an object with `seal_id` (required, the ID of an organization
        seal), `order` (required, a positive integer that no other entry repeats
        and that is not greater than the number of recipients of the template
        plus the number of entries) and an optional `temp_id`. The recipients
        keep their relative order and each seal is placed at its `order`.
        `null`, any other value that is not an array and an entry without
        `seal_id` answer 400 `VALIDATION_ERROR`; an `order` that breaks the
        rules above answers 400 `INVALID_SIGNING_ORDER`; a `seal_id` that is not
        a UUID answers 404 `NOT_FOUND`; a seal of your company that is revoked
        or deleted answers 400 `SEAL_UNAVAILABLE`. Each of these answers is
        immediate and leaves the seal participants unchanged.
        `seal_participants` is processed after the other parts of the call, also
        when they collected problems, so it can be applied in a call that then
        answers 400 `VALIDATION_ERROR`.
      operationId: updateTemplate
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                template_properties:
                  type: object
                  description: Update template metadata and settings
                  properties:
                    name:
                      type: string
                      maxLength: 255
                    description:
                      type: string
                    document:
                      type: string
                      format: byte
                      description: >-
                        Base64-encoded PDF or DOCX to replace document. DOCX
                        files are automatically converted to PDF. For documents
                        larger than 5 MB, use POST /documents and pass the
                        document_id instead. (mutually exclusive with
                        document_id)
                    document_id:
                      type: string
                      format: uuid
                      description: >-
                        ID of a previously uploaded document (mutually exclusive
                        with document). Obtain by calling POST /documents first.
                      example: 123e4567-e89b-12d3-a456-426614174000
                    expiration_hours:
                      type: integer
                      minimum: 1
                    settings:
                      type: object
                      properties:
                        allow_editing_before_sending:
                          type: boolean
                        attach_pdf_on_finish:
                          type: boolean
                        allow_download:
                          type: boolean
                        hand_drawn_only:
                          type: boolean
                        require_otp_verification:
                          type: boolean
                          nullable: true
                          description: >-
                            Require signers to verify their email with a
                            one-time code; `null` inherits the workspace or
                            company setting.
                        disable_guided_navigation:
                          type: boolean
                          nullable: true
                        allow_presigning_download:
                          type: boolean
                          nullable: true
                          description: >-
                            Allow signers to download the original document
                            before signing; `null` inherits the workspace or
                            company setting.
                        show_qr_code:
                          type: boolean
                          nullable: true
                          description: >-
                            Show a QR code on the signing page that lets signers
                            continue on their phone. Inherits from workspace or
                            company setting when null.
                users:
                  type: array
                  description: >-
                    Upsert users (include id to update, omit to create). An
                    existing recipient cannot be changed between CC and
                    Signer/Approver (400); delete it and create it again.
                  items:
                    type: object
                    required:
                      - first_name
                      - email
                      - designation
                      - order
                    properties:
                      id:
                        type: string
                        format: uuid
                        description: Omit for new users
                      first_name:
                        type: string
                      last_name:
                        type: string
                        description: >-
                          Optional, but required if using full_name or last_name
                          prefilled variables
                      email:
                        type: string
                        format: email
                      designation:
                        type: string
                        enum:
                          - Signer
                          - Approver
                          - CC
                      order:
                        type: integer
                        minimum: 1
                      phone_number:
                        type: string
                      street_address:
                        type: string
                      city:
                        type: string
                      state_province:
                        type: string
                      postal_code:
                        type: string
                      country:
                        type: string
                      title:
                        type: string
                      company:
                        type: string
                force_remove_conditions:
                  type: boolean
                  default: false
                  description: >-
                    When deleting users whose fields are referenced by
                    conditions in other fields: if true, automatically remove
                    the condition references; if false (default), the request
                    will be rejected with an error.
                deleted_users:
                  type: array
                  description: Users to delete with field handling strategy
                  items:
                    type: object
                    required:
                      - user_id
                      - field_action
                    properties:
                      user_id:
                        type: string
                        format: uuid
                      field_action:
                        type: string
                        enum:
                          - delete
                          - reassign
                        description: What to do with fields assigned to this user
                      reassign_to_user_id:
                        type: string
                        format: uuid
                        description: >-
                          Required when field_action is 'reassign'. Target user
                          must have same designation.
                fields:
                  type: array
                  description: Upsert fields (include id to update, omit to create)
                  items:
                    type: object
                    required:
                      - type
                      - x
                      - 'y'
                      - width
                      - height
                      - page
                    properties:
                      id:
                        type: string
                        format: uuid
                        description: Omit for new fields
                      type:
                        type: string
                        enum:
                          - signature
                          - text
                          - date
                          - checkbox
                          - dropdown
                          - approval_signature
                          - approval_checkmark
                          - approval_date
                      x:
                        type: number
                        minimum: 0
                        maximum: 100
                        description: X position as percentage
                      'y':
                        type: number
                        minimum: 0
                        maximum: 100
                        description: Y position as percentage
                      width:
                        type: number
                        minimum: 0
                        maximum: 100
                      height:
                        type: number
                        minimum: 0
                        maximum: 100
                      page:
                        type: integer
                        minimum: 1
                      required:
                        type: boolean
                        default: false
                      assigned_to_user_id:
                        type: string
                        format: uuid
                      options:
                        type: array
                        items:
                          type: string
                        description: For dropdown fields
                      default_to_signing_date:
                        type: boolean
                        description: For date fields
                      multi_group_id:
                        type: string
                        format: uuid
                        description: >-
                          Group ID for mutually exclusive checkbox/radio button
                          groups
                      variable_name:
                        type: string
                      variable_defined_name:
                        type: string
                        maxLength: 100
                        nullable: true
                        description: >-
                          Human-readable custom field definition name. Can be
                          used as an alternative to variable_name for targeting
                          fields in template-based creation.
                      required_conditions:
                        $ref: '#/components/schemas/ConditionSet'
                        nullable: true
                      visibility_conditions:
                        $ref: '#/components/schemas/ConditionSet'
                        nullable: true
                reminders:
                  type: array
                  description: Upsert reminders (include id to update, omit to create)
                  items:
                    type: object
                    required:
                      - hours
                      - subject
                      - message
                    properties:
                      id:
                        type: string
                        format: uuid
                        description: Omit for new reminders
                      hours:
                        type: integer
                        minimum: 1
                        description: Hours after sending before reminder
                      all_users:
                        type: boolean
                        default: false
                      user_id:
                        type: string
                        format: uuid
                        description: Required if all_users is false
                      subject:
                        type: string
                        maxLength: 255
                      message:
                        type: string
                        maxLength: 5000
                documents_layout_version:
                  type: integer
                  minimum: 0
                  description: >-
                    The `documents_layout_version` of your last read
                    (multi-document). Required for a field write on a template
                    with more than one document or a layout version above 1
                    (`409 DOCUMENTS_LAYOUT_VERSION_REQUIRED`); a stale value
                    answers `409 DOCUMENT_SET_VERSION_CONFLICT`; a value that is
                    not a non-negative integer answers `400 VALIDATION_ERROR`
                    with key `documents_layout_version`.
                seal_participants:
                  type: array
                  description: >-
                    When present, the array replaces the template's whole set of
                    seal participants and removes the fields the former ones
                    owned; `[]` removes them all; omit the key to leave them
                    unchanged. `null` is not accepted: it answers 400
                    `VALIDATION_ERROR`. See the operation description for the
                    rules of each entry and the errors.
                  items:
                    $ref: '#/components/schemas/TemplateSealParticipantInput'
      responses:
        '200':
          description: >-
            Template updated successfully. Returns full template with all
            relationships. `seal_participants` lists only the seal participants
            whose seal belongs to the company of the API key: a seal participant
            whose seal is missing or belongs to another company is omitted, so
            an empty or shorter list does not prove that the template has no
            other seal participant stored.
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: 'Rate limit: 120 requests per minute'
            X-RateLimit-Remaining:
              schema:
                type: integer
            X-RateLimit-Reset:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateDetail'
        '400':
          description: >-
            Bad Request - Validation failed. Multi-document:
            `PAGE_COUNT_MISMATCH`, `DIMENSION_MISMATCH` (document replacement).
            Multi-document field writes: `VALIDATION_ERROR` with key `page` (a
            page beyond the document's page count) or `documents_layout_version`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Validation Error
                message: Invalid input data
                details:
                  name: Name is required
                  email: Invalid email format
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '409':
          description: >-
            Conflict: `MULTI_DOCUMENT_READ_ONLY`,
            `MULTI_DOCUMENT_REPLACE_UNSUPPORTED`,
            `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`,
            `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`,
            `DOCUMENT_SET_INCONSISTENT`, `DOCUMENTS_LAYOUT_VERSION_REQUIRED`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiDocumentError'
        '429':
          $ref: '#/components/responses/RateLimitError'
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: TypeScript
          label: '@firma-dev/sdk'
          source: |-
            import { FirmaClient } from "@firma-dev/sdk";

            const firma = new FirmaClient({ apiKey: "YOUR_API_KEY" });

            const response = await firma.templates.updateTemplate({
                id: "id"
            });
            console.log(response);
components:
  schemas:
    ConditionSet:
      type: object
      required:
        - logic
        - groups
      description: >-
        A set of condition groups with nested logic. The outer 'logic' operator
        combines groups, while each group's conditions use the opposite
        operator. Example: logic='and' means all groups must match, and within
        each group any condition can match (OR).
      properties:
        logic:
          type: string
          enum:
            - and
            - or
          description: >-
            Logical operator to combine groups. 'and' = all groups must match,
            'or' = any group can match.
        groups:
          type: array
          items:
            $ref: '#/components/schemas/ConditionGroup'
          description: Array of condition groups
    TemplateSealParticipantInput:
      type: object
      required:
        - seal_id
        - order
      description: >-
        One seal participant of a template: an item of `seal_participants` on
        `PUT /templates/{id}`.
      properties:
        seal_id:
          type: string
          format: uuid
          description: >-
            ID of the organization seal this seal participant applies. Required:
            there is no default seal on this call.
        order:
          type: integer
          minimum: 1
          description: >-
            Position of the seal among the recipients and seals of the template:
            a positive integer that no other entry repeats and that is not
            greater than the number of recipients of the template plus the
            number of entries.
        temp_id:
          type: string
          description: Optional temporary ID of this entry.
    TemplateDetail:
      description: >-
        A template with its seal participants: every key of Template, plus
        `seal_participants`. `seal_participants` lists only the seal
        participants whose seal belongs to the company of the API key: a seal
        participant whose seal is missing or belongs to another company is
        omitted, so an empty or shorter list does not prove that the template
        has no other seal participant stored.
      allOf:
        - $ref: '#/components/schemas/Template'
        - type: object
          required:
            - seal_participants
          properties:
            seal_participants:
              type: array
              description: >-
                The template's seal participants in order, limited to those
                whose seal belongs to the company of the API key. A seal
                participant whose seal is missing or belongs to another company
                is omitted, so an empty or shorter list does not prove that the
                template has no other seal participant stored.
              items:
                $ref: '#/components/schemas/SealParticipantApi'
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human-readable error message
        code:
          type: string
          description: >-
            Machine-readable error code Seal-related codes: SEALS_DISABLED,
            SEAL_ALREADY_REVOKED, SEAL_CREATION_DISABLED_EDGE,
            SEAL_ERASE_NOT_ELIGIBLE, SEAL_IMAGE_INVALID,
            SEAL_MUTATION_NOT_ALLOWED, SEAL_NOT_FOUND, SEAL_NO_IMAGE_FIELD,
            SEAL_ORDER_COLLISION, SEAL_PAUSED, SEAL_SCOPE_FORBIDDEN,
            SEAL_UNAVAILABLE Multi-document codes: see MultiDocumentErrorCode
            (41 codes).
        errors:
          type: array
          description: >-
            All validation errors when multiple failures are reported together.
            The top-level error repeats the first item for backward
            compatibility.
          items:
            type: object
            required:
              - message
            properties:
              message:
                type: string
        message:
          type: string
          description: Detailed error description
        details:
          type: object
          description: Additional error details
          additionalProperties: true
      required:
        - error
      description: >-


        Organization Seal error codes: SEALS_DISABLED, SEAL_ALREADY_REVOKED,
        SEAL_CREATION_DISABLED_EDGE, SEAL_ERASE_NOT_ELIGIBLE,
        SEAL_IMAGE_INVALID, SEAL_MUTATION_NOT_ALLOWED, SEAL_NOT_FOUND,
        SEAL_NO_IMAGE_FIELD, SEAL_ORDER_COLLISION, SEAL_PAUSED,
        SEAL_SCOPE_FORBIDDEN, SEAL_UNAVAILABLE
    MultiDocumentError:
      description: An error answered by a multi-document route.
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          required:
            - error
            - code
          properties:
            code:
              $ref: '#/components/schemas/MultiDocumentErrorCode'
    ConditionGroup:
      type: object
      required:
        - conditions
      properties:
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/Condition'
          description: >-
            Array of conditions within this group. Combined using the opposite
            of the parent ConditionSet's logic operator.
    Template:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the template
        name:
          type: string
          description: Template name
          maxLength: 255
        description:
          type: string
          description: Template description
          nullable: true
        document_url:
          type: string
          format: uri
          description: >-
            Pre-signed URL to the PDF document. This is a time-limited signed
            URL for secure access - see document_url_expires_at for expiration
            time. Initial URLs are valid for 7 days; refreshed URLs are valid
            for 1 hour. Request a new template retrieval to get a fresh URL if
            expired.
        document_url_expires_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            ISO 8601 timestamp when the document_url will expire. After this
            time, the URL will return an access denied error. Fetch the template
            again to receive a fresh signed URL.
        page_count:
          type: integer
          minimum: 1
          description: Number of pages in the document
        expiration_hours:
          type: integer
          minimum: 1
          default: 168
          description: Hours until signing requests created from this template expire
        credit_cost:
          type: integer
          minimum: 1
          default: 1
          description: >-
            Number of credits consumed when a signing request is sent from this
            template. Minimum value is 1.
        settings:
          $ref: '#/components/schemas/SigningRequestSettings'
        recipients:
          type: array
          items:
            $ref: '#/components/schemas/TemplateUser'
          description: Template recipients (included in GET single template)
        fields:
          type: array
          items:
            $ref: '#/components/schemas/TemplateField'
          description: Template fields (included in GET single template)
        created_date:
          type: string
          format: date-time
          description: Template creation timestamp
        updated_date:
          type: string
          format: date-time
          description: Template last update timestamp
        documents:
          type: array
          items:
            $ref: '#/components/schemas/DocumentSummary'
          description: >-
            The template's documents in position order (multi-document; present
            only for companies enabled for it). On GET /templates (the list): A
            list entry carries no `document_url`. A parent whose document set
            has never been changed lists `documents: []` here, while its
            single-resource GET answers its one document (with `document_id`
            null). On GET /templates/{id}, PUT /templates/{id} and POST
            /templates: A parent whose document set has never been changed
            answers its one document, with `document_id` null.
        documents_version:
          type: integer
          description: >-
            Version of the document set, raised by every document change
            (multi-document; enabled companies only).
        documents_layout_version:
          type: integer
          description: >-
            Version of the document layout, raised when documents are added,
            removed or reordered (multi-document; enabled companies only). Field
            writes on a signing request with more than one document send it back
            as `documents_layout_version`.
      required:
        - id
        - name
        - created_date
    SealParticipantApi:
      type: object
      description: >-
        Seal participant as the API answers it on a signing request or a
        template. Every key is always present; nullable keys are null when
        unset.
      required:
        - id
        - order
        - seal
        - status
        - applied_at
        - paused_at
        - pause_reason
        - swapped_from_seal_id
        - triggered_by_recipient_id
        - sender_kind
        - seal_out_of_scope
      properties:
        id:
          type: string
          format: uuid
        order:
          type: integer
          minimum: 1
          description: >-
            Position in the signing order, shared with the recipients' order
            space.
        seal:
          type: object
          description: The organization seal this participant applies.
          required:
            - id
            - lineage_id
            - name
            - version
            - display_name
          properties:
            id:
              type: string
              format: uuid
            lineage_id:
              type: string
              format: uuid
              description: Shared across versions of the same seal
            name:
              type: string
            version:
              type: integer
            display_name:
              type: string
        status:
          type: string
          enum:
            - pending
            - paused
            - applied
          description: >-
            applied when applied_at is set, else paused when paused_at is set,
            else pending.
        applied_at:
          type: string
          format: date-time
          nullable: true
        paused_at:
          type: string
          format: date-time
          nullable: true
        pause_reason:
          type: string
          nullable: true
          enum:
            - seal_revoked_stop_pending
            - seal_integrity_mismatch
            - null
        swapped_from_seal_id:
          type: string
          format: uuid
          nullable: true
        triggered_by_recipient_id:
          type: string
          format: uuid
          nullable: true
          description: The recipient whose action applied the seal.
        sender_kind:
          type: string
          nullable: true
          enum:
            - dashboard
            - api_key
            - embedded
            - null
        seal_out_of_scope:
          type: boolean
          description: >-
            True when the seal belongs to a workspace other than the signing
            request's or the template's.
    MultiDocumentErrorCode:
      type: string
      enum:
        - ALREADY_CANCELLED
        - ALREADY_FINISHED
        - ALREADY_SENT
        - ANCHOR_DOCUMENT_REQUIRED
        - ANCHOR_MISMATCH
        - CONFLICTING_DOCUMENT_SOURCE
        - DIMENSION_MISMATCH
        - DOCUMENTS_LAYOUT_VERSION_REQUIRED
        - DOCUMENT_CANDIDATE_EXPIRED
        - DOCUMENT_NOT_FOUND
        - DOCUMENT_ORIGINAL_NOT_AVAILABLE
        - DOCUMENT_SET_BUSY
        - DOCUMENT_SET_DISPATCH_STALE
        - DOCUMENT_SET_INCONSISTENT
        - DOCUMENT_SET_LOCKED
        - DOCUMENT_SET_TOO_LARGE
        - DOCUMENT_SET_VERSION_CONFLICT
        - DOCUMENT_SIGNED_NOT_AVAILABLE
        - DOCUMENT_UPLOAD_NOT_FOUND
        - DUPLICATE_DOCUMENT_ID
        - FENCE_COLUMN_PROTECTED
        - INSUFFICIENT_CREDITS
        - INTERNAL
        - INTERNAL_ERROR
        - INVALID_DOCUMENT_ORDER
        - INVALID_SIGNING_ORDER
        - MAX_DOCUMENTS_EXCEEDED
        - MIN_DOCUMENTS_REQUIRED
        - MULTI_DOCUMENT_READ_ONLY
        - MULTI_DOCUMENT_REPLACE_UNSUPPORTED
        - NOT_FOUND
        - PAGE_COUNT_MISMATCH
        - PARTICIPANTS_CHANGED
        - RATE_LIMIT_EXCEEDED
        - SEAL_MUTATION_NOT_ALLOWED
        - SEND_EFFECTS_EXIST
        - SEND_IN_PROGRESS
        - SIGNED_DATA_IMMUTABLE
        - SIGNING_ORDER_LOCKED_APPLIED
        - SIGNING_ORDER_LOCKED_SENDING
        - SIGNING_ORDER_LOCKED_SENT
        - VALIDATION_ERROR
      description: >-
        Error codes of the multi-document contract and of the routes it changes
        (generated from the error matrix's API-surfaced rows). A genuine server
        fault answers 500 with INTERNAL_ERROR on the legacy routes and INTERNAL
        on the shared HttpError paths (multi-document dispatch, the RPC status
        map, document-set routes); neither carries detail.
    Condition:
      type: object
      required:
        - field_id
        - operator
      description: A single condition that evaluates a field's value.
      properties:
        field_id:
          type: string
          format: uuid
          description: ID of the field to evaluate
        operator:
          type: string
          enum:
            - is_filled
            - is_empty
            - equals
            - not_equals
            - contains
            - not_contains
            - greater_than
            - less_than
            - greater_than_or_equal
            - less_than_or_equal
          description: >-
            Comparison operator. 'is_filled'/'is_empty' don't require a value.
            Text operators: equals, not_equals, contains, not_contains.
            Numeric/date operators: greater_than, less_than,
            greater_than_or_equal, less_than_or_equal.
        value:
          oneOf:
            - type: string
            - type: number
          nullable: true
          description: >-
            Value to compare against. Not required for is_filled/is_empty
            operators.
    SigningRequestSettings:
      type: object
      description: >-
        Settings returned by the signing request list and detail endpoints.
        Templates use the TemplateSettings schema (no identity fields).
      properties:
        allow_download:
          type: boolean
          description: Whether recipients can download the document
          default: true
        attach_pdf_on_finish:
          type: boolean
          description: Whether to attach PDF when signing is complete
          default: true
        allow_editing_before_sending:
          type: boolean
          description: Whether the signing request can be edited before sending
          default: false
        use_signing_order:
          type: boolean
          description: >-
            Whether signing order is enforced among recipients. When true,
            signers receive the document in sequence based on their order. When
            false, all signers receive the document simultaneously.
          default: true
        hand_drawn_only:
          type: boolean
          description: >-
            When enabled, signers can only hand-draw their signatures and cannot
            use typed/font-based signatures
          default: false
        send_signing_email:
          type: boolean
          description: Whether to send signing request notification emails to signers
          default: true
        send_finish_email:
          type: boolean
          description: Whether to send completion email when all signers finish
          default: true
        send_expiration_email:
          type: boolean
          description: Whether to send expiration notification email when request expires
          default: true
        send_cancellation_email:
          type: boolean
          description: >-
            Whether to send cancellation notification email when request is
            cancelled
          default: true
        require_otp_verification:
          type: boolean
          nullable: true
          description: >-
            Whether signers must verify their email with a one-time code before
            accessing the document; `null` inherits the workspace or company
            setting.
          default: null
        disable_guided_navigation:
          type: boolean
          nullable: true
          description: >-
            Disable automatic scrolling to the next required field during
            signing. Inherits from workspace or company if not set.
        allow_presigning_download:
          type: boolean
          nullable: true
          description: >-
            Allow signers to download the original document before signing;
            `null` inherits the workspace or company setting.
        show_qr_code:
          type: boolean
          nullable: true
          description: >-
            Show a QR code on the signing page that lets signers continue on
            their phone. Inherits from workspace or company setting when null.
        identity_editable_fields:
          type: array
          nullable: true
          items:
            type: string
          description: >-
            Identity fields signers may edit before signing, for example
            `["name", "company"]`; `null` disables the editing. When set, a
            confirmation dialog lets signers edit the specified fields.
        notify_identity_change_email:
          type: boolean
          default: false
          description: Send an email notification when a signer changes their identity.
    TemplateUser:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the template user
        name:
          type: string
          description: Recipient name (combined first and last name)
        email:
          type: string
          format: email
          description: Recipient email address
        first_name:
          type: string
          nullable: true
          description: Recipient first name
        last_name:
          type: string
          nullable: true
          description: Recipient last name
        designation:
          type: string
          enum:
            - Signer
            - Approver
            - CC
          description: >-
            Role of the recipient. Signer signs the document, Approver approves
            with approval fields, CC receives a copy when complete.
        order:
          type: integer
          minimum: 1
          description: Order in which the recipient should sign
        phone_number:
          type: string
          nullable: true
          description: Recipient phone number
        street_address:
          type: string
          nullable: true
          description: Recipient street address
        city:
          type: string
          nullable: true
          description: Recipient city
        state_province:
          type: string
          nullable: true
          description: Recipient state or province
        postal_code:
          type: string
          nullable: true
          description: Recipient postal code
        country:
          type: string
          nullable: true
          description: Recipient country
        title:
          type: string
          nullable: true
          description: Recipient job title
        company:
          type: string
          nullable: true
          description: Recipient company name
        required_fields:
          type: array
          items:
            type: string
          description: >-
            List of recipient data fields required for sending (based on
            template fields with variable_name mappings). Always includes
            'email' and 'first_name'.
        missing_fields:
          type: array
          items:
            type: string
          description: List of required fields that are currently empty for this recipient
        required_read_only_fields:
          type: array
          items:
            type: object
            properties:
              variable_name:
                type: string
                nullable: true
                description: Variable name of the read-only field
              variable_defined_name:
                type: string
                nullable: true
                description: >-
                  Human-readable field name from the custom field definition
                  (e.g. 'artist_name'). Only present for fields linked to a
                  custom field definition, null otherwise.
              field_type:
                type: string
                description: Type of the field (text, date, etc.)
          description: >-
            List of required read-only fields that need pre-filled values before
            sending
        ready_to_send:
          type: boolean
          description: Whether this recipient has all required data filled in for sending
      required:
        - id
        - first_name
        - email
        - designation
        - order
    TemplateField:
      type: object
      description: A field placed on a template document
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the field
        type:
          type: string
          enum:
            - text
            - signature
            - date
            - checkbox
            - dropdown
            - radio_buttons
            - number
            - text_area
            - file
            - initial
            - stamp
            - approval_signature
            - approval_checkmark
            - approval_date
          description: Type of the field
        required:
          type: boolean
          description: Whether the field is required
        recipient_id:
          type: string
          format: uuid
          nullable: true
          description: ID of assigned recipient
        variable_name:
          type: string
          nullable: true
          description: Variable name for field (used in templates)
        variable_defined_name:
          type: string
          nullable: true
          description: >-
            Human-readable field name from the custom field definition (e.g.
            'artist_name'). Only present for fields linked to a custom field
            definition, null otherwise.
        position:
          type: object
          description: >-
            Position and dimensions of the field on the document. All values are
            percentages (0-100). The field must fit within the page: x + width
            <= 100 and y + height <= 100.
          properties:
            x:
              type: number
              minimum: 0
              maximum: 100
              description: X coordinate of field position (percentage, 0-100)
            'y':
              type: number
              minimum: 0
              maximum: 100
              description: Y coordinate of field position (percentage, 0-100)
            width:
              type: number
              minimum: 0
              maximum: 100
              description: >-
                Width of the field (percentage, 0-100). Note: x + width must be
                <= 100
            height:
              type: number
              minimum: 0
              maximum: 100
              description: >-
                Height of the field (percentage, 0-100). Note: y + height must
                be <= 100
        page_number:
          type: integer
          minimum: 1
          nullable: true
          description: >-
            Page number where the field is located (1-indexed). Must not exceed
            the document's total page count.
        dropdown_options:
          nullable: true
          description: Options for dropdown fields
          oneOf:
            - type: array
              items:
                type: string
            - type: object
        multi_group_id:
          type: string
          format: uuid
          nullable: true
          description: >-
            Group ID for linking multiple checkbox or radio button fields
            together. Fields sharing the same multi_group_id behave as a
            mutually exclusive group (like radio buttons) - selecting one
            automatically deselects the others in the group. Use the same UUID
            across multiple fields to create a group where only one option can
            be selected at a time.
        date_default:
          type: string
          format: date
          nullable: true
          description: >-
            Default date value for date fields (ISO 8601 format, e.g.,
            '2024-01-15')
        date_signing_default:
          type: boolean
          description: Use signing date as default for date fields
        format_rules:
          $ref: '#/components/schemas/DateFormatRules'
          nullable: true
          description: >-
            Formatting rules - currently used for date fields to specify display
            format
        validation_rules:
          $ref: '#/components/schemas/FieldValidationRules'
        read_only:
          type: boolean
          default: false
          description: Whether this field is read-only (pre-filled before signing)
        read_only_value:
          type: string
          nullable: true
          description: Static value for read-only fields
      required:
        - id
        - type
        - page_number
    DocumentSummary:
      type: object
      description: One document of a template or signing request.
      required:
        - document_id
        - position
        - label
        - original_filename
        - page_count
        - document_url_kind
      properties:
        document_id:
          type: string
          format: uuid
          nullable: true
          description: >-
            Id of the document. null only for the one document of a signing
            request or template whose document set has never been changed (see
            the example).
        position:
          type: integer
          minimum: 1
          description: 1-based position in the set.
        label:
          type: string
          nullable: true
          maxLength: 200
          description: Display name, or null.
        original_filename:
          type: string
          nullable: true
          maxLength: 255
          description: File name recorded at upload, or null.
        page_count:
          type: integer
          nullable: true
          description: Number of pages of this document.
        document_url:
          type: string
          nullable: true
          description: >-
            Signed URL (1 hour) of the file `document_url_kind` names. Absent on
            list responses.
        document_url_kind:
          type: string
          nullable: true
          enum:
            - stored
            - signed
            - null
          description: >-
            `stored`: the document as stored; `signed`: the individually sealed
            document. Always `stored` on templates; null on signing-request list
            entries.
        document_only_hash:
          type: string
          nullable: true
          description: >-
            SHA-256 (hex) of the individually sealed document, null before the
            certificate is bound. Signing requests only.
      example:
        document_id: null
        position: 1
        label: null
        original_filename: null
        page_count: 3
        document_url: >-
          https://api.firma.dev/storage/v1/object/sign/signing-request-documents/example.pdf?token=example
        document_url_kind: stored
        document_only_hash: null
    DateFormatRules:
      type: object
      description: >-
        Formatting rules for date fields. Specifies how date values should be
        displayed and formatted.
      properties:
        dateFormat:
          type: string
          description: >-
            Date format pattern. Use predefined formats or custom patterns with:
            yyyy (4-digit year), MM (2-digit month), dd (2-digit day), MMMM
            (full month name), MMM (abbreviated month name), HH (24-hour), mm
            (minute), ss (second). Examples: 'MM/dd/yyyy' displays as
            01/31/2024, 'MMMM dd, yyyy' displays as January 31, 2024.
          enum:
            - MM/dd/yyyy
            - dd/MM/yyyy
            - yyyy-MM-dd
            - MMMM dd, yyyy
            - MMM dd, yyyy
            - dd MMMM yyyy
          default: MM/dd/yyyy
        fontSize:
          type: integer
          minimum: 8
          maximum: 48
          description: >-
            Optional starting/maximum font size in pixels for the rendered field
            value. Text still auto-shrinks to fit the field box. Omit for
            automatic sizing. Values outside 8-48 are clamped.
      example:
        dateFormat: MMMM dd, yyyy
    FieldValidationRules:
      type: object
      nullable: true
      description: >-
        Validation rules for field values. Reserved for future use - currently
        not enforced for any field types.
      additionalProperties: true
  responses:
    UnauthorizedError:
      description: Unauthorized - Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Unauthorized
            message: Invalid API key
    NotFoundError:
      description: Not Found - Resource does not exist
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Not Found
            message: The requested resource was not found
    RateLimitError:
      description: Too Many Requests - Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
          description: Maximum requests per minute
        X-RateLimit-Remaining:
          schema:
            type: integer
          description: Requests remaining
        X-RateLimit-Reset:
          schema:
            type: integer
          description: Unix timestamp of reset
        Retry-After:
          schema:
            type: integer
          description: Seconds until retry allowed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Rate Limit Exceeded
            message: Too many requests. Please wait before retrying.
            details:
              retry_after: 45
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key for authentication. Use your API key directly without any prefix
        (e.g., 'your-api-key'). Bearer prefix is optional but not required.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.