> ## 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 update signing request



## OpenAPI

````yaml api-reference/v01.13.00/openapi-v01.15.00.json put /signing-requests/{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);
        }
      });
    });

    ```
  version: 01.00.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: 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: Legacy
    description: Deprecated endpoints maintained for backward compatibility
paths:
  /signing-requests/{id}:
    put:
      tags:
        - Signing Requests
      summary: Comprehensive Update Signing Request
      description: >-
        Perform comprehensive updates to a signing request including properties,
        recipients, fields, and reminders. Cannot update after signing request
        has been sent, completed, or cancelled. All sections are optional but at
        least one must be provided.


        **Temporary ID Pattern for New Recipients**: When adding new recipients
        in a comprehensive update, use the '_temp_id' field (format: 'temp_X')
        instead of 'id' to establish relationships with fields and reminders.
        This allows you to create new recipients and reference them in
        fields/reminders in a single request. Use the 'id' field to update
        existing recipients. Validation rules: (1) Temporary IDs must start with
        'temp_'; (2) Each temporary ID must be unique within the request; (3)
        Fields and reminders can reference temporary IDs in their recipient_id
        property; (4) The API will automatically resolve temporary IDs to real
        UUIDs after recipient creation.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: Signing request ID
      requestBody:
        $ref: '#/components/requestBodies/UpdateSigningRequestBody'
      responses:
        '200':
          description: >-
            Signing request updated successfully. Returns summary of changes
            made.
          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:
                type: object
                properties:
                  signing_request:
                    $ref: '#/components/schemas/SigningRequest'
                  changes:
                    type: object
                    properties:
                      properties_updated:
                        type: boolean
                      recipients_created:
                        type: integer
                      recipients_updated:
                        type: integer
                      recipients_deleted:
                        type: integer
                      fields_created:
                        type: integer
                      fields_updated:
                        type: integer
                      fields_reassigned:
                        type: integer
                      reminders_created:
                        type: integer
                      reminders_updated:
                        type: integer
        '400':
          description: Validation errors. All section errors returned together.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                  details:
                    type: object
                    properties:
                      signing_request_properties:
                        type: array
                        items:
                          type: string
                      recipients:
                        type: array
                        items:
                          type: string
                      deleted_recipients:
                        type: array
                        items:
                          type: string
                      fields:
                        type: array
                        items:
                          type: string
                      reminders:
                        type: array
                        items:
                          type: string
              example:
                error: Validation failed
                message: Multiple validation errors occurred
                details:
                  recipients:
                    - 'Recipient 1: email is invalid'
                  deleted_recipients:
                    - 'Cannot reassign: designations must match (Signer vs CC)'
                  fields:
                    - 'Field 2: x coordinate must be between 0 and 100'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/RateLimitError'
      security:
        - ApiKeyAuth: []
components:
  requestBodies:
    UpdateSigningRequestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UpdateSigningRequestBodySchema'
          examples:
            comprehensive-update:
              summary: Comprehensive update with all sections
              value:
                signing_request_properties:
                  name: Updated Contract Name
                  expiration_hours: 72
                recipients:
                  - id: rec1-e89b-12d3-a456-426614174000
                    first_name: John
                    last_name: Smith
                    email: john.smith@example.com
                    designation: Signer
                    order: 1
                  - first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    designation: Signer
                    order: 2
                deleted_recipients:
                  - recipient_id: rec2-e89b-12d3-a456-426614174000
                    field_action: reassign
                    reassign_to_recipient_id: rec1-e89b-12d3-a456-426614174000
                fields:
                  - id: field1-e89b-12d3-a456-426614174000
                    type: signature
                    position:
                      x: 15
                      'y': 85
                      width: 30
                      height: 10
                    page_number: 1
                    required: true
                    recipient_id: rec1-e89b-12d3-a456-426614174000
                reminders:
                  - hours: 48
                    all_users: true
                    subject: 'Reminder: Please sign the document'
                    message: This is a reminder to complete your signature.
            update-with-temp-ids:
              summary: Update with new recipients using temporary IDs
              description: >-
                Comprehensive update adding new recipients with temporary IDs
                alongside existing recipients
              value:
                signing_request_properties:
                  name: Updated NDA Agreement
                recipients:
                  - id: existing-recipient-uuid
                    email: updated@example.com
                  - _temp_id: temp_new_signer
                    first_name: New
                    last_name: Signer
                    email: newsigner@example.com
                    designation: Signer
                    order: 2
                fields:
                  - id: existing-field-uuid
                    position:
                      x: 50
                      'y': 700
                      width: 150
                      height: 50
                  - recipient_id: temp_new_signer
                    type: signature
                    page_number: 1
                    position:
                      x: 50
                      'y': 600
                      width: 150
                      height: 50
                    required: true
                reminders:
                  - recipient_id: temp_new_signer
                    hours: 24
                    all_users: false
                    subject: 'Reminder: Sign Document'
                    message: Please sign the updated NDA.
  schemas:
    SigningRequest:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the signing request
        name:
          type: string
          description: Signing request name
          maxLength: 255
        description:
          type: string
          nullable: true
          description: Signing request description
        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 signing request 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 signing
            request again to receive a fresh signed URL.
        document_page_count:
          type: integer
          minimum: 1
          description: Number of pages in the document
        status:
          type: string
          enum:
            - not_sent
            - in_progress
            - finished
            - cancelled
            - deleted
            - expired
          description: Current status of the signing request
        expiration_hours:
          type: integer
          minimum: 1
          default: 168
          description: 'Hours until signing request expires (default: 168 = 7 days)'
        settings:
          $ref: '#/components/schemas/SigningRequestSettings'
        template_id:
          type: string
          format: uuid
          nullable: true
          description: ID of template used to create this signing request
        date_created:
          type: string
          format: date-time
          description: Signing request creation timestamp
        date_sent:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when the signing request was sent
        date_finished:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when all signatures were completed
        date_cancelled:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when signing request was cancelled
        expires_at:
          type: string
          format: date-time
          nullable: true
          description: Expiration timestamp
        certificate:
          type: object
          nullable: true
          description: Certificate generation status information
          properties:
            generated:
              type: boolean
              description: Whether the final certificate PDF has been generated
            generated_on:
              type: string
              format: date-time
              nullable: true
              description: Timestamp when certificate was generated
            has_error:
              type: boolean
              description: Whether there was an error generating the certificate
        final_document_download_url:
          type: string
          format: uri
          nullable: true
          description: >-
            Signed URL to download the final signed document (PDF with
            certificate). Only available when signing request is finished and
            certificate has been generated. URL expires after 1 hour.
        final_document_download_error:
          type: string
          nullable: true
          enum:
            - file_not_accessible
            - null
          description: >-
            Error indicator if the final document exists but could not be
            accessed. Value is 'file_not_accessible' when the file path exists
            but the file is missing or inaccessible, otherwise null.
    UpdateSigningRequestBodySchema:
      type: object
      properties:
        signing_request_properties:
          type: object
          description: Update signing request properties
          properties:
            name:
              type: string
              maxLength: 255
            description:
              type: string
            document:
              type: string
              format: byte
              description: Replace document (base64-encoded PDF)
            expiration_hours:
              type: integer
              minimum: 1
            settings:
              $ref: '#/components/schemas/SigningRequestSettings'
        recipients:
          type: array
          items:
            $ref: '#/components/schemas/Recipient'
          description: >-
            Upsert recipients - include 'id' to update existing recipients, use
            '_temp_id' (e.g., 'temp_1') for new recipients to reference them in
            fields and reminders within the same request
        deleted_recipients:
          type: array
          items:
            $ref: '#/components/schemas/DeletedRecipient'
          description: Recipients to delete and how to handle their fields
        fields:
          type: array
          items:
            $ref: '#/components/schemas/Field'
          description: Upsert fields - include id to update, omit id to create new
        reminders:
          type: array
          items:
            $ref: '#/components/schemas/SigningRequestReminder'
          description: Upsert reminders - include id to update, omit id to create new
    SigningRequestSettings:
      type: object
      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
        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
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human-readable error message
        message:
          type: string
          description: Detailed error description
        details:
          type: object
          description: Additional error details
          additionalProperties: true
    Recipient:
      type: object
      required:
        - first_name
        - email
        - designation
      description: >-
        Recipient schema with auto-construction and mapping behaviors. **Name
        field**: Auto-constructed from first_name and last_name ('First Last' if
        both present, otherwise 'First'). Manual name values are overwritten.
        **Order assignment**: ALL recipients MUST have an explicit order value.
        Order determines the signing sequence, which is always enforced.
        Recipients must sign in order, with lower numbers signing first.
        **Custom fields**: Supports both flat structure (e.g., company_name at
        root) and nested structure (custom_fields object). Both formats are
        normalized internally. **Template field mapping**: When creating from a
        template with custom recipients, use template_user_id or order to match
        template users. Only user info (name, email, phone, etc.) can be updated
        - order and designation are inherited from template. **Temporary IDs**:
        For document-based creation, use temporary IDs (format: 'temp_1',
        'temp_2', etc.) to reference recipients in fields and reminders before
        they're created.
      properties:
        id:
          type: string
          description: >-
            Unique identifier. For updates: use existing UUID. For
            document-based creation: optionally use temporary ID (format:
            'temp_1', 'temp_2', etc.) to reference recipients in fields and
            reminders before creation. Temporary IDs are automatically resolved
            to real UUIDs in the response.
        _temp_id:
          type: string
          description: >-
            Temporary identifier for new recipients in PUT (comprehensive
            update) requests (e.g., 'temp_1'). Use this when creating new
            recipients alongside existing ones in comprehensive updates. Must
            start with 'temp_' and be unique within the request. Not used for
            POST (create) requests - use 'id' field instead.
        template_user_id:
          type: string
          format: uuid
          description: >-
            When creating from a template, the ID of the template user to
            update. If provided, this recipient's data will update the matching
            template user. If not provided, falls back to matching by order.
            Only user info (name, email, phone, address, title, company) can be
            updated - order and designation are always inherited from the
            template.
        first_name:
          type: string
          maxLength: 100
          description: Recipient's first name
        last_name:
          type: string
          maxLength: 100
          description: >-
            Recipient's last name (optional, but required if using full_name or
            last_name prefilled variables)
        email:
          type: string
          format: email
          maxLength: 255
          description: Recipient's email address
        designation:
          type: string
          enum:
            - Signer
          description: Role of the recipient
        order:
          type: integer
          minimum: 1
          description: >-
            Signing sequence number. Recipients must sign in order, with lower
            numbers signing first. This field is required for all recipients.
        phone_number:
          type: string
          maxLength: 50
          nullable: true
          description: Recipient's phone number
        street_address:
          type: string
          maxLength: 255
          nullable: true
          description: Street address
        city:
          type: string
          maxLength: 100
          nullable: true
          description: City
        state_province:
          type: string
          maxLength: 100
          nullable: true
          description: State or province
        postal_code:
          type: string
          maxLength: 20
          nullable: true
          description: Postal/ZIP code
        country:
          type: string
          maxLength: 100
          nullable: true
          description: Country
        title:
          type: string
          maxLength: 100
          nullable: true
          description: Job title
        company:
          type: string
          maxLength: 255
          nullable: true
          description: Company name
        custom_fields:
          type: object
          additionalProperties: true
          description: Custom key-value pairs for additional recipient data
    DeletedRecipient:
      type: object
      required:
        - recipient_id
        - field_action
      properties:
        recipient_id:
          type: string
          format: uuid
          description: ID of recipient to delete
        field_action:
          type: string
          enum:
            - delete
            - reassign
          description: Action to take with fields assigned to this recipient
        reassign_to_recipient_id:
          type: string
          format: uuid
          description: >-
            Recipient to reassign fields to (required if field_action is
            'reassign')
    Field:
      type: object
      required:
        - type
        - position
        - page_number
      description: >-
        Field definition for signing requests. **Read-only fields**: Set
        read_only=true to pre-fill a field value that signers cannot edit. Use
        read_only_value for static text, or prefilled_data to auto-populate from
        recipient attributes.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (include for updates, omit for new fields)
        type:
          type: string
          enum:
            - signature
            - text
            - date
            - checkbox
            - dropdown
            - initials
            - image
          description: Type of field
        position:
          type: object
          required:
            - x
            - 'y'
            - width
            - height
          properties:
            x:
              type: number
              minimum: 0
              maximum: 100
              description: X coordinate as percentage (0-100)
            'y':
              type: number
              minimum: 0
              maximum: 100
              description: Y coordinate as percentage (0-100)
            width:
              type: number
              minimum: 0
              maximum: 100
              description: Width as percentage (0-100)
            height:
              type: number
              minimum: 0
              maximum: 100
              description: Height as percentage (0-100)
        page_number:
          type: integer
          minimum: 1
          description: Page number where field is located
        required:
          type: boolean
          default: false
          description: Whether field must be completed
        recipient_id:
          type: string
          description: >-
            ID of recipient assigned to this field. Use real UUID for
            template-based creation or updates, or temporary ID (e.g., 'temp_1')
            for document-based creation to reference recipients defined in the
            same request.
        variable_name:
          type: string
          maxLength: 100
          nullable: true
          description: Variable name for field (used in templates)
        dropdown_options:
          type: array
          items:
            type: string
          description: Options for dropdown fields
        date_default:
          type: string
          format: date
          nullable: true
          description: Default date value
        date_signing_default:
          type: boolean
          default: false
          description: Use signing date as default
        multi_group_id:
          type: string
          format: uuid
          nullable: true
          description: Group ID for multi-instance fields
        format_rules:
          oneOf:
            - $ref: '#/components/schemas/DateFormatRules'
            - type: object
              additionalProperties: true
          nullable: true
          description: >-
            Formatting rules for field value. For date fields, use
            DateFormatRules schema with dateFormat property. Predefined formats:
            MM/dd/yyyy, dd/MM/yyyy, yyyy-MM-dd, MMMM dd yyyy, MMM dd yyyy, dd
            MMMM yyyy. Custom formats supported using yyyy (year), MM (month),
            dd (day), MMMM (full month name), MMM (abbreviated month), HH
            (hour), mm (minute), ss (second).
        validation_rules:
          $ref: '#/components/schemas/FieldValidationRules'
        read_only:
          type: boolean
          default: false
          description: >-
            Whether this field is read-only (pre-filled before signing). When
            true, the signer cannot edit the field value. Useful for displaying
            contract terms, recipient information, or other fixed data.
        read_only_value:
          type: string
          nullable: true
          description: >-
            Static value for read-only fields. Takes precedence over
            prefilled_data if both are specified. Only applicable when read_only
            is true. Example: 'Contract #12345' or 'Acme Corporation'.
        prefilled_data:
          type: string
          nullable: true
          enum:
            - first_name
            - last_name
            - full_name
            - email
            - phone_number
            - company
            - title
            - street_address
            - city
            - state_province
            - postal_code
            - country
          description: >-
            User attribute to auto-populate when read_only is true. Value is
            pulled from the assigned recipient's data at signing time. Can also
            reference custom_fields keys defined on the recipient (not limited
            to enum values). Only applicable when read_only is true and
            read_only_value is not set. Example: Set to 'email' to display the
            recipient's email address.
    SigningRequestReminder:
      type: object
      required:
        - hours
        - subject
        - message
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (include for updates, omit for new reminders)
        hours:
          type: integer
          minimum: 1
          description: Hours before expiration to send reminder
        all_users:
          type: boolean
          default: false
          description: Send reminder to all recipients
        recipient_id:
          type: string
          nullable: true
          description: >-
            Specific recipient ID (required if all_users is false). Use real
            UUID for existing recipients or temporary ID (e.g., 'temp_1') for
            document-based creation to reference recipients in the same request.
        subject:
          type: string
          maxLength: 255
          description: Email subject line
        message:
          type: string
          maxLength: 5000
          description: Email message body
    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
      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.

````