{
  "openapi": "3.0.3",
  "info": {
    "title": "Firma Partner API",
    "description": "RESTful API for document signing and template management.\n\n**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.\n\n**Security Features**:\n- Input validation using Zod schemas with detailed field-level error messages\n- RSA-256 signed JWT tokens for embedded template access\n\n**Rate Limiting**: Rate limits are tiered based on operation type:\n- Read operations (GET): 200 requests per minute\n- Write operations (POST/PUT/PATCH/DELETE): 120 requests per minute\n- Webhook CRUD operations: 60 requests per minute\n- Webhook test: 10 requests per minute\n- API key regeneration/expiration: 1 request per minute\n- Webhook secret rotation: 1 request per minute\n\nWhen rate limits are exceeded, the API returns a `429 Too Many Requests` response with headers:\n- `X-RateLimit-Limit`: Maximum requests per minute for this endpoint\n- `X-RateLimit-Remaining`: Requests remaining in current window\n- `X-RateLimit-Reset`: Unix timestamp when limit resets\n- `Retry-After`: Seconds until retry is allowed\n\n**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).\n\n**Embedded Template Integration**: The Firma Template Editor can be embedded in your application using a standalone JavaScript library.\n\n```html\n<!-- Load the Firma Template Editor library -->\n<script src=\"https://api.firma.dev/functions/v1/embed-proxy/template-editor.js\"></script>\n\n<script>\n// Generate JWT token via API first\nfetch('https://api.firma.dev/functions/v1/signing-request-api/generate-template-token', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'YOUR_API_KEY',\n    'Content-Type': 'application/json'\n  },\n  body: JSON.stringify({\n    companies_workspaces_templates_id: 'template-id'\n  })\n})\n.then(res => res.json())\n.then(data => {\n  // Initialize editor with JWT token\n  window.FirmaTemplateEditor.init({\n    container: '#firma-editor-container',\n    jwt: data.token,\n    templateId: 'template-id',\n    theme: 'dark',\n    readOnly: false,\n    onSave: (savedData) => {\n      console.log('Template saved:', savedData);\n    },\n    onError: (error) => {\n      console.error('Editor error:', error);\n    },\n    onLoad: (template) => {\n      console.log('Template loaded:', template);\n    }\n  });\n});\n```\n\n**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.\n\n**Multi-document documents (API 01.39.00, available to every company)**: 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 for every company. While multi-document editing is suspended, parents on the multi-document read-only path keep their single-resource reads and document downloads (a template can still be deleted), but other edits answer `409 MULTI_DOCUMENT_READ_ONLY`; parents on the single-document path have no `/documents` routes (`404 NOT_FOUND`) or multi-document response keys, and list and create responses omit those keys.\n\n**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 handles seal versions and suspended multi-document editing. `GET /templates/{id}` returns `seal_participants`, and `POST /templates` answers `warnings` when its body contains keys it ignores.",
    "version": "01.40.00",
    "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"
    }
  ],
  "components": {
    "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."
      }
    },
    "responses": {
      "ValidationError": {
        "description": "Bad Request - Validation failed",
        "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"
              }
            }
          }
        }
      },
      "UnauthorizedError": {
        "description": "Unauthorized - Invalid or missing API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Unauthorized",
              "message": "Invalid API key"
            }
          }
        }
      },
      "ForbiddenError": {
        "description": "Forbidden - Insufficient permissions",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Forbidden",
              "message": "You do not have permission to access this resource"
            }
          }
        }
      },
      "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
              }
            }
          }
        }
      }
    },
    "requestBodies": {
      "PatchSigningRequestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PatchSigningRequestBodySchema"
            },
            "examples": {
              "update-properties": {
                "summary": "Update properties",
                "value": {
                  "name": "Updated Contract Name",
                  "expiration_hours": 72
                }
              },
              "update-recipient": {
                "summary": "Update single recipient",
                "value": {
                  "recipient": {
                    "id": "rec123-e89b-12d3-a456-426614174000",
                    "first_name": "John",
                    "last_name": "Smith",
                    "email": "john.smith@example.com",
                    "designation": "Signer",
                    "order": 1
                  }
                }
              },
              "add-recipient": {
                "summary": "Add new recipient",
                "value": {
                  "recipient": {
                    "first_name": "Jane",
                    "last_name": "Doe",
                    "email": "jane@example.com",
                    "designation": "Signer",
                    "order": 2
                  }
                }
              },
              "add-date-field": {
                "summary": "Add date field with formatting",
                "value": {
                  "field": {
                    "type": "date",
                    "position": {
                      "x": 70,
                      "y": 45,
                      "width": 15,
                      "height": 3
                    },
                    "page_number": 1,
                    "required": true,
                    "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                    "date_signing_default": true,
                    "format_rules": {
                      "dateFormat": "MMMM dd, yyyy"
                    }
                  }
                }
              },
              "add-read-only-static-field": {
                "summary": "Add read-only field with static value",
                "description": "Creates a text field that displays a fixed value the signer cannot edit",
                "value": {
                  "field": {
                    "type": "text",
                    "position": {
                      "x": 15,
                      "y": 20,
                      "width": 40,
                      "height": 3
                    },
                    "page_number": 1,
                    "required": false,
                    "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                    "read_only": true,
                    "read_only_value": "Contract #12345 - Acme Corporation"
                  }
                }
              },
              "add-read-only-prefilled-field": {
                "summary": "Add read-only field with recipient data",
                "description": "Creates a text field that auto-populates with the recipient's email address (signer cannot edit)",
                "value": {
                  "field": {
                    "type": "text",
                    "position": {
                      "x": 15,
                      "y": 30,
                      "width": 30,
                      "height": 3
                    },
                    "page_number": 1,
                    "required": false,
                    "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                    "read_only": true,
                    "prefilled_data": "email"
                  }
                }
              }
            }
          }
        }
      },
      "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": 10,
                        "y": 70,
                        "width": 30,
                        "height": 10
                      }
                    },
                    {
                      "recipient_id": "temp_new_signer",
                      "type": "signature",
                      "page_number": 1,
                      "position": {
                        "x": 10,
                        "y": 55,
                        "width": 30,
                        "height": 10
                      },
                      "required": true
                    }
                  ],
                  "reminders": [
                    {
                      "recipient_id": "temp_new_signer",
                      "hours": 24,
                      "all_users": false,
                      "subject": "Reminder: Sign Document",
                      "message": "Please sign the updated NDA."
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Company": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the company"
          },
          "name": {
            "type": "string",
            "description": "Company name",
            "maxLength": 255
          },
          "language": {
            "type": "string",
            "description": "Default language for the company",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb",
              "ca"
            ],
            "default": "en"
          },
          "account_owner": {
            "type": "string",
            "description": "Name of the account owner",
            "maxLength": 255
          },
          "account_owner_email": {
            "type": "string",
            "format": "email",
            "description": "Email address of the account owner"
          },
          "website": {
            "type": "string",
            "format": "uri",
            "description": "Company website URL",
            "nullable": true
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "Publicly accessible URL to the company logo image. Returns null if no logo is set.",
            "nullable": true,
            "example": "https://ielmshcswdhuacyjlpiy.supabase.co/functions/v1/logo/company/3feb35a8-5aaf-4603-8b50-acd807176b38"
          },
          "credits": {
            "type": "integer",
            "description": "Available credits for the company (read-only, managed internally)",
            "minimum": 0,
            "readOnly": true
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Company account creation timestamp"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Company account last update timestamp"
          }
        },
        "required": [
          "id",
          "name",
          "account_owner",
          "account_owner_email",
          "created_date"
        ]
      },
      "Workspace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the workspace"
          },
          "name": {
            "type": "string",
            "description": "Workspace name",
            "maxLength": 255
          },
          "protected": {
            "type": "boolean",
            "description": "Protected workspaces cannot be deleted"
          },
          "api_key": {
            "type": "string",
            "description": "Live-mode API key for this workspace. Used for authenticating API requests scoped to this workspace.",
            "nullable": true
          },
          "test_api_key": {
            "type": "string",
            "description": "Test-mode API key for this workspace. Requests authenticated with this key do not consume credits and produce test-flagged, watermarked signing requests.",
            "nullable": true
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Workspace creation timestamp"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Workspace last update timestamp"
          },
          "webhook_enabled": {
            "type": "boolean",
            "description": "Whether workspace-level webhooks are enabled"
          },
          "webhook_secret": {
            "type": "string",
            "description": "Webhook signing secret for this workspace",
            "nullable": true
          },
          "webhook_secret_rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the last webhook secret rotation",
            "nullable": true
          },
          "webhook_secret_created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the webhook secret was first created",
            "nullable": true
          },
          "ignore_company_webhooks": {
            "type": "boolean",
            "description": "When true, company-level webhooks do not fire for events in this workspace"
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "Publicly accessible URL to the workspace logo image. Returns the workspace-specific logo, or null if not set (company logo is NOT included as fallback in this field).",
            "nullable": true,
            "example": "https://ielmshcswdhuacyjlpiy.supabase.co/functions/v1/logo/workspace/company-id/workspace-id"
          }
        },
        "required": [
          "id",
          "name",
          "created_date"
        ]
      },
      "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 for every company). 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. While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          },
          "documents_version": {
            "type": "integer",
            "description": "Version of the document set, raised by every document change (multi-document; available to every company). While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          },
          "documents_layout_version": {
            "type": "integer",
            "description": "Version of the document layout, raised when documents are added, removed or reordered (multi-document; available to every company). Field writes on a signing request with more than one document send it back as `documents_layout_version`. While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          }
        },
        "required": [
          "id",
          "name",
          "created_date"
        ]
      },
      "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"
                }
              }
            }
          }
        ]
      },
      "TemplateCreateResponse": {
        "description": "The created template: every key of Template, plus `warnings` when the request body contained keys this operation ignores.",
        "allOf": [
          {
            "$ref": "#/components/schemas/Template"
          },
          {
            "type": "object",
            "properties": {
              "warnings": {
                "type": "array",
                "description": "Present only when the request body contained `seal_participants`, `recipients` or `fields` (the key being present is enough, whatever its value, including `null` or `[]`). One string per such key, in the order seal_participants, recipients, fields.",
                "items": {
                  "type": "string"
                },
                "example": [
                  "seal_participants is not accepted on POST /templates and was ignored; add it with PATCH or PUT /templates/{id}"
                ]
              }
            }
          }
        ]
      },
      "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"
        ]
      },
      "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"
        }
      },
      "TextFormatRules": {
        "type": "object",
        "description": "Formatting rules for text-bearing fields (text, textarea, email, name, phone, company, title, number, dropdown, url).",
        "properties": {
          "fontSize": {
            "type": "integer",
            "minimum": 8,
            "maximum": 48,
            "description": "Optional starting/maximum font size in pixels for the rendered field value, applied in the signing view and the sealed PDF. Text still auto-shrinks to fit the field box, so the explicit size is a ceiling, not a guarantee. Omit for automatic sizing (default 14px base). Values outside 8-48 are clamped; non-numeric values are ignored. Not applicable to signature, initials, checkbox, radio, file, or stamp fields."
          }
        },
        "example": {
          "fontSize": 12
        }
      },
      "FileFormatRules": {
        "type": "object",
        "description": "Formatting rules for file upload fields. Specifies which file types signers are allowed to upload.",
        "properties": {
          "acceptedFileTypes": {
            "type": "string",
            "enum": [
              "image_and_pdf",
              "image",
              "pdf"
            ],
            "default": "image_and_pdf",
            "description": "Accepted file types for upload. 'image_and_pdf' accepts JPG, PNG, and PDF. 'image' accepts JPG and PNG only. 'pdf' accepts PDF only. Files are validated by magic bytes, not just extension. Maximum file size is 10MB."
          }
        },
        "example": {
          "acceptedFileTypes": "image_and_pdf"
        }
      },
      "FieldValidationRules": {
        "type": "object",
        "nullable": true,
        "description": "Validation rules for field values. Reserved for future use - currently not enforced for any field types.",
        "additionalProperties": true
      },
      "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"
        ]
      },
      "Reminder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the reminder"
          },
          "hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Hours after sending before reminder is sent"
          },
          "subject": {
            "type": "string",
            "description": "Email subject for the reminder",
            "maxLength": 255
          },
          "message": {
            "type": "string",
            "description": "Email message body for the reminder",
            "maxLength": 5000
          },
          "all_users": {
            "type": "boolean",
            "description": "Whether reminder applies to all users"
          },
          "template_user_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Specific user to send reminder to (used in template context)"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Specific recipient to send reminder to (used in signing request context, same as template_user_id)"
          },
          "sent_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the reminder was actually sent"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Reminder creation timestamp"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Reminder last update timestamp"
          }
        },
        "required": [
          "id",
          "hours",
          "subject",
          "message"
        ]
      },
      "SigningRequestListItem": {
        "type": "object",
        "description": "Signing request as returned by the LIST endpoint (GET /signing-requests)",
        "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"
          },
          "status": {
            "type": "string",
            "enum": [
              "not_sent",
              "in_progress",
              "finished",
              "cancelled",
              "declined",
              "deleted",
              "expired"
            ],
            "description": "Current status of the signing request"
          },
          "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."
          },
          "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 request expires (default: 168 = 7 days)"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "ISO 8601 timestamp when the signing request expires. Computed from sent_date + expiration_hours. Null if the signing request has not been sent yet or has no expiration_hours set."
          },
          "credit_cost": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Number of credits consumed when this signing request was sent. Minimum value is 1."
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Template ID if created from a template"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the signing request was sent"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When all signatures were completed"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the signing request was cancelled"
          },
          "declined_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the signing request was declined"
          },
          "recipients": {
            "type": "array",
            "description": "Signing request recipients (simplified shape)",
            "items": {
              "$ref": "#/components/schemas/SigningRequestListRecipient"
            }
          },
          "fields": {
            "type": "array",
            "description": "Signing request fields with nested position object",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "signature",
                    "date",
                    "checkbox",
                    "dropdown",
                    "radio_buttons",
                    "number",
                    "text_area",
                    "file",
                    "initial",
                    "stamp",
                    "approval_signature",
                    "approval_checkmark",
                    "approval_date"
                  ]
                },
                "required": {
                  "type": "boolean"
                },
                "recipient_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true
                },
                "variable_name": {
                  "type": "string",
                  "nullable": true
                },
                "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",
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "width": {
                      "type": "number"
                    },
                    "height": {
                      "type": "number"
                    }
                  }
                },
                "value": {
                  "type": "string",
                  "nullable": true,
                  "description": "Final value of the field after signing"
                },
                "dropdown_options": {
                  "nullable": true,
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "object"
                    }
                  ]
                },
                "format_rules": {
                  "$ref": "#/components/schemas/DateFormatRules",
                  "nullable": true
                },
                "validation_rules": {
                  "$ref": "#/components/schemas/FieldValidationRules"
                }
              }
            }
          },
          "seal_participants": {
            "type": "array",
            "description": "Organization seal participants in the signing order. Empty when the request has no seals.",
            "items": {
              "$ref": "#/components/schemas/SealParticipantApi"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentSummary"
            },
            "description": "The signing request's documents in position order (multi-document; present for every company). 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). While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          },
          "documents_version": {
            "type": "integer",
            "nullable": true,
            "description": "Version of the document set, raised by every document change (multi-document; available to every company). While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          },
          "documents_layout_version": {
            "type": "integer",
            "nullable": true,
            "description": "Version of the document layout, raised when documents are added, removed or reordered (multi-document; available to every company). Field writes on a signing request with more than one document send it back as `documents_layout_version`. While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "created_date"
        ]
      },
      "SigningRequestListRecipient": {
        "type": "object",
        "description": "Recipient as returned in LIST signing request responses (simplified shape)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the recipient"
          },
          "name": {
            "type": "string",
            "description": "Combined full name"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Recipient email address"
          },
          "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": "Signing order"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When this recipient completed signing"
          },
          "signature_details": {
            "type": "object",
            "nullable": true,
            "description": "Details about the recipient's signature"
          }
        }
      },
      "SigningRequestCreateResponse": {
        "type": "object",
        "description": "Signing request as returned by CREATE endpoints (POST /signing-requests)",
        "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"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft"
            ],
            "description": "Status is always 'draft' for newly created signing requests"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "Pre-signed URL to the PDF document"
          },
          "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 request expires (default: 168 = 7 days)"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Template ID if created from a template"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the signing request was sent"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When all signatures were completed"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the signing request was cancelled"
          },
          "recipients": {
            "type": "array",
            "description": "Signing request recipients",
            "items": {
              "$ref": "#/components/schemas/SigningRequestCreateRecipient"
            }
          },
          "fields": {
            "type": "array",
            "description": "Signing request fields with flat position values",
            "items": {
              "$ref": "#/components/schemas/SigningRequestCreateField"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional non-blocking warnings, including unusual recipient email formats, unknown anchor-tag properties during the compatibility window, and anchor-processing warnings."
          },
          "seal_participants": {
            "type": "array",
            "description": "Organization seal participants in the signing order. Empty when the request has no seals. Each item is either a persisted seal participant (`dropped: false`) or, on a template-based request, an entry for a template seal that was not copied because the API key's company cannot see the seal or because the seal is limited to another workspace (`dropped: true`, `id` and `order` null, `seal_out_of_scope: true`). Dropped entries come after the persisted ones, in template order. Template seals that an explicit `seal_participants` array replaced are not listed.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/SealParticipantCreated"
                },
                {
                  "$ref": "#/components/schemas/SealParticipantDropped"
                }
              ]
            }
          }
        },
        "required": [
          "id",
          "name",
          "status"
        ]
      },
      "SigningRequestCreateRecipient": {
        "type": "object",
        "description": "Recipient as returned in CREATE signing request responses",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the recipient"
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Recipient first name"
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Recipient last name"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Combined full name (auto-constructed from first_name + last_name)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Recipient email address"
          },
          "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": "Signing order"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Recipient phone number"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Street address"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "City"
          },
          "state_province": {
            "type": "string",
            "nullable": true,
            "description": "State or province"
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Postal code"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Country"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "description": "Job title"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "description": "Company name"
          },
          "custom_fields": {
            "type": "object",
            "nullable": true,
            "description": "Custom key-value pairs"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When this recipient completed signing"
          }
        },
        "required": [
          "first_name",
          "email",
          "designation"
        ]
      },
      "SigningRequestCreateField": {
        "type": "object",
        "description": "Field as returned in CREATE signing request responses (flat position, database-style)",
        "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"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID of assigned recipient"
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Page number (1-indexed)"
          },
          "x_position": {
            "type": "number",
            "description": "X coordinate as percentage (0-100)"
          },
          "y_position": {
            "type": "number",
            "description": "Y coordinate as percentage (0-100)"
          },
          "width": {
            "type": "number",
            "description": "Width as percentage (0-100)"
          },
          "height": {
            "type": "number",
            "description": "Height as percentage (0-100)"
          },
          "required": {
            "type": "boolean",
            "description": "Whether the field is required"
          },
          "read_only": {
            "type": "boolean",
            "description": "Whether this field is read-only"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Static value for read-only fields"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Variable name for prefilled data mapping"
          },
          "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."
          },
          "dropdown_options": {
            "nullable": true,
            "description": "Options for dropdown fields",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "format_rules": {
            "type": "object",
            "nullable": true,
            "description": "Formatting rules (e.g., date format)"
          },
          "validation_rules": {
            "type": "object",
            "nullable": true,
            "description": "Validation rules for the field"
          },
          "date_signing_default": {
            "type": "boolean",
            "description": "Whether to use signing date as default"
          },
          "final_value": {
            "type": "string",
            "nullable": true,
            "description": "Pre-filled or final value of the field"
          }
        },
        "required": [
          "type",
          "recipient_id",
          "page_number"
        ]
      },
      "SigningRequestDetail": {
        "type": "object",
        "description": "Detailed signing request as returned by GET /signing-requests/{id} (nested shape with status object and timestamps)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the signing request"
          },
          "name": {
            "type": "string",
            "description": "Signing request name"
          },
          "template_description": {
            "type": "string",
            "nullable": true,
            "description": "Description from the template"
          },
          "companies_workspaces_id": {
            "type": "string",
            "format": "uuid",
            "description": "Workspace ID this signing request belongs to"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "Pre-signed URL to the PDF document"
          },
          "document_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "document_page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of pages in the document"
          },
          "expiration_hours": {
            "type": "integer",
            "description": "Hours until signing request expires"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "ISO 8601 timestamp when the signing request expires. Computed from sent_on + expiration_hours. Null if not sent yet or no expiration_hours set."
          },
          "credit_cost": {
            "type": "integer",
            "description": "Credits consumed when sent"
          },
          "status": {
            "type": "object",
            "description": "Status flags (multiple can be true for terminal states)",
            "properties": {
              "sent": {
                "type": "boolean"
              },
              "finished": {
                "type": "boolean"
              },
              "cancelled": {
                "type": "boolean"
              },
              "declined": {
                "type": "boolean"
              },
              "expired": {
                "type": "boolean"
              }
            }
          },
          "timestamps": {
            "type": "object",
            "description": "All relevant timestamps for the signing request lifecycle",
            "properties": {
              "created_on": {
                "type": "string",
                "format": "date-time"
              },
              "sent_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "finished_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "cancelled_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "declined_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "last_changed_on": {
                "type": "string",
                "format": "date-time"
              },
              "last_signing_action_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "use_signing_order": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "allow_download": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "allow_editing_before_sending": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "hand_drawn_only": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "attach_pdf_on_finish": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "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). URL expires after 1 hour."
          },
          "final_document_download_error": {
            "type": "string",
            "nullable": true,
            "enum": [
              "file_not_accessible",
              null
            ]
          },
          "document_only_download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Signed URL to download the document-only PDF. URL expires after 1 hour."
          },
          "document_only_download_error": {
            "type": "string",
            "nullable": true,
            "enum": [
              "file_not_accessible",
              null
            ]
          },
          "certificate_only_download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Signed URL to download the certificate-only PDF. URL expires after 1 hour."
          },
          "certificate_only_download_error": {
            "type": "string",
            "nullable": true,
            "enum": [
              "file_not_accessible",
              null
            ]
          },
          "seal_participants": {
            "type": "array",
            "description": "Organization seal participants in the signing order. Empty when the request has no seals.",
            "items": {
              "$ref": "#/components/schemas/SealParticipantApi"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentSummary"
            },
            "description": "The signing request's documents in position order (multi-document; present for every company). A parent whose document set has never been changed answers its one document, with `document_id` null. While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          },
          "documents_version": {
            "type": "integer",
            "description": "Version of the document set, raised by every document change (multi-document; available to every company). While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          },
          "documents_layout_version": {
            "type": "integer",
            "description": "Version of the document layout, raised when documents are added, removed or reordered (multi-document; available to every company). Field writes on a signing request with more than one document send it back as `documents_layout_version`. While multi-document editing is suspended, this key is absent on the single-document path and in list and create responses."
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "companies_workspaces_id"
        ]
      },
      "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."
          },
          "allow_decline": {
            "type": "boolean",
            "nullable": true,
            "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. Inherits from the workspace or company setting when null."
          },
          "show_save_for_later": {
            "type": "boolean",
            "nullable": true,
            "description": "Show the Save & Finish Later button on the signing page. Inherits from the 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."
          }
        }
      },
      "TemplateSettings": {
        "type": "object",
        "description": "Settings returned by the template endpoints. Matches SigningRequestSettings minus the signer-identity fields (identity_editable_fields, notify_identity_change_email), which apply only to signing requests.",
        "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.",
            "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 = inherit from workspace/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. Inherits from workspace or company setting when null."
          },
          "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."
          },
          "allow_decline": {
            "type": "boolean",
            "nullable": true,
            "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. Inherits from the workspace or company setting when null."
          },
          "show_save_for_later": {
            "type": "boolean",
            "nullable": true,
            "description": "Show the Save & Finish Later button on the signing page. Inherits from the workspace or company setting when null."
          }
        }
      },
      "LegacyDocumentSettings": {
        "type": "object",
        "description": "Settings returned by the deprecated POST /documents endpoint. A reduced set; new integrations should use the signing request endpoints, which return SigningRequestSettings.",
        "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.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "When enabled, signers can only hand-draw their 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
          },
          "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. Inherits from workspace or company setting when null."
          }
        }
      },
      "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. A recipient with designation CC is never matched to a template user; it is added as a CC recipient, and the template's CC recipients are copied to the signing request, skipping any whose email (case-insensitive) is already on a CC recipient of the request. **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. **CC recipients**: CC recipients receive a completed copy but cannot sign or have fields assigned. At least one Signer is required. An existing recipient cannot be changed between CC and Signer/Approver (400); delete it and create it again.",
        "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. Not used for CC recipients, which are never matched to a template user."
          },
          "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",
              "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": "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"
          }
        }
      },
      "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. **Template-based field merging**: When creating from a template with fields array, use template_field_id (preferred) or variable_name (fallback) to match template fields. Only provided properties override template defaults (partial update). Fields not matched are ignored.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier (include for updates, omit for new fields)"
          },
          "template_field_id": {
            "type": "string",
            "format": "uuid",
            "description": "Template field ID to match for partial updates (template-based creation only). Use this to identify which template field to override. Takes precedence over variable_name for matching."
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "text",
              "date",
              "checkbox",
              "dropdown",
              "initial",
              "initials",
              "text_area",
              "textarea",
              "image",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Type of field. Accepts 'initial' or 'initials' (normalized to 'initial'), 'textarea' or 'text_area' (normalized to 'text_area')."
          },
          "position": {
            "type": "object",
            "required": [
              "x",
              "y",
              "width",
              "height"
            ],
            "description": "Field must fit within page bounds: x + width <= 100 and y + height <= 100",
            "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). x + width must be <= 100"
              },
              "height": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Height as percentage (0-100). y + height must be <= 100"
              }
            }
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Page number where field is located (1-indexed). Must not exceed the document's total page count."
          },
          "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). Also used as fallback for field matching in template-based creation when template_field_id is not provided."
          },
          "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."
          },
          "dropdown_options": {
            "description": "Options for dropdown fields",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "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 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."
          },
          "format_rules": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DateFormatRules"
              },
              {
                "$ref": "#/components/schemas/FileFormatRules"
              },
              {
                "type": "object",
                "additionalProperties": true
              }
            ],
            "nullable": true,
            "description": "Formatting rules for field value. For date fields, use DateFormatRules schema with dateFormat property. For file fields, use FileFormatRules schema with acceptedFileTypes property (image_and_pdf, image, or pdf). For url fields, use { urlDisplayText: string }. Text-bearing fields (text, textarea, email, name, phone, company, title, number, dropdown, url, date) additionally accept an optional fontSize property (integer px, 8-48, clamped) - see TextFormatRules."
          },
          "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."
          },
          "required_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Conditional rules for when this field is required. When set, overrides the static 'required' flag. The field is required only when the conditions evaluate to true based on other field values."
          },
          "visibility_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Conditional rules for when this field is visible. When set, the field is hidden unless the conditions evaluate to true. Hidden fields are not validated on submission."
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
            "description": "Background color for the field as a hex color string (e.g., '#FFFDE7', '#fff'). Useful for highlighting fields that need attention.",
            "example": "#FFFDE7"
          },
          "seal_participant_temp_id": {
            "type": "string",
            "nullable": true,
            "description": "Temporary ID of the seal participant this field is assigned to (matches temp_id in seal_participants array). Used during creation to link fields to seal participants defined in the same request."
          }
        }
      },
      "AnchorTag": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "anchor_string",
          "type",
          "recipient_id"
        ],
        "description": "Anchor tag definition for automatic field placement. Anchor tags are text markers embedded in a PDF document (e.g., '{{SIGN_HERE}}') that are automatically located and converted into positioned fields. The anchor text is removed from the PDF after processing by default.",
        "properties": {
          "anchor_string": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Text string to search for in the PDF document. Common patterns include '{{SIGN_HERE}}', '{{DATE}}', etc.",
            "example": "{{SIGN_HERE}}"
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "initial",
              "initials",
              "text",
              "date",
              "checkbox",
              "radio_buttons",
              "radio",
              "dropdown",
              "textarea",
              "text_area",
              "url",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Type of field to place at the anchor location"
          },
          "recipient_id": {
            "oneOf": [
              {
                "type": "integer"
              },
              {
                "type": "string"
              }
            ],
            "description": "ID of the recipient assigned to this field. Use temporary ID (e.g., 'temp_1') for document-based creation or integer order for template-based.",
            "example": "temp_1"
          },
          "x_offset": {
            "type": "number",
            "description": "Horizontal offset from anchor position. Units determined by offset_units (default: percent of page width).",
            "default": 0
          },
          "y_offset": {
            "type": "number",
            "description": "Vertical offset from anchor position. Units determined by offset_units (default: percent of page height).",
            "default": 0
          },
          "offset_units": {
            "type": "string",
            "enum": [
              "percent",
              "pixels"
            ],
            "default": "percent",
            "description": "Unit type for x_offset and y_offset. 'percent' = percentage of page dimensions, 'pixels' = PDF points (72 DPI)."
          },
          "width": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Field width as percentage of page width. Defaults vary by field type (e.g., signature=25, text=20, checkbox=3)."
          },
          "height": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Field height as percentage of page height. Defaults vary by field type (e.g., signature=5, text=3, checkbox=3)."
          },
          "case_sensitive": {
            "type": "boolean",
            "default": false,
            "description": "Whether anchor string matching is case-sensitive"
          },
          "match_whole_word": {
            "type": "boolean",
            "default": true,
            "description": "Whether to match whole words only (bounded by non-word characters)"
          },
          "ignore_if_not_present": {
            "type": "boolean",
            "default": false,
            "description": "If true, skip this anchor without error when not found in the document. If false (default), a missing anchor causes a validation error."
          },
          "occurrence": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "default": 0,
            "description": "Which occurrence to place a field on. 0 = all occurrences (default), 1 = first only, 2 = second only, etc."
          },
          "remove_anchor_text": {
            "type": "boolean",
            "default": true,
            "description": "Whether to remove the anchor text using corrected glyph geometry and sub-pixel text removal. Defaults to true."
          },
          "add_white_background": {
            "type": "boolean",
            "default": false,
            "description": "Whether to draw a white background across the full resolved field rectangle. This is independent of anchor-text removal."
          },
          "required": {
            "type": "boolean",
            "default": true,
            "description": "Whether the field must be completed by the signer"
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Whether the field is read-only (pre-filled)"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "maxLength": 10000,
            "description": "Static value for read-only fields"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "description": "Variable name for the field"
          },
          "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."
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
            "description": "Background color as hex (e.g., '#FFFDE7')",
            "example": "#FFFDE7"
          },
          "font_size": {
            "type": "integer",
            "minimum": 8,
            "maximum": 48,
            "description": "Optional starting/maximum font size in pixels for text-bearing field types, stored on the resolved field as format_rules.fontSize (see TextFormatRules). Text still auto-shrinks to fit the field box. Omit for automatic sizing. Values outside 8-48 are clamped; non-numeric values are ignored.",
            "example": 12
          },
          "dropdown_options": {
            "description": "Options for dropdown fields",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "date_default": {
            "type": "string",
            "nullable": true,
            "maxLength": 50,
            "description": "Default date value"
          },
          "date_signing_default": {
            "type": "boolean",
            "default": false,
            "description": "Use signing date as default"
          },
          "multi_group_id": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "description": "Group ID for linking checkbox/radio fields"
          },
          "document_index": {
            "type": "integer",
            "minimum": 1,
            "description": "1-based index into `document_ids` of the document this tag is searched in. Optional with one document (defaults to 1); required with more than one (`400 ANCHOR_DOCUMENT_REQUIRED`); out of range answers `400 VALIDATION_ERROR`."
          }
        }
      },
      "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"
          }
        }
      },
      "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."
          }
        }
      },
      "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."
          }
        }
      },
      "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"
          }
        }
      },
      "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')"
          }
        }
      },
      "SigningRequestUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the signing request 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": "Signing order"
          },
          "finished_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when this recipient completed all actions"
          },
          "declined_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when this recipient declined to sign"
          },
          "decline_reason": {
            "type": "string",
            "nullable": true,
            "description": "Reason provided by recipient for declining"
          },
          "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"
          },
          "custom_fields": {
            "type": "object",
            "nullable": true,
            "description": "Custom field values for this recipient"
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of recipient data fields required for sending (based on 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.)"
                },
                "has_value": {
                  "type": "boolean",
                  "description": "Whether this read-only field has a value set"
                }
              }
            },
            "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"
        ]
      },
      "SigningRequestField": {
        "type": "object",
        "description": "Field associated with a signing request, containing position, type, and value information",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the field"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "initial",
              "dropdown",
              "radio_buttons",
              "text_area",
              "url",
              "file",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Type of the field. Clean alias for field_type."
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID of the recipient assigned to this field. Clean alias for companies_workspaces_signing_requests_users_id."
          },
          "value": {
            "type": "string",
            "nullable": true,
            "description": "Final signed value of the field. Clean alias for final_value."
          },
          "position": {
            "type": "object",
            "description": "Position and dimensions of the field on the document. All values are percentages (0-100).",
            "properties": {
              "x": {
                "type": "number",
                "nullable": true,
                "description": "X position (percentage, 0-100). Clean alias for x_postion."
              },
              "y": {
                "type": "number",
                "nullable": true,
                "description": "Y position (percentage, 0-100). Clean alias for y_position."
              },
              "width": {
                "type": "number",
                "nullable": true,
                "description": "Width (percentage, 0-100)."
              },
              "height": {
                "type": "number",
                "nullable": true,
                "description": "Height (percentage, 0-100). Clean alias for heigh."
              }
            }
          },
          "companies_workspaces_signing_requests_id": {
            "type": "string",
            "format": "uuid",
            "description": "Deprecated: redundant with path parameter. ID of the signing request this field belongs to."
          },
          "companies_workspaces_signing_requests_users_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Deprecated: use 'recipient_id' instead. ID of the recipient assigned to this field."
          },
          "field_type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "initial",
              "dropdown",
              "radio_buttons",
              "text_area",
              "url",
              "file",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Deprecated: use 'type' instead. Type of the field."
          },
          "required": {
            "type": "boolean",
            "description": "Whether the field is required."
          },
          "x_postion": {
            "type": "number",
            "nullable": true,
            "description": "Deprecated: use 'position.x' instead. X position (note: column name has typo)."
          },
          "y_position": {
            "type": "number",
            "nullable": true,
            "description": "Deprecated: use 'position.y' instead. Y position of the field."
          },
          "width": {
            "type": "number",
            "nullable": true,
            "description": "Deprecated: use 'position.width' instead. Width of the field."
          },
          "heigh": {
            "type": "number",
            "nullable": true,
            "description": "Deprecated: use 'position.height' instead. Height (note: column name has typo)."
          },
          "page_number": {
            "type": "integer",
            "nullable": true,
            "description": "Page number where the field is located (1-indexed)"
          },
          "tl_position": {
            "type": "number",
            "nullable": true,
            "description": "Top-left corner position"
          },
          "tr_position": {
            "type": "number",
            "nullable": true,
            "description": "Top-right corner position"
          },
          "bl_position": {
            "type": "number",
            "nullable": true,
            "description": "Bottom-left corner position"
          },
          "br_position": {
            "type": "number",
            "nullable": true,
            "description": "Bottom-right corner position"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Variable name for prefilled data mapping"
          },
          "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."
          },
          "final_value": {
            "type": "string",
            "nullable": true,
            "description": "Deprecated: use 'value' instead. Final signed value of the field."
          },
          "date_default": {
            "type": "string",
            "nullable": true,
            "description": "Default date value"
          },
          "date_signing_default": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether to use signing date as default."
          },
          "format_rules": {
            "type": "object",
            "nullable": true,
            "description": "Formatting rules (e.g., date format)"
          },
          "validation_rules": {
            "type": "object",
            "nullable": true,
            "description": "Validation rules for the field"
          },
          "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."
          },
          "read_only": {
            "type": "boolean",
            "description": "Whether the field is read-only."
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Static value for read-only fields"
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "description": "Background color as hex (e.g., '#FFFDE7')"
          },
          "calculated_font_size": {
            "type": "number",
            "nullable": true,
            "description": "Calculated font size for the field"
          },
          "deleted": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Deprecated: internal field, will be removed in v2. Soft delete flag (0 = active, 1 = deleted)."
          }
        },
        "required": [
          "id",
          "field_type",
          "page_number"
        ]
      },
      "SendSigningRequestResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the signing request was sent successfully"
          },
          "message": {
            "type": "string",
            "description": "Success message"
          },
          "sentTo": {
            "type": "string",
            "format": "email",
            "description": "Email address the signing request was sent to"
          },
          "sentAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the request was sent"
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the webhook"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Webhook URL"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Webhook description"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Events that trigger this webhook"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the webhook is enabled"
          },
          "consecutive_failures": {
            "type": "integer",
            "description": "Number of consecutive delivery failures"
          },
          "auto_disabled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the webhook was auto-disabled due to failures"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Webhook creation timestamp"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Webhook last update timestamp"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "enabled",
          "created_at"
        ]
      },
      "PatchSigningRequestBodySchema": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "document"
            ],
            "description": "Create signing request from a PDF document",
            "properties": {
              "document": {
                "type": "string",
                "format": "byte",
                "description": "Base64-encoded PDF or DOCX document. DOCX files are automatically converted to PDF. Page count will be auto-extracted. For documents larger than 5 MB, use POST /documents and pass the document_id instead."
              },
              "name": {
                "type": "string",
                "maxLength": 255,
                "description": "Name for the signing request"
              },
              "description": {
                "type": "string",
                "description": "Description for the signing request"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1,
                "default": 168,
                "description": "Hours until the signing request expires (default: 168 = 7 days)"
              },
              "recipients": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Recipient"
                },
                "description": "Recipients for the signing request. Use temporary IDs (e.g., 'temp_1') in the id field to reference recipients in fields/reminders."
              },
              "fields": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Field"
                },
                "description": "Fields to place on the document. Use recipient_id to assign fields to recipients."
              },
              "anchor_tags": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/AnchorTag"
                },
                "description": "Anchor tags for automatic field placement. Text markers in the PDF are located and converted to positioned fields. The anchor text is removed from the PDF after processing. Fields created from anchor tags are added alongside any manually specified fields. Only available for document-based creation (not template-based)."
              },
              "reminders": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SigningRequestReminder"
                },
                "description": "Reminders to send to recipients"
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings",
                "description": "Signing request settings"
              },
              "language": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "en",
                  "es",
                  "it",
                  "pt",
                  "fr",
                  "de",
                  "el",
                  "ru",
                  "pl",
                  "cs",
                  "sv",
                  "nl",
                  "ro",
                  "nb",
                  "ca"
                ],
                "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
              },
              "completion_title": {
                "type": "string",
                "nullable": true,
                "description": "Heading shown on the completion page after signing. Inherits from the workspace, then the company, when omitted or null.",
                "maxLength": 200
              },
              "completion_message": {
                "type": "string",
                "nullable": true,
                "description": "Body text shown on the completion page after signing. Inherits from the workspace, then the company, when omitted or null.",
                "maxLength": 1000
              },
              "completion_redirect_url": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Inherits from the workspace, then the company, when omitted or null.",
                "maxLength": 2000
              },
              "completion_redirect_delay": {
                "type": "integer",
                "nullable": true,
                "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Inherits from the workspace, then the company, when omitted or null.",
                "minimum": 0,
                "maximum": 30
              },
              "seal_participants": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SealParticipantInput"
                },
                "description": "Organization seal participants to include in the signing sequence. `null` is treated like an absent key; any other value that is not an array answers 400 `VALIDATION_ERROR`. The seal `order` values and the recipients' `order` values must form one contiguous sequence starting at 1: a gap answers 400 `INVALID_SIGNING_ORDER`, two of them (recipients or seals) sharing an `order` answer 400 `SEAL_ORDER_COLLISION`, and every recipient needs an `order` when a seal is present. A non-empty array requires organization seals to be enabled; otherwise the call answers 503 `SEALS_DISABLED`.",
                "nullable": true
              }
            }
          },
          {
            "type": "object",
            "required": [
              "template_id"
            ],
            "description": "Create signing request from a template. Supports partial updates for both recipients and fields.",
            "properties": {
              "template_id": {
                "type": "string",
                "format": "uuid",
                "description": "ID of the template to create signing request from. The document, fields, and default recipients will be copied from the template.\n\n**Seals.** If the template has seal participants and `seal_participants` is absent or `null`, the request inherits them and the template fields that belong to them. An array, including `[]`, replaces them: the template's seal participants and their fields are not copied. Any other type answers 400 `VALIDATION_ERROR`. A kept seal and the recipients are renumbered together into one contiguous order sequence that keeps the template's relative order. When the template has no recipients of its own, its inherited seals keep their place first and the request's recipients follow them. A template seal follows the current version of its lineage: the request attaches the current version, not the version the template points at. If that current version is revoked or deleted, or the lineage has no current version, the call answers 409 `SEAL_UNAVAILABLE` and creates nothing. A template seal that the API key's company cannot see, or whose current version is limited to a workspace other than the API key's workspace, is not copied and neither are its fields; the request is still created and `seal_participants` lists the seal as a dropped entry (`dropped: true`). If a seal would be kept while organization seals are not enabled, the call answers 503 `SEALS_DISABLED`."
              },
              "name": {
                "type": "string",
                "maxLength": 255,
                "description": "Custom name for signing request (defaults to template name if not provided)"
              },
              "description": {
                "type": "string",
                "description": "Custom description (defaults to template description if not provided)"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1,
                "description": "Override template expiration hours"
              },
              "recipients": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Recipient"
                },
                "description": "Optional recipient overrides. Use template_user_id (preferred) or order (fallback) to match template users. Only user info (first_name, last_name, email, phone_number, address fields, title, company) can be updated - order and designation are always inherited from template. Recipients not provided will use template defaults. Recipients with designation CC are never matched to template users; they are added as CC recipients. The template's CC recipients are copied to the signing request, skipping any whose email (case-insensitive) is already on a CC recipient of the request."
              },
              "fields": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Field"
                },
                "description": "Optional field overrides for partial updates. Use template_field_id (preferred) or variable_name (fallback) to match template fields. Only provided properties override template defaults. Supported override properties: type, required, position, read_only, read_only_value, format_rules, validation_rules, dropdown_options, date_default, date_signing_default, multi_group_id. Fields not matched are ignored. If fields array is omitted, all template fields are used as-is."
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings",
                "description": "Override template settings"
              },
              "language": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "en",
                  "es",
                  "it",
                  "pt",
                  "fr",
                  "de",
                  "el",
                  "ru",
                  "pl",
                  "cs",
                  "sv",
                  "nl",
                  "ro",
                  "nb",
                  "ca"
                ],
                "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
              },
              "completion_title": {
                "type": "string",
                "nullable": true,
                "description": "Heading shown on the completion page after signing. Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                "maxLength": 200
              },
              "completion_message": {
                "type": "string",
                "nullable": true,
                "description": "Body text shown on the completion page after signing. Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                "maxLength": 1000
              },
              "completion_redirect_url": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                "maxLength": 2000
              },
              "completion_redirect_delay": {
                "type": "integer",
                "nullable": true,
                "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                "minimum": 0,
                "maximum": 30
              },
              "seal_participants": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SealParticipantInput"
                },
                "description": "Organization seal participants for the new signing request: with `template_id`, omit the key or send `null` to inherit the template's seals, send `[]` for no seals, or send an array to replace them. A replaced template seal and its fields are not copied. Any other type answers 400 `VALIDATION_ERROR`. On a template-based request the seal orders and the recipients' orders are renumbered together into one contiguous sequence, whether the seals are inherited or sent in the array. A non-empty array, or an inherited seal that would be kept, requires organization seals to be enabled; otherwise the call answers 503 `SEALS_DISABLED`.",
                "nullable": true
              }
            },
            "example": {
              "template_id": "21424147-11c0-43d5-ac5f-a1f7001b5607",
              "name": "Contract for Client X",
              "recipients": [
                {
                  "template_user_id": "template-user-uuid-1",
                  "first_name": "Toni",
                  "last_name": "Campins",
                  "email": "acampins@cocodin.com"
                }
              ],
              "fields": [
                {
                  "template_field_id": "field-uuid-1",
                  "read_only": true,
                  "read_only_value": "Contract #12345"
                },
                {
                  "variable_name": "company_name",
                  "read_only_value": "Acme Corporation"
                }
              ]
            }
          }
        ]
      },
      "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"
              },
              "completion_title": {
                "type": "string",
                "nullable": true,
                "description": "Heading shown on the completion page after signing. Null or an empty string clears the override.",
                "maxLength": 200
              },
              "completion_message": {
                "type": "string",
                "nullable": true,
                "description": "Body text shown on the completion page after signing. Null or an empty string clears the override.",
                "maxLength": 1000
              },
              "completion_redirect_url": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Null or an empty string clears the override.",
                "maxLength": 2000
              },
              "completion_redirect_delay": {
                "type": "integer",
                "nullable": true,
                "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Null clears the override.",
                "minimum": 0,
                "maximum": 30
              }
            }
          },
          "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. An existing recipient cannot be changed between CC and Signer/Approver (400); delete it and create it again."
          },
          "deleted_recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeletedRecipient"
            },
            "description": "Recipients to delete and how to handle their fields"
          },
          "force_remove_conditions": {
            "type": "boolean",
            "default": false,
            "description": "When deleting recipients 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 listing the dependent 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"
          },
          "language": {
            "type": "string",
            "nullable": true,
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb",
              "ca"
            ],
            "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
          },
          "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 signing request 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`."
          }
        }
      },
      "GenerateJWTRequest": {
        "type": "object",
        "required": [
          "companies_workspaces_templates_id"
        ],
        "properties": {
          "companies_workspaces_templates_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the template to generate JWT for"
          }
        }
      },
      "GenerateJWTResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "The generated JWT token"
          },
          "jwt_record_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this JWT record"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "JWT expiration timestamp (30 days from creation)"
          }
        },
        "required": [
          "token",
          "expires_at"
        ]
      },
      "RevokeJWTRequest": {
        "type": "object",
        "required": [
          "jwt_id"
        ],
        "properties": {
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the JWT token to revoke"
          }
        }
      },
      "RevokeJWTResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Confirmation message"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the revoked JWT"
          },
          "revoked": {
            "type": "boolean",
            "description": "Whether the JWT was successfully revoked"
          }
        },
        "required": [
          "message"
        ]
      },
      "GenerateSigningRequestJWTRequest": {
        "type": "object",
        "required": [
          "companies_workspaces_signing_requests_id"
        ],
        "properties": {
          "companies_workspaces_signing_requests_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the signing request to generate JWT for"
          }
        }
      },
      "GenerateSigningRequestJWTResponse": {
        "type": "object",
        "properties": {
          "jwt": {
            "type": "string",
            "description": "The generated JWT token"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "JWT expiration timestamp (7 days from creation)"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the signing request this JWT is for"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the JWT was created"
          }
        },
        "required": [
          "jwt",
          "expires_at",
          "signing_request_id"
        ]
      },
      "RevokeSigningRequestJWTRequest": {
        "type": "object",
        "required": [
          "jwt_id"
        ],
        "properties": {
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the JWT token to revoke"
          }
        }
      },
      "RevokeSigningRequestJWTResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Confirmation message"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the revoked JWT"
          },
          "revoked": {
            "type": "boolean",
            "description": "Whether the JWT was successfully revoked"
          }
        },
        "required": [
          "message"
        ]
      },
      "ColorPalette": {
        "type": "object",
        "description": "Resolved color palette for the signing experience. All values are hex color strings (#rrggbb).",
        "properties": {
          "primary": {
            "type": "string",
            "description": "Primary action color (buttons, links, accents)",
            "example": "#2563eb"
          },
          "primary_fg": {
            "type": "string",
            "description": "Text color on primary-colored elements",
            "example": "#ffffff"
          },
          "background": {
            "type": "string",
            "description": "Page/canvas background color",
            "example": "#1c1c21"
          },
          "foreground": {
            "type": "string",
            "description": "Main text color",
            "example": "#ffffff"
          },
          "card": {
            "type": "string",
            "description": "Card/panel background color",
            "example": "#22222a"
          },
          "border": {
            "type": "string",
            "description": "Border and divider color",
            "example": "#3b3b3b"
          },
          "accent": {
            "type": "string",
            "description": "Editor chrome accent",
            "example": "#34eeff"
          },
          "accent_fg": {
            "type": "string",
            "description": "Foreground on accent",
            "example": "#000000"
          },
          "canvas": {
            "type": "string",
            "description": "Editor document-canvas surround",
            "example": "#0f1419"
          },
          "muted": {
            "type": "string",
            "description": "Muted surface (defaults to the resolved card)",
            "example": "#22222a"
          },
          "muted_fg": {
            "type": "string",
            "description": "Muted text (derived for readability when unset)",
            "example": "#b8b8b8"
          }
        }
      },
      "CompanySettings": {
        "type": "object",
        "properties": {
          "default_expiration_hours": {
            "type": "integer",
            "minimum": 1
          },
          "require_terms_acceptance": {
            "type": "boolean"
          },
          "show_custom_branding_only": {
            "type": "boolean"
          },
          "require_otp_verification": {
            "type": "boolean"
          },
          "allow_presigning_download": {
            "type": "boolean"
          },
          "disable_guided_navigation": {
            "type": "boolean"
          },
          "show_signature_frame": {
            "type": "boolean"
          },
          "show_partial_watermark": {
            "type": "boolean"
          },
          "email_local_part": {
            "type": "string"
          },
          "color_primary": {
            "type": "string",
            "nullable": true
          },
          "color_primary_fg": {
            "type": "string",
            "nullable": true
          },
          "color_background": {
            "type": "string",
            "nullable": true
          },
          "color_foreground": {
            "type": "string",
            "nullable": true
          },
          "color_card": {
            "type": "string",
            "nullable": true
          },
          "color_border": {
            "type": "string",
            "nullable": true
          },
          "color_accent": {
            "type": "string",
            "nullable": true
          },
          "color_accent_fg": {
            "type": "string",
            "nullable": true
          },
          "color_canvas": {
            "type": "string",
            "nullable": true
          },
          "color_muted": {
            "type": "string",
            "nullable": true
          },
          "color_muted_fg": {
            "type": "string",
            "nullable": true
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Show a QR code on the signing page that lets signers continue on their phone. This is the company-level default; workspaces, templates, and signing requests can override it."
          },
          "allow_decline": {
            "type": "boolean",
            "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. This is the company-level default; workspaces, templates and signing requests can override it."
          },
          "show_save_for_later": {
            "type": "boolean",
            "description": "Show the Save & Finish Later button on the signing page. This is the company-level default; workspaces, templates and signing requests can override it."
          },
          "completion_title": {
            "type": "string",
            "nullable": true,
            "description": "Company-level default heading for the completion page shown after signing. Workspaces, templates, and signing requests can override it. Null means no company default, so the built-in translated heading is used.",
            "maxLength": 200
          },
          "completion_message": {
            "type": "string",
            "nullable": true,
            "description": "Company-level default body text for the completion page shown after signing. Workspaces, templates, and signing requests can override it. Null means no company default, so the built-in translated message is used.",
            "maxLength": 1000
          },
          "completion_redirect_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Company-level default URL the signer is redirected to from the completion page. Must use https://. Workspaces, templates, and signing requests can override it. Null means no redirect unless a lower level sets one.",
            "pattern": "^https://",
            "maxLength": 2000
          },
          "completion_redirect_delay": {
            "type": "integer",
            "nullable": true,
            "description": "Company-level default number of seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay.",
            "minimum": 0,
            "maximum": 30
          },
          "default_timezone": {
            "type": "string",
            "description": "IANA timezone identifier used as the company-wide default for certificates and email timestamps.",
            "example": "Europe/Paris"
          },
          "language": {
            "type": "string",
            "description": "Default language for company emails and certificates.",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb",
              "ca"
            ],
            "example": "en"
          }
        },
        "required": [
          "default_expiration_hours"
        ]
      },
      "WorkspaceSettings": {
        "type": "object",
        "properties": {
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Workspace name"
          },
          "team_email": {
            "type": "string",
            "format": "email",
            "description": "Workspace contact email"
          },
          "timezone": {
            "type": "string",
            "description": "Workspace timezone"
          },
          "language": {
            "type": "string",
            "description": "Workspace language for email templates",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb",
              "ca"
            ],
            "default": "en"
          },
          "signing_request_email_header": {
            "type": "string",
            "description": "Custom email header text"
          },
          "signing_request_email_body": {
            "type": "string",
            "description": "Custom HTML email body"
          },
          "show_credit_cost_in_editor": {
            "type": "boolean",
            "description": "Whether to display credit cost in embedded template and signing request editors",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether signers must verify their email via OTP before accessing documents. null = inherit from company setting, true = require OTP, false = do not require OTP"
          },
          "require_terms_acceptance": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether signers must accept terms before signing. null inherits the company-level setting."
          },
          "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."
          },
          "show_signature_frame": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether to render a visual frame with Signature ID around signatures in completed PDFs. null = inherit from company setting (default enabled), true = show frame, false = hide frame"
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Allow signers to download the original document before signing. null inherits the company-level setting."
          },
          "show_partial_watermark": {
            "type": "boolean",
            "nullable": true,
            "description": "Show an IN PROGRESS watermark on partial PDF downloads when not all signers have completed. null inherits the company-level setting."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Show a QR code on the signing page that lets signers continue on their phone. null inherits the company-level setting."
          },
          "allow_decline": {
            "type": "boolean",
            "nullable": true,
            "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. null inherits the company-level setting."
          },
          "show_save_for_later": {
            "type": "boolean",
            "nullable": true,
            "description": "Show the Save & Finish Later button on the signing page. null inherits the company-level setting."
          },
          "color_primary": {
            "type": "string",
            "nullable": true,
            "description": "Primary color override (#rrggbb hex). Null to inherit from company.",
            "example": "#2563eb"
          },
          "color_primary_fg": {
            "type": "string",
            "nullable": true,
            "description": "Primary foreground color override. Null to inherit.",
            "example": "#ffffff"
          },
          "color_background": {
            "type": "string",
            "nullable": true,
            "description": "Background color override. Null to inherit.",
            "example": "#0f172a"
          },
          "color_foreground": {
            "type": "string",
            "nullable": true,
            "description": "Foreground/text color override. Null to inherit.",
            "example": "#ffffff"
          },
          "color_card": {
            "type": "string",
            "nullable": true,
            "description": "Card background color override. Null to inherit.",
            "example": "#22222a"
          },
          "color_border": {
            "type": "string",
            "nullable": true,
            "description": "Border color override. Null to inherit.",
            "example": "#3b3b3b"
          },
          "color_accent": {
            "type": "string",
            "nullable": true,
            "description": "Editor chrome accent color. Null to inherit.",
            "example": "#34eeff"
          },
          "color_accent_fg": {
            "type": "string",
            "nullable": true,
            "description": "Foreground color on accent surfaces. Null to inherit.",
            "example": "#000000"
          },
          "color_canvas": {
            "type": "string",
            "nullable": true,
            "description": "Editor document-canvas surround color. Null to inherit.",
            "example": "#0f1419"
          },
          "color_muted": {
            "type": "string",
            "nullable": true,
            "description": "Muted surface color. Null to inherit.",
            "example": "#22222a"
          },
          "color_muted_fg": {
            "type": "string",
            "nullable": true,
            "description": "Muted text color. Null to inherit.",
            "example": "#b8b8b8"
          },
          "email_local_part": {
            "type": "string",
            "nullable": true,
            "description": "The local-part (before the @) of the sender email address. Null to inherit from company setting. Only applies when a verified custom domain is configured.",
            "example": "signatures",
            "pattern": "^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$",
            "minLength": 1,
            "maxLength": 64
          },
          "signing_button_label_overrides": {
            "type": "object",
            "nullable": true,
            "description": "Per-language custom button labels for the signing view. Keys are language codes (en, de, etc.); values are objects mapping translation keys to custom text. Null to use defaults.",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          },
          "completion_title": {
            "type": "string",
            "nullable": true,
            "description": "Heading shown on the completion page after signing. Null inherits the company-level setting; the built-in translated heading is used when unset at every level.",
            "example": "Thank you for signing",
            "maxLength": 200
          },
          "completion_message": {
            "type": "string",
            "nullable": true,
            "description": "Body text shown on the completion page after signing. Null inherits the company-level setting; the built-in translated message is used when unset at every level.",
            "example": "Your signed copy is on its way to your inbox.",
            "maxLength": 1000
          },
          "completion_redirect_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL the signer is redirected to from the completion page. Must use https://. Null inherits the company-level setting; no redirect happens when unset at every level. The completion page only honors this server-resolved URL.",
            "example": "https://example.com/thank-you",
            "pattern": "^https://",
            "maxLength": 2000
          },
          "completion_redirect_delay": {
            "type": "integer",
            "nullable": true,
            "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves. Null inherits the company-level setting; the page falls back to 5 seconds when unset at every level.",
            "example": 5,
            "minimum": 0,
            "maximum": 30
          }
        },
        "required": [
          "workspace_id"
        ]
      },
      "WorkspaceCustomField": {
        "type": "object",
        "description": "A custom field definition for a workspace",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier"
          },
          "field_name": {
            "type": "string",
            "description": "Machine-readable field name (auto-generated from label)"
          },
          "field_label": {
            "type": "string",
            "description": "Human-readable display label"
          },
          "is_preset": {
            "type": "boolean",
            "description": "If true, this field has a preset value for all users"
          },
          "preset_value": {
            "type": "string",
            "nullable": true,
            "description": "Preset value (only used when is_preset=true)"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name",
          "field_label"
        ]
      },
      "TemplateCustomField": {
        "type": "object",
        "description": "A custom field definition for a template",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier"
          },
          "field_name": {
            "type": "string",
            "description": "Machine-readable field name"
          },
          "field_label": {
            "type": "string",
            "description": "Human-readable display label"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name"
        ]
      },
      "SigningRequestCustomField": {
        "type": "object",
        "description": "A custom field definition for a signing request",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier"
          },
          "field_name": {
            "type": "string",
            "description": "Machine-readable field name"
          },
          "field_label": {
            "type": "string",
            "description": "Human-readable display label"
          },
          "copied_from_template": {
            "type": "boolean",
            "description": "True if this field was copied from a template"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name"
        ]
      },
      "Domain": {
        "type": "object",
        "description": "Email domain configuration for sending signing request emails",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the domain"
          },
          "domain": {
            "type": "string",
            "description": "The domain name (e.g., 'example.com')"
          },
          "verification_status": {
            "type": "integer",
            "enum": [
              0,
              1,
              2
            ],
            "description": "Domain ownership verification status: 0=pending, 1=ownership verified (TXT record confirmed), 2=finalized (registered with email provider)"
          },
          "domain_status": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Email sending status: 0=DNS records pending verification, 1=fully verified and ready to send"
          },
          "is_primary": {
            "type": "boolean",
            "description": "Whether this is the primary domain for sending emails from this workspace"
          },
          "verification_token": {
            "type": "string",
            "description": "Token to add as TXT record for domain ownership verification. Only returned when verification_status=0."
          },
          "resend_domain_id": {
            "type": "string",
            "nullable": true,
            "description": "External email provider domain ID (internal use)"
          },
          "dns_records": {
            "type": "array",
            "nullable": true,
            "description": "Required DNS records for email sending. Only returned after domain finalization (verification_status=2).",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            }
          },
          "date_created": {
            "type": "string",
            "format": "date-time",
            "description": "Domain creation timestamp"
          },
          "date_changed": {
            "type": "string",
            "format": "date-time",
            "description": "Domain last update timestamp"
          }
        },
        "required": [
          "id",
          "domain",
          "domain_status",
          "verification_status"
        ]
      },
      "DomainDnsRecord": {
        "type": "object",
        "description": "DNS record required for email domain verification",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "TXT",
              "CNAME",
              "MX"
            ],
            "description": "DNS record type"
          },
          "name": {
            "type": "string",
            "description": "DNS record name/host (e.g., 'resend._domainkey' or '@')"
          },
          "value": {
            "type": "string",
            "description": "DNS record value"
          },
          "ttl": {
            "type": "string",
            "description": "Time to live (e.g., 'Auto' or seconds)"
          },
          "priority": {
            "type": "integer",
            "nullable": true,
            "description": "Priority for MX records"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ],
            "description": "Verification status of this specific record"
          }
        }
      },
      "EmailTemplate": {
        "type": "object",
        "description": "Custom email template for signing request notifications",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the email template"
          },
          "email_type": {
            "type": "string",
            "enum": [
              "signing_invite",
              "next_signer",
              "signing_expired",
              "signing_cancelled",
              "signing_declined"
            ],
            "description": "Type of email this template is for"
          },
          "subject": {
            "type": "string",
            "description": "Email subject line"
          },
          "body": {
            "type": "string",
            "description": "Email body (HTML). Supports placeholders like {{signing_link}}, {{signer_name}}, etc."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Template creation timestamp"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Template last update timestamp"
          }
        },
        "required": [
          "email_type",
          "subject",
          "body"
        ]
      },
      "SignerTerms": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb",
              "ca"
            ]
          },
          "statement_text": {
            "type": "string",
            "description": "Sanitized HTML consent statement"
          },
          "terms_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Optional external terms link"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "language",
          "statement_text"
        ]
      },
      "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": "\n\nOrganization 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"
      },
      "SigningRequestDownloadResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "finished",
              "in_progress",
              "cancelled",
              "declined",
              "expired"
            ],
            "description": "Signing request status. `finished` means all signers have completed. `in_progress` means signing is still ongoing and this is a partial download. `cancelled`, `declined`, and `expired` indicate terminal states where the document is a partial snapshot from the point when signing ended."
          },
          "is_partial": {
            "type": "boolean",
            "description": "Whether this download URL points to a partially-signed document (not all signers have completed)."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "Pre-signed URL to download the PDF document. Expires at the time indicated by `expires_at`."
          },
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "ISO 8601 timestamp when the document was last generated. For partial downloads, this is when the partial PDF was created."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp when the `download_url` expires. Fetch this endpoint again for a fresh URL after expiry."
          }
        },
        "required": [
          "status",
          "is_partial",
          "download_url",
          "expires_at"
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "current_page": {
            "type": "integer"
          },
          "page_size": {
            "type": "integer"
          },
          "total_count": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          }
        },
        "description": "Pagination metadata for list responses",
        "required": [
          "current_page",
          "page_size",
          "total_count",
          "total_pages"
        ]
      },
      "WorkspaceListResponse": {
        "type": "object",
        "description": "Paginated list of workspaces",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Workspace"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "TemplateListResponse": {
        "type": "object",
        "description": "Paginated list of templates",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Template"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "SigningRequestListResponse": {
        "type": "object",
        "description": "Paginated list of signing requests",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestListItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "WebhookListResponse": {
        "type": "object",
        "description": "Paginated list of webhooks",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Webhook"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "MessageResponse": {
        "type": "object",
        "description": "Simple success response with a message",
        "properties": {
          "message": {
            "type": "string",
            "description": "Success message"
          }
        },
        "required": [
          "message"
        ]
      },
      "TemplateUserListResponse": {
        "type": "object",
        "description": "List of template users",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateUser"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "TemplateFieldListResponse": {
        "type": "object",
        "description": "List of template fields",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateField"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "SigningRequestUserListResponse": {
        "type": "object",
        "description": "List of signing request users",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestUser"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "SigningRequestFieldListResponse": {
        "type": "object",
        "description": "List of signing request fields",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestField"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "AuditTrailListResponse": {
        "type": "object",
        "description": "List of audit trail entries",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "timestamp": {
                  "type": "string",
                  "format": "date-time"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "admin",
                    "signer"
                  ],
                  "description": "Whether the event was triggered by an admin/API or a signer"
                },
                "event": {
                  "type": "string",
                  "description": "Event type identifier"
                },
                "description": {
                  "type": "string",
                  "description": "Human-readable event description"
                },
                "actor": {
                  "type": "object",
                  "nullable": true,
                  "description": "Who performed the action (signer name/email or admin/API key)"
                },
                "ip_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "IP address of the signer (signer events only)"
                },
                "details": {
                  "type": "object",
                  "nullable": true,
                  "description": "Additional event-specific metadata"
                }
              }
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "CompanyEmailTemplateListResponse": {
        "type": "object",
        "description": "List of company email templates",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailTemplate"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "DomainListResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Domain"
            }
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Workspace ID for scoped results"
          }
        },
        "description": "List of domains with workspace context",
        "required": [
          "results"
        ]
      },
      "DomainCreateResponse": {
        "type": "object",
        "properties": {
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "verification_instructions": {
            "type": "object",
            "properties": {
              "record_type": {
                "type": "string",
                "example": "TXT"
              },
              "record_name": {
                "type": "string",
                "example": "_firma-verification.acme.com"
              },
              "record_value": {
                "type": "string",
                "example": "firma-verify=abc123xyz"
              },
              "next_step": {
                "type": "string",
                "example": "Add this TXT record to your DNS, then call POST /company/domains/{id}/verify-ownership"
              }
            }
          }
        },
        "description": "Domain created with verification instructions",
        "required": [
          "domain",
          "verification_instructions"
        ]
      },
      "DomainDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "Domain deletion confirmation",
        "required": [
          "message",
          "domain_id"
        ]
      },
      "DomainVerifyOwnershipResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "next_step": {
            "type": "string"
          }
        },
        "description": "Domain ownership verification result",
        "required": [
          "message",
          "domain",
          "next_step"
        ]
      },
      "DomainFinalizeResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "dns_records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            },
            "description": "DNS records to add for email sending"
          },
          "next_step": {
            "type": "string"
          }
        },
        "description": "Domain finalization with DNS records",
        "required": [
          "message",
          "domain",
          "dns_records",
          "next_step"
        ]
      },
      "DomainVerifyDnsResponse": {
        "type": "object",
        "properties": {
          "verified": {
            "type": "boolean",
            "description": "Whether all DNS records are verified"
          },
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "dns_records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            },
            "description": "Status of each DNS record"
          }
        },
        "description": "DNS verification result",
        "required": [
          "verified",
          "message",
          "domain"
        ]
      },
      "DomainSetPrimaryResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          }
        },
        "description": "Primary domain update confirmation",
        "required": [
          "message",
          "domain"
        ]
      },
      "RotateSecretResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "new_secret": {
            "type": "string",
            "description": "The new webhook signing secret (64 character hex string)"
          },
          "grace_period_hours": {
            "type": "integer",
            "description": "Hours the old secret remains valid alongside the new one"
          },
          "warning": {
            "type": "string",
            "description": "Reminder to update webhook signature verification"
          }
        },
        "description": "Secret rotation result with grace period",
        "required": [
          "message",
          "new_secret",
          "grace_period_hours"
        ]
      },
      "SecretStatusResponse": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the webhook secret was created",
            "nullable": true
          },
          "last_rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the webhook secret was last rotated",
            "nullable": true
          },
          "grace_period_active": {
            "type": "boolean",
            "description": "Whether the old secret is still valid alongside the new one"
          },
          "grace_period_ends_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the old secret grace period expires",
            "nullable": true
          }
        },
        "description": "Webhook secret status and rotation info",
        "required": [
          "created_at"
        ]
      },
      "EmailTemplateDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "email_type": {
            "type": "string"
          }
        },
        "description": "Email template deletion confirmation",
        "required": [
          "message",
          "email_type"
        ]
      },
      "SignerTermsListResponse": {
        "type": "object",
        "properties": {
          "terms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SignerTerms"
            }
          }
        },
        "description": "List of signer terms by language",
        "required": [
          "terms"
        ]
      },
      "SignerTermsUpdateResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "storedHtml": {
            "type": "string",
            "description": "The sanitized HTML actually stored"
          },
          "changed": {
            "type": "boolean",
            "description": "Whether sanitization altered the submitted statement"
          }
        },
        "description": "Signer terms update result",
        "required": [
          "ok"
        ]
      },
      "SignerTermsDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "language": {
            "type": "string"
          }
        },
        "description": "Signer terms deletion confirmation",
        "required": [
          "message",
          "language"
        ]
      },
      "CustomFieldListResponse": {
        "type": "object",
        "properties": {
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkspaceCustomField"
            }
          }
        },
        "description": "List of custom fields",
        "required": [
          "custom_fields"
        ]
      },
      "LogoUploadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "Public URL to the uploaded logo"
          }
        },
        "description": "Logo upload confirmation with URL",
        "required": [
          "success",
          "icon_url"
        ]
      },
      "LogoDeleteResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "description": "Logo deletion confirmation",
        "required": [
          "success"
        ]
      },
      "ApiKeyRegenerateResponse": {
        "type": "object",
        "properties": {
          "new_key": {
            "type": "object",
            "description": "The newly generated API key",
            "properties": {
              "api_key": {
                "type": "string",
                "description": "The new API key value"
              },
              "created_at": {
                "type": "string",
                "format": "date-time",
                "description": "When the key was created"
              }
            }
          },
          "key_type": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ],
            "description": "The key type that was regenerated"
          },
          "expiring_keys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "api_key": {
                  "type": "string",
                  "description": "The expiring API key value"
                },
                "expires_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "List of keys that were set to expire in 24 hours"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "API key regeneration result",
        "required": [
          "new_key",
          "key_type",
          "workspace_id"
        ]
      },
      "ApiKeyExpireResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the operation succeeded"
          },
          "expired_keys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "api_key": {
                  "type": "string",
                  "description": "The expired API key value"
                },
                "original_expires_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the key was originally set to expire"
                },
                "expired_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "When the key was actually expired"
                }
              }
            },
            "description": "List of expired keys with details"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          },
          "message": {
            "type": "string",
            "description": "Optional message when no pending keys exist"
          }
        },
        "description": "API key expiration result",
        "required": [
          "success",
          "workspace_id"
        ]
      },
      "TemplatePatchResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "updated_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Returned when updating properties"
          },
          "user": {
            "type": "object",
            "description": "Returned when updating/creating a user"
          }
        },
        "description": "Template partial update result",
        "required": [
          "message",
          "updated_fields"
        ]
      },
      "TemplateDuplicateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the newly created signing request"
          },
          "name": {
            "type": "string",
            "description": "Name of the new signing request"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Description of the new signing request"
          },
          "status": {
            "type": "string",
            "description": "Status of the new signing request",
            "example": "draft"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Workspace the signing request belongs to"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "seal_participants": {
            "type": "array",
            "description": "Seal participants of the new signing request, persisted entries (the shape of the create operations, except that `order` can be null) with `dropped: false`, then dropped entries. Not answered during normal operation for any company. While multi-document editing is suspended, duplication of a template on the multi-document read-only path answers 409 `MULTI_DOCUMENT_READ_ONLY`; on the single-document path, this key is always present, an empty array when the template has no seal participants.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/TemplateDuplicateSealParticipant"
                },
                {
                  "$ref": "#/components/schemas/SealParticipantDropped"
                }
              ]
            }
          }
        },
        "description": "Duplicated template details",
        "required": [
          "id",
          "name",
          "status",
          "workspace_id"
        ]
      },
      "CreateAndSendResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Signing request ID"
          },
          "name": {
            "type": "string",
            "description": "Signing request name"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Signing request description"
          },
          "status": {
            "type": "string",
            "enum": [
              "sent"
            ],
            "description": "Always 'sent' for this endpoint"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "Signed URL to access document"
          },
          "page_count": {
            "type": "integer",
            "description": "Number of pages in document"
          },
          "expiration_hours": {
            "type": "integer",
            "description": "Hours until expiration"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "description": "When request was sent"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "first_signer": {
            "type": "object",
            "description": "Details of the first signer who received the email",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "signing_link": {
                "type": "string",
                "format": "uri",
                "description": "Direct link for signer to access signing view"
              }
            }
          },
          "recipients": {
            "type": "array",
            "description": "All recipients with real UUIDs",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "first_name": {
                  "type": "string"
                },
                "last_name": {
                  "type": "string",
                  "nullable": true
                },
                "name": {
                  "type": "string"
                },
                "email": {
                  "type": "string",
                  "format": "email"
                },
                "designation": {
                  "type": "string"
                },
                "order": {
                  "type": "integer"
                }
              }
            }
          },
          "fields": {
            "type": "array",
            "description": "All active fields of the new signing request, including the fields owned by seal participants. Each item is the stored field record, not the `Field` shape used in requests: for example the field type is in `field_type`, and a seal-owned field has no recipient and names its seal participant in `seal_participant_id`.",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "seal_participants": {
            "type": "array",
            "description": "Organization seal participants in the signing order. Empty when the request has no seals. Each item is either a persisted seal participant (`dropped: false`) or, on a template-based request, an entry for a template seal that was not copied because the API key's company cannot see the seal or because the seal is limited to another workspace (`dropped: true`, `id` and `order` null, `seal_out_of_scope: true`). Dropped entries come after the persisted ones, in template order. Template seals that an explicit `seal_participants` array replaced are not listed.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/SealParticipantCreated"
                },
                {
                  "$ref": "#/components/schemas/SealParticipantDropped"
                }
              ]
            }
          },
          "credits_remaining": {
            "type": "integer",
            "description": "Company credits remaining after deduction"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional non-blocking warnings, including unknown anchor-tag properties during the compatibility window and anchor-processing warnings."
          }
        },
        "description": "Signing request created and sent",
        "required": [
          "id",
          "name",
          "status"
        ]
      },
      "CreateAndSendValidationError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code",
            "example": "VALIDATION_ERROR"
          },
          "phase": {
            "type": "string",
            "enum": [
              "create_validation",
              "send_validation"
            ],
            "description": "Which validation phase failed"
          },
          "validation_errors": {
            "type": "array",
            "description": "Detailed validation errors for send phase",
            "items": {
              "type": "object",
              "properties": {
                "recipient_index": {
                  "type": "integer",
                  "description": "1-based index of recipient"
                },
                "recipient_email": {
                  "type": "string"
                },
                "missing_fields": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "List of missing required fields"
                }
              }
            }
          },
          "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"
                }
              }
            }
          }
        },
        "description": "Validation error during create-and-send",
        "required": [
          "error",
          "code"
        ]
      },
      "InsufficientCreditsError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "Insufficient credits. Please purchase more credits to send signing requests."
          },
          "code": {
            "type": "string",
            "example": "INSUFFICIENT_CREDITS"
          },
          "current_credits": {
            "type": "integer",
            "example": 0
          }
        },
        "description": "Insufficient credits error",
        "required": [
          "error",
          "code",
          "current_credits"
        ]
      },
      "UnprocessableEntityError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "A recipient's email address cannot receive messages."
          },
          "code": {
            "type": "string",
            "example": "RECIPIENT_EMAIL_SUPPRESSED"
          }
        },
        "description": "Unprocessable entity error",
        "required": [
          "error",
          "code"
        ]
      },
      "SigningRequestUpdateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Signing request ID (for backward compatibility)"
          },
          "name": {
            "type": "string",
            "description": "Signing request name (for backward compatibility)"
          },
          "signing_request": {
            "type": "object",
            "description": "Summary of the updated signing request (subset of full SigningRequest schema)",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "description": "Signing request ID"
              },
              "name": {
                "type": "string",
                "description": "Signing request name"
              },
              "description": {
                "type": "string",
                "nullable": true,
                "description": "Signing request description (mapped from template_description)"
              },
              "document_url": {
                "type": "string",
                "format": "uri",
                "description": "Pre-signed URL to the PDF document"
              },
              "document_url_expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When the document URL expires"
              },
              "document_page_count": {
                "type": "integer",
                "description": "Number of pages in the document"
              },
              "status": {
                "type": "string",
                "description": "Current status of the signing request"
              },
              "expiration_hours": {
                "type": "integer",
                "description": "Hours until signing request expires"
              },
              "settings": {
                "type": "object",
                "description": "Subset of signing request settings returned in PUT response",
                "properties": {
                  "allow_download": {
                    "type": "boolean",
                    "description": "Whether recipients can download the document"
                  },
                  "attach_pdf_on_finish": {
                    "type": "boolean",
                    "description": "Whether to attach PDF on completion"
                  },
                  "hand_drawn_only": {
                    "type": "boolean",
                    "description": "Whether only hand-drawn signatures are allowed"
                  }
                }
              },
              "template_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true,
                "description": "Template ID if created from a template"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "ISO 8601 timestamp when the signing request expires"
              },
              "created_date": {
                "type": "string",
                "format": "date-time",
                "description": "Creation timestamp"
              },
              "sent_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When the signing request was sent"
              },
              "finished_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When all signatures were completed"
              },
              "cancelled_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When the signing request was cancelled"
              }
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Recipient"
            },
            "description": "Updated recipients list"
          },
          "reminders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Reminder"
            },
            "description": "Updated reminders list"
          },
          "summary": {
            "type": "object",
            "description": "Summary of all changes made in this update",
            "properties": {
              "properties_updated": {
                "type": "boolean",
                "description": "Whether any properties were updated"
              },
              "recipients_created": {
                "type": "integer",
                "description": "Number of new recipients created"
              },
              "recipients_updated": {
                "type": "integer",
                "description": "Number of existing recipients updated"
              },
              "recipients_deleted": {
                "type": "integer",
                "description": "Number of recipients soft-deleted"
              },
              "fields_created": {
                "type": "integer",
                "description": "Number of new fields created"
              },
              "fields_updated": {
                "type": "integer",
                "description": "Number of existing fields updated"
              },
              "fields_reassigned": {
                "type": "integer",
                "description": "Number of fields reassigned to another recipient"
              },
              "fields_deleted": {
                "type": "integer",
                "description": "Number of fields soft-deleted"
              },
              "reminders_created": {
                "type": "integer",
                "description": "Number of new reminders created"
              },
              "reminders_updated": {
                "type": "integer",
                "description": "Number of existing reminders updated"
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Email format warnings for recipients (non-blocking)"
              }
            }
          }
        },
        "description": "Signing request update result",
        "required": [
          "id",
          "name"
        ]
      },
      "SigningRequestUpdateError": {
        "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"
                }
              }
            }
          }
        },
        "description": "Signing request update validation error",
        "required": [
          "error"
        ]
      },
      "SigningRequestDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "deleted_on": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Signing request deletion confirmation",
        "required": [
          "message",
          "signing_request_id"
        ]
      },
      "CancelSigningRequestResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "cancelled_on": {
            "type": "string",
            "format": "date-time"
          },
          "notify_signers": {
            "type": "boolean"
          },
          "emails_sent": {
            "type": "integer",
            "description": "Number of cancellation notification emails sent to signers"
          }
        },
        "description": "Signing request cancellation result",
        "required": [
          "message",
          "signing_request_id",
          "cancelled_on"
        ]
      },
      "ResendSigningRequestResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "recipients_notified": {
            "type": "integer"
          },
          "recipients_failed": {
            "type": "integer",
            "description": "Number of recipients whose resend notification failed to send"
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "email": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "recipients_suppressed": {
            "type": "integer",
            "description": "Number of recipients not reminded because their address is suppressed (bounced)"
          }
        },
        "description": "Signing request resend result",
        "required": [
          "message",
          "signing_request_id"
        ]
      },
      "ResendConflictError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "properties": {
              "current_order": {
                "type": "integer"
              },
              "invalid_recipients": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "email": {
                      "type": "string"
                    },
                    "order": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Resend conflict error",
        "required": [
          "error",
          "code"
        ]
      },
      "TestWebhookResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the test webhook was delivered successfully"
          },
          "status_code": {
            "type": "integer",
            "description": "HTTP status code returned by the webhook endpoint"
          },
          "webhook_event_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the webhook event record"
          },
          "message": {
            "type": "string"
          },
          "headers_sent": {
            "type": "object",
            "description": "Headers sent with the test webhook request",
            "properties": {
              "X-Firma-Event": {
                "type": "string"
              },
              "X-Firma-Signature": {
                "type": "string"
              },
              "X-Firma-Delivery": {
                "type": "string"
              },
              "X-Firma-Signature-Old": {
                "type": "string",
                "description": "Only present during grace period after secret rotation"
              }
            }
          }
        },
        "description": "Webhook test execution result",
        "required": [
          "success",
          "status_code"
        ]
      },
      "GenerateTemplateTokenResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "The JWT token"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Token expiration timestamp"
          },
          "jwt_record_id": {
            "type": "string",
            "format": "uuid",
            "description": "Database record ID for the JWT"
          }
        },
        "description": "Generated JWT token for template",
        "required": [
          "token",
          "expires_at"
        ]
      },
      "EmailTemplateDefaultsResponse": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string"
          },
          "templates": {
            "type": "object",
            "description": "Map of email_type to default template {subject, body}",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "subject": {
                  "type": "string"
                },
                "body": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Default email templates for a language",
        "required": [
          "language",
          "templates"
        ]
      },
      "EmailTemplatePlaceholdersResponse": {
        "type": "object",
        "properties": {
          "placeholders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "description": "Placeholder key (e.g., 'signing_link')"
                },
                "description": {
                  "type": "string",
                  "description": "What this placeholder resolves to"
                }
              }
            }
          }
        },
        "description": "Available email template placeholders",
        "required": [
          "placeholders"
        ]
      },
      "WorkspaceEmailTemplateListResponse": {
        "type": "object",
        "description": "List of workspace email templates",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailTemplate"
            }
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Workspace ID"
          }
        },
        "required": [
          "results",
          "workspace_id"
        ]
      },
      "TemplateCopyResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the newly created template copy"
          },
          "name": {
            "type": "string",
            "description": "Name of the copied template"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Target workspace the template was copied to"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "seal_participants": {
            "type": "array",
            "description": "One entry per active seal participant of the source template, in source order. A seal that is not available in the target workspace is not copied, nor are the fields assigned to it; its entry is `{ id: null, order: null, seal: <summary or null>, seal_out_of_scope: true, dropped: true }`.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/TemplateCopySealParticipant"
                },
                {
                  "$ref": "#/components/schemas/SealParticipantDropped"
                }
              ]
            }
          }
        },
        "description": "Template copy response",
        "required": [
          "id",
          "name",
          "workspace_id",
          "created_date",
          "seal_participants"
        ]
      },
      "OrganizationSeal": {
        "type": "object",
        "description": "Organization seal metadata (image and statement internals are stripped from list/get responses).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "lineage_id": {
            "type": "string",
            "format": "uuid",
            "description": "Shared across versions of the same seal"
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "companies_id": {
            "type": "string",
            "format": "uuid"
          },
          "companies_workspaces_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Null for company-scope seals"
          },
          "authority_name": {
            "type": "string",
            "nullable": true,
            "description": "The name the seal was attested for: the company for company scope or the protected workspace, otherwise the workspace. Null for seals whose lineage was created before pinning; they certify in the company's current name."
          },
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "display_name": {
            "type": "string",
            "maxLength": 200
          },
          "signatory_title": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "kind": {
            "type": "string",
            "enum": [
              "uploaded",
              "typed",
              "drawn"
            ]
          },
          "is_default": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "1 if this is the default seal for its scope"
          },
          "statement_language": {
            "type": "string"
          },
          "statement_version": {
            "type": "integer",
            "minimum": 1
          },
          "statement_text": {
            "type": "string",
            "description": "The authority statement the seal was attested under, stored verbatim. Write-once: it never changes across versions of a lineage."
          },
          "statement_hash": {
            "type": "string",
            "description": "SHA-256 of statement_text (UTF-8), lowercase hex."
          },
          "signatory_name": {
            "type": "string",
            "maxLength": 200
          },
          "signatory_title_attested": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "attested_at": {
            "type": "string",
            "format": "date-time"
          },
          "revoked_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "deleted": {
            "type": "integer",
            "enum": [
              0,
              1
            ]
          }
        }
      },
      "OrganizationSealCreate": {
        "type": "object",
        "required": [
          "name",
          "display_name",
          "kind",
          "scope",
          "statement"
        ],
        "description": "Request body to create an organization seal.",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "description": "Internal name for the seal"
          },
          "display_name": {
            "type": "string",
            "maxLength": 200,
            "description": "Display name rendered on the seal image"
          },
          "signatory_title": {
            "type": "string",
            "maxLength": 200,
            "nullable": true,
            "description": "Signatory title rendered on the seal image"
          },
          "kind": {
            "type": "string",
            "enum": [
              "uploaded",
              "typed",
              "drawn"
            ],
            "description": "How the seal image was created"
          },
          "scope": {
            "type": "string",
            "enum": [
              "company",
              "workspace"
            ],
            "description": "Scope of the seal. Company-scope requires a protected API key."
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Required when scope is 'workspace'"
          },
          "image": {
            "type": "string",
            "description": "Base64-encoded PNG data URI (data:image/png;base64,...). Required for 'uploaded' and 'drawn' kinds."
          },
          "typed": {
            "type": "object",
            "description": "Typed seal parameters. Required for 'typed' kind.",
            "properties": {
              "text": {
                "type": "string",
                "description": "Text to render on the seal"
              },
              "style": {
                "type": "string",
                "description": "Style variant for the typed seal"
              }
            }
          },
          "statement": {
            "$ref": "#/components/schemas/SealStatement"
          },
          "is_default": {
            "type": "boolean",
            "default": false,
            "description": "Set as default seal for this scope"
          }
        }
      },
      "SealStatement": {
        "type": "object",
        "required": [
          "language",
          "version",
          "signatory_name",
          "text",
          "accepted"
        ],
        "description": "Attestation statement affirming authority to apply the seal.",
        "properties": {
          "language": {
            "type": "string",
            "description": "Language code of the statement"
          },
          "signatory_name": {
            "type": "string",
            "maxLength": 200,
            "description": "Name of the person attesting"
          },
          "signatory_title": {
            "type": "string",
            "maxLength": 200,
            "nullable": true,
            "description": "Title of the person attesting"
          },
          "text": {
            "type": "string",
            "description": "On create, the statement rendered with the authority name (the stored workspace or company name exactly as returned by the API, including HTML escaping). On replace, it must equal the seal's stored statement text."
          },
          "accepted": {
            "type": "boolean",
            "description": "Must be true to confirm acceptance"
          },
          "version": {
            "type": "integer",
            "minimum": 1,
            "description": "Statement version number"
          }
        }
      },
      "SealImage": {
        "type": "object",
        "description": "Seal image response.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "uploaded",
              "typed",
              "drawn"
            ]
          },
          "content_type": {
            "type": "string",
            "example": "image/png"
          },
          "data_url": {
            "type": "string",
            "description": "Base64-encoded PNG data URI"
          }
        }
      },
      "SealParticipantInput": {
        "type": "object",
        "required": [
          "temp_id",
          "order"
        ],
        "description": "One organization seal participant of a new signing request: an item of `seal_participants` on `POST /signing-requests` and `POST /signing-requests/create-and-send`.",
        "properties": {
          "seal_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the organization seal to apply; omit it to use the default seal of the workspace or, when the workspace has none, of the company. The call answers 400 `SEAL_UNAVAILABLE` when neither exists."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Position in the signing sequence"
          },
          "temp_id": {
            "type": "string",
            "description": "Temporary ID of this seal participant, required and unique within `seal_participants`; fields of the same request name it in `seal_participant_temp_id`."
          }
        }
      },
      "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."
          }
        }
      },
      "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."
          }
        }
      },
      "SealSummary": {
        "type": "object",
        "description": "Summary of an organization seal.",
        "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"
          }
        }
      },
      "SealParticipantDropped": {
        "type": "object",
        "description": "A template seal that was not copied to the new signing request or template because it is not available there: the key's company cannot see the seal, or the seal is limited to a workspace other than the target workspace. The fields that belong to the seal were not copied either. `seal` is the summary of the seal's current version, or null when the seal is not visible to the key's company.",
        "required": [
          "id",
          "order",
          "seal",
          "seal_out_of_scope",
          "dropped"
        ],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "enum": [
              null
            ],
            "description": "Always null: no participant was created."
          },
          "order": {
            "type": "integer",
            "nullable": true,
            "enum": [
              null
            ],
            "description": "Always null: no participant was created."
          },
          "seal": {
            "type": "object",
            "nullable": true,
            "description": "Summary of the seal's current version; null when the API key's company cannot see the seal.",
            "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"
              }
            }
          },
          "seal_out_of_scope": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "dropped": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        }
      },
      "SealParticipantCreated": {
        "description": "A persisted seal participant of the new document: every key of SealParticipantApi, plus `dropped: false`.",
        "allOf": [
          {
            "$ref": "#/components/schemas/SealParticipantApi"
          },
          {
            "type": "object",
            "required": [
              "dropped"
            ],
            "properties": {
              "dropped": {
                "type": "boolean",
                "enum": [
                  false
                ]
              }
            }
          }
        ]
      },
      "TemplateCopySealParticipant": {
        "type": "object",
        "description": "A seal participant of the copied template. `order` is its position in the copied template; `seal_out_of_scope` is true only when the seal has been revoked or deleted.",
        "required": [
          "id",
          "order",
          "seal",
          "seal_out_of_scope",
          "dropped"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Position in the copied template. Normally an integer. Null only if the position was not reported when the participant was saved; read the template to get it."
          },
          "seal": {
            "$ref": "#/components/schemas/SealSummary"
          },
          "seal_out_of_scope": {
            "type": "boolean"
          },
          "dropped": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        }
      },
      "SealApplication": {
        "type": "object",
        "description": "Record of a seal being applied to a signing request.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "signing_request_name": {
            "type": "string"
          },
          "seal_id": {
            "type": "string",
            "format": "uuid"
          },
          "seal_name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "applied",
              "paused",
              "pending"
            ],
            "description": "Application status"
          },
          "applied_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SealAccessLogEntry": {
        "type": "object",
        "description": "Access log entry for a seal lineage.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "organization_seals_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "lineage_id": {
            "type": "string",
            "format": "uuid"
          },
          "action": {
            "type": "string",
            "enum": [
              "created",
              "replaced",
              "revoked",
              "renamed",
              "default_changed",
              "erased",
              "image_read",
              "participant_swapped"
            ]
          },
          "actor_kind": {
            "type": "string",
            "enum": [
              "user",
              "api_key",
              "system"
            ]
          },
          "details": {
            "type": "object",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SealErrorCode": {
        "type": "string",
        "enum": [
          "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"
        ],
        "description": "Error codes specific to organization seal operations."
      },
      "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
        }
      },
      "DocumentSetMutationResponse": {
        "type": "object",
        "description": "Answer of every /documents mutation: the full document set after the change and its two versions.",
        "required": [
          "documents",
          "documents_version",
          "documents_layout_version"
        ],
        "properties": {
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentSummary"
            }
          },
          "documents_version": {
            "type": "integer"
          },
          "documents_layout_version": {
            "type": "integer"
          }
        }
      },
      "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."
      },
      "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"
              }
            }
          }
        ]
      },
      "CreateAndSendConflictError": {
        "description": "A 409 answered by POST /signing-requests/create-and-send: a MultiDocumentError that also names the signing request this call created when that request was kept (its rollback was refused with `SEND_EFFECTS_EXIST` or `ALREADY_SENT`).",
        "allOf": [
          {
            "$ref": "#/components/schemas/MultiDocumentError"
          },
          {
            "type": "object",
            "properties": {
              "signing_request_id": {
                "type": "string",
                "format": "uuid",
                "description": "Present only on SEND_EFFECTS_EXIST and ALREADY_SENT when the signing request this call created was kept (its rollback was refused): its id, so the caller can recover it instead of retrying (a retry creates a second request). Absent when the request was rolled back."
              }
            }
          }
        ]
      },
      "TemplateDuplicateSealParticipant": {
        "type": "object",
        "description": "A persisted seal participant of the duplicated signing request: every key of SealParticipantApi, plus `dropped: false`. `order` is normally an integer and is null only if the position was not reported when the participant was saved.",
        "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",
          "dropped"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Position in the signing order, shared with the recipients' order space. Normally an integer. Null only if the position was not reported when the participant was saved; read the signing request to get it."
          },
          "seal": {
            "$ref": "#/components/schemas/SealSummary"
          },
          "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."
          },
          "dropped": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        }
      },
      "RequestTooLargeError": {
        "description": "The API gateway rejected a request payload above the Lambda Function URL limit of 6,291,456 bytes (6 MiB).",
        "allOf": [
          {
            "$ref": "#/components/schemas/Error"
          },
          {
            "type": "object",
            "required": [
              "error",
              "code"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "REQUEST_TOO_LARGE"
                ]
              }
            }
          }
        ]
      }
    }
  },
  "paths": {
    "/company": {
      "get": {
        "summary": "Get company information",
        "description": "Retrieve information about the authenticated company",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Company information retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                },
                "example": {
                  "id": "123e4567-e89b-12d3-a456-426614174000",
                  "name": "Acme Corporation",
                  "language": "en",
                  "account_owner": "John Doe",
                  "account_owner_email": "john@acme.com",
                  "website": "https://acme.com",
                  "icon_url": "https://acme.com/logo.png",
                  "credits": 1000,
                  "created_date": "2024-01-15T10:30:00Z",
                  "updated_date": "2024-03-20T14:25:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getCompany",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.getCompany();\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Update company information",
        "description": "Update all company details. This is a full replacement operation requiring all fields except icon_url.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "account_owner",
                  "account_owner_email",
                  "website"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Company name"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb",
                      "ca"
                    ],
                    "description": "Default language for the company"
                  },
                  "account_owner": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Name of the account owner"
                  },
                  "account_owner_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Email address of the account owner"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri",
                    "description": "Company website URL"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "name": "Acme Corporation Ltd",
                "account_owner": "Jane Smith",
                "account_owner_email": "jane@acme.com",
                "website": "https://www.acme.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Company updated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Attempted to modify protected fields",
                    "value": {
                      "error": "The following fields cannot be modified: credits",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompany",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.updateCompany({\n    name: \"Acme Corporation Ltd\",\n    account_owner: \"Jane Smith\",\n    account_owner_email: \"jane@acme.com\",\n    website: \"https://www.acme.com\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Partially update company information",
        "description": "Update specific company fields. Only provided fields will be updated. At least one field must be provided.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Company name"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb",
                      "ca"
                    ],
                    "description": "Default language for the company"
                  },
                  "account_owner": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Name of the account owner"
                  },
                  "account_owner_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Email address of the account owner"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri",
                    "description": "Company website URL"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "name": "Acme Corporation Ltd",
                "website": "https://www.acme.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Company updated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Attempted to modify protected fields",
                    "value": {
                      "error": "The following fields cannot be modified: credits",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "noFields": {
                    "summary": "No fields provided",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "body"
                          ],
                          "message": "No fields provided to update"
                        }
                      ]
                    }
                  },
                  "invalidEmail": {
                    "summary": "Invalid email",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "account_owner_email"
                          ],
                          "message": "Invalid email address"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "patchCompany",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.patchCompany({\n    name: \"Acme Corporation Ltd\",\n    website: \"https://www.acme.com\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/settings": {
      "get": {
        "summary": "Get company settings",
        "description": "Retrieve settings for the authenticated company",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Company settings retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanySettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getCompanySettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.getCompanySettings();\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Update company settings",
        "description": "Update company settings. Only provided fields will be updated.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "default_expiration_hours": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Default signing request expiration in hours"
                  },
                  "require_terms_acceptance": {
                    "type": "boolean",
                    "description": "Whether signers must accept terms before signing"
                  },
                  "show_custom_branding_only": {
                    "type": "boolean"
                  },
                  "require_otp_verification": {
                    "type": "boolean"
                  },
                  "allow_presigning_download": {
                    "type": "boolean"
                  },
                  "disable_guided_navigation": {
                    "type": "boolean"
                  },
                  "show_signature_frame": {
                    "type": "boolean"
                  },
                  "show_partial_watermark": {
                    "type": "boolean"
                  },
                  "email_local_part": {
                    "type": "string"
                  },
                  "color_primary": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_primary_fg": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_background": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_foreground": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_card": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_border": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_accent": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_accent_fg": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_canvas": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_muted": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_muted_fg": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "show_qr_code": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Show a QR code on the signing page that lets signers continue on their phone. This is the company-level default; workspaces, templates, and signing requests can override it."
                  },
                  "allow_decline": {
                    "type": "boolean",
                    "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. This is the company-level default; workspaces, templates and signing requests can override it."
                  },
                  "show_save_for_later": {
                    "type": "boolean",
                    "description": "Show the Save & Finish Later button on the signing page. This is the company-level default; workspaces, templates and signing requests can override it."
                  },
                  "completion_title": {
                    "type": "string",
                    "nullable": true,
                    "description": "Company-level default heading for the completion page shown after signing. Null (or an empty string) clears the company default.",
                    "maxLength": 200
                  },
                  "completion_message": {
                    "type": "string",
                    "nullable": true,
                    "description": "Company-level default body text for the completion page shown after signing. Null (or an empty string) clears the company default.",
                    "maxLength": 1000
                  },
                  "completion_redirect_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Company-level default URL the signer is redirected to from the completion page. Must use https://. Null (or an empty string) clears the company default.",
                    "pattern": "^https://",
                    "maxLength": 2000
                  },
                  "completion_redirect_delay": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Company-level default number of seconds the completion page waits before redirecting (0 redirects immediately). Null clears the company default.",
                    "minimum": 0,
                    "maximum": 30
                  },
                  "default_timezone": {
                    "type": "string",
                    "description": "IANA timezone identifier (e.g. \"Europe/Paris\", \"America/New_York\"). Set to null to reset to UTC.",
                    "example": "Europe/Paris"
                  },
                  "language": {
                    "type": "string",
                    "description": "Default language for company emails and certificates.",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb",
                      "ca"
                    ],
                    "example": "en"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Company settings updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanySettings"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompanySettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.updateCompanySettings();\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains": {
      "get": {
        "summary": "List company domains",
        "description": "List all email domains configured for the company (domains on the protected/default workspace). These domains are used as the default sending domain for all workspaces.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Company domains retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "123e4567-e89b-12d3-a456-426614174000",
                      "domain": "acme.com",
                      "verification_status": 2,
                      "domain_status": 1,
                      "is_primary": true,
                      "date_created": "2024-01-15T10:30:00Z",
                      "date_changed": "2024-01-16T14:00:00Z"
                    }
                  ],
                  "workspace_id": "456e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listCompanyDomains",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.listCompanyDomains();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Add company domain",
        "description": "Add a new email domain for the company. This initiates the domain verification process. After creation, you must:\n1. Add a TXT record to your DNS with the verification token\n2. Call POST /company/domains/{id}/verify-ownership to verify domain ownership\n3. Call POST /company/domains/{id}/finalize to register with email provider\n4. Add the returned DNS records (SPF, DKIM, etc.)\n5. Call POST /company/domains/{id}/verify-dns to complete verification",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "Domain name to add (e.g., 'example.com'). Must be a valid domain format.",
                    "example": "acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domain created successfully. Add the verification TXT record to your DNS.",
            "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/DomainCreateResponse"
                },
                "example": {
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 0,
                    "domain_status": 0,
                    "is_primary": false,
                    "verification_token": "firma-verify=abc123xyz",
                    "date_created": "2024-01-15T10:30:00Z",
                    "date_changed": "2024-01-15T10:30:00Z"
                  },
                  "verification_instructions": {
                    "record_type": "TXT",
                    "record_name": "_firma-verification.acme.com",
                    "record_value": "firma-verify=abc123xyz",
                    "next_step": "Add this TXT record to your DNS, then call POST /company/domains/{id}/verify-ownership"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid domain format or domain already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidDomain": {
                    "value": {
                      "error": "Invalid domain format",
                      "message": "Please provide a valid domain name (e.g., example.com)"
                    }
                  },
                  "domainExists": {
                    "value": {
                      "error": "Domain already exists",
                      "message": "This domain is already configured for your company"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.createCompanyDomain({\n    domain: \"acme.com\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}": {
      "get": {
        "summary": "Get company domain",
        "description": "Retrieve details of a specific company domain including verification status and DNS records",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.getCompanyDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete company domain",
        "description": "Remove a domain from the company. If the domain is the primary or only domain, sending reverts to the company or default sender.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainDeleteResponse"
                },
                "example": {
                  "message": "Domain deleted successfully",
                  "domain_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.deleteCompanyDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/verify-ownership": {
      "post": {
        "summary": "Verify domain ownership",
        "description": "Verify domain ownership by checking the TXT record. Call this after adding the verification TXT record to your DNS. DNS propagation may take up to 48 hours, but typically completes within minutes.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain ownership verified successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyOwnershipResponse"
                },
                "example": {
                  "message": "Domain ownership verified",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 1,
                    "domain_status": 0
                  },
                  "next_step": "Call POST /company/domains/{id}/finalize to complete domain setup and receive DNS records for email sending"
                }
              }
            }
          },
          "400": {
            "description": "Verification failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "recordNotFound": {
                    "value": {
                      "error": "Verification failed",
                      "message": "TXT record not found. Please ensure the record is added correctly and DNS has propagated.",
                      "details": {
                        "expected_record": "_firma-verification.acme.com",
                        "expected_value": "firma-verify=abc123xyz"
                      }
                    }
                  },
                  "alreadyVerified": {
                    "value": {
                      "error": "Already verified",
                      "message": "Domain ownership has already been verified"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyCompanyDomainOwnership",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyCompanyDomainOwnership({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/finalize": {
      "post": {
        "summary": "Finalize domain setup",
        "description": "Finalize domain setup by registering with the email provider. This returns the DNS records (SPF, DKIM, DMARC) that must be added to enable email sending. Can only be called after domain ownership is verified.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain finalized successfully. Add the returned DNS records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainFinalizeResponse"
                },
                "example": {
                  "message": "Domain finalized. Add the following DNS records to enable email sending.",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 2,
                    "domain_status": 0
                  },
                  "dns_records": [
                    {
                      "type": "TXT",
                      "name": "@",
                      "value": "v=spf1 include:amazonses.com ~all",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "CNAME",
                      "name": "resend._domainkey",
                      "value": "resend._domainkey.amazonses.com",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "TXT",
                      "name": "_dmarc",
                      "value": "v=DMARC1; p=none;",
                      "ttl": "Auto",
                      "status": "pending"
                    }
                  ],
                  "next_step": "Add these DNS records, then call POST /company/domains/{id}/verify-dns to complete verification"
                }
              }
            }
          },
          "400": {
            "description": "Cannot finalize",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "notVerified": {
                    "value": {
                      "error": "Ownership not verified",
                      "message": "Please verify domain ownership first by calling POST /company/domains/{id}/verify-ownership"
                    }
                  },
                  "alreadyFinalized": {
                    "value": {
                      "error": "Already finalized",
                      "message": "Domain has already been finalized"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "finalizeCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.finalizeCompanyDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/verify-dns": {
      "post": {
        "summary": "Verify DNS records",
        "description": "Verify that all required DNS records (SPF, DKIM, DMARC) are properly configured. Call this after adding all DNS records from the finalize step. Once verified, the domain is ready for sending emails.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "DNS verification result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyDnsResponse"
                },
                "examples": {
                  "verified": {
                    "summary": "All records verified",
                    "value": {
                      "verified": true,
                      "message": "Domain is fully verified and ready to send emails",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "acme.com",
                        "verification_status": 2,
                        "domain_status": 1,
                        "is_primary": true
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "verified"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "verified"
                        }
                      ]
                    }
                  },
                  "pending": {
                    "summary": "Some records pending",
                    "value": {
                      "verified": false,
                      "message": "Some DNS records are not yet verified. Please check your DNS configuration.",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "acme.com",
                        "verification_status": 2,
                        "domain_status": 0
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "pending"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "pending"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Domain not finalized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not finalized",
                  "message": "Please finalize domain setup first by calling POST /company/domains/{id}/finalize"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyCompanyDomainDns",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyCompanyDomainDns({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/set-primary": {
      "post": {
        "summary": "Set primary domain",
        "description": "Set a domain as the primary sending domain for the company. Only fully verified domains (domain_status=1) can be set as primary.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Primary domain updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainSetPrimaryResponse"
                },
                "example": {
                  "message": "Primary domain updated",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 2,
                    "domain_status": 1,
                    "is_primary": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Domain not verified",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not verified",
                  "message": "Only fully verified domains can be set as primary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "setCompanyPrimaryDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.setCompanyPrimaryDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces": {
      "get": {
        "summary": "List workspaces",
        "description": "Retrieve a paginated list of workspaces for the authenticated company",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by workspace name (partial match, case-insensitive)"
          },
          {
            "name": "protected",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ]
            },
            "description": "Filter by protected status"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter workspaces created after this date (ISO 8601 format)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter workspaces created before this date (ISO 8601 format)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "protected",
                "created_on"
              ],
              "default": "created_on"
            },
            "description": "Field to sort by"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort order"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspaces retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "789e4567-e89b-12d3-a456-426614174000",
                      "name": "Sales Workspace",
                      "protected": false,
                      "api_key": "fk_a1b2c3d4e5f6g7h8i9j0",
                      "created_date": "2024-01-20T09:00:00Z",
                      "updated_date": "2024-01-20T09:00:00Z"
                    },
                    {
                      "id": "456e4567-e89b-12d3-a456-426614174000",
                      "name": "Default Workspace",
                      "protected": true,
                      "api_key": "fk_z9y8x7w6v5u4t3s2r1q0",
                      "created_date": "2024-01-15T10:30:00Z",
                      "updated_date": "2024-01-15T10:30:00Z"
                    }
                  ],
                  "pagination": {
                    "current_page": 1,
                    "page_size": 20,
                    "total_count": 2,
                    "total_pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid date format or sort parameters",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Invalid date format",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_after"
                          ],
                          "message": "created_after must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Invalid sort parameter",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "sort_order"
                          ],
                          "message": "sort_order must be either 'asc' or 'desc'"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaces",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.listWorkspaces();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Create a new workspace",
        "description": "Create a new workspace for the authenticated company. All workspaces are created as non-protected by default. The protected status can only be set during company account creation.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Workspace name"
                  }
                }
              },
              "example": {
                "name": "Marketing Workspace"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Workspace created successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                },
                "example": {
                  "id": "abc12345-e89b-12d3-a456-426614174000",
                  "name": "Marketing Workspace",
                  "protected": false,
                  "api_key": "fk_m1n2o3p4q5r6s7t8u9v0",
                  "created_date": "2024-01-25T14:00:00Z",
                  "updated_date": "2024-01-25T14:00:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.createWorkspace({\n    name: \"Marketing Workspace\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}": {
      "get": {
        "summary": "Get a workspace",
        "description": "Retrieve a specific workspace by ID including its API key",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                },
                "example": {
                  "id": "789e4567-e89b-12d3-a456-426614174000",
                  "name": "Sales Workspace",
                  "protected": false,
                  "api_key": "fk_a1b2c3d4e5f6g7h8i9j0",
                  "created_date": "2024-01-20T09:00:00Z",
                  "updated_date": "2024-01-20T09:00:00Z",
                  "webhook_enabled": false,
                  "webhook_secret": null,
                  "webhook_secret_rotated_at": null,
                  "webhook_secret_created_at": null,
                  "ignore_company_webhooks": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.getWorkspace({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Update a workspace",
        "description": "Update an existing workspace's information. This is a full replacement operation requiring the name field.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Workspace name"
                  }
                }
              },
              "example": {
                "name": "Enterprise Sales Workspace"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Workspace updated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.updateWorkspace({\n    id: \"id\",\n    name: \"Enterprise Sales Workspace\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Partially update a workspace",
        "description": "Update specific workspace fields. Only the name can be updated via API. The protected field is read-only and can only be set during company account creation.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Workspace name"
                  }
                }
              },
              "example": {
                "name": "Updated Workspace Name"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Workspace updated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "examples": {
                  "protectedField": {
                    "summary": "Attempted to update protected field",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "protected"
                          ],
                          "message": "The 'protected' field cannot be updated via API"
                        }
                      ]
                    }
                  },
                  "noFields": {
                    "summary": "No fields provided",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "body"
                          ],
                          "message": "No fields provided to update"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "patchWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.patchWorkspace({\n    id: \"id\",\n    name: \"Updated Workspace Name\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/api-key/regenerate": {
      "post": {
        "summary": "Regenerate workspace API key",
        "description": "Regenerates the API key for a workspace. Sets 24-hour expiration on existing active keys and creates a new key. Cannot be used on protected workspaces. Rate limited to 1 request per minute.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "key_type": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "default": "live",
                    "description": "Which key type to regenerate ('live' or 'test'). Defaults to 'live'. Regenerating one type does not expire or affect the other."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key regenerated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 1 request per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyRegenerateResponse"
                },
                "example": {
                  "new_key": {
                    "api_key": "firma_live_abc123xyz...",
                    "created_at": "2024-12-17T10:30:00Z"
                  },
                  "key_type": "live",
                  "expiring_keys": [
                    {
                      "id": "old-key-uuid",
                      "api_key": "firma_old456...",
                      "expires_at": "2024-12-18T10:30:00Z"
                    }
                  ],
                  "workspace_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "description": "Cannot regenerate key for protected workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Cannot regenerate API key for protected workspace"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "regenerateWorkspaceApiKey",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.regenerateWorkspaceApiKey({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/api-key/expire": {
      "post": {
        "summary": "Expire pending API keys",
        "description": "Immediately expires all pending API keys (those with expires_at set) for a workspace. Useful after verifying that the new key works correctly. Cannot be used on protected workspaces. Rate limited to 1 request per minute.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "key_type": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "description": "Optionally restrict expiry to one key type ('live' or 'test'). If omitted, all pending keys are expired (current behavior)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pending keys expired successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 1 request per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyExpireResponse"
                },
                "example": {
                  "success": true,
                  "expired_keys": [
                    {
                      "id": "old-key-uuid",
                      "api_key": "firma_old456...",
                      "original_expires_at": "2024-12-18T10:30:00Z",
                      "expired_at": "2024-12-17T10:30:00Z"
                    }
                  ],
                  "workspace_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "description": "Cannot expire keys for protected workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Cannot expire API keys for protected workspace"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "expireWorkspaceApiKey",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.expireWorkspaceApiKey({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates": {
      "get": {
        "summary": "List Templates",
        "description": "Retrieve a paginated list of templates",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Page number"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Items per page"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by template name (partial match, case-insensitive)"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter templates created after this date (ISO 8601 format)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter templates created before this date (ISO 8601 format)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "created_on",
                "last_changed_on"
              ],
              "default": "created_on"
            },
            "description": "Field to sort by"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort order"
          }
        ],
        "responses": {
          "200": {
            "description": "Templates retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplates",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplates();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Create Template",
        "description": "Create a new template with a base64-encoded PDF document. The API automatically extracts the page count from the document.\n\n`seal_participants`, `recipients` and `fields` are not accepted keys on this operation: they are ignored and nothing is created from them. When the request body contains any of them (the key being present is enough, whatever its value, including `null` or `[]`), the 201 response carries `warnings`, one string per ignored key. Add participants and fields with `PATCH /templates/{id}` or `PUT /templates/{id}`.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Template name",
                    "example": "Employment Contract Template"
                  },
                  "description": {
                    "type": "string",
                    "description": "Template description",
                    "example": "Standard employment contract for new hires"
                  },
                  "document": {
                    "type": "string",
                    "format": "byte",
                    "description": "Base64-encoded PDF or DOCX document. DOCX files are automatically converted to PDF. The API will automatically extract the page count from the document. For documents larger than 5 MB, use POST /documents and pass the document_id instead. (mutually exclusive with document_id and document_ids)",
                    "example": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c..."
                  },
                  "expiration_hours": {
                    "type": "integer",
                    "description": "Hours until signing request expires",
                    "default": 168,
                    "example": 168
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "allow_editing_before_sending": {
                        "type": "boolean",
                        "default": false,
                        "description": "Allow editing fields before sending"
                      },
                      "attach_pdf_on_finish": {
                        "type": "boolean",
                        "default": true,
                        "description": "Attach completed PDF to completion email"
                      },
                      "allow_download": {
                        "type": "boolean",
                        "default": true,
                        "description": "Allow recipients to download the document"
                      },
                      "hand_drawn_only": {
                        "type": "boolean",
                        "default": false,
                        "description": "Require signers to hand-draw their signatures instead of using typed signatures"
                      },
                      "require_otp_verification": {
                        "type": "boolean",
                        "nullable": true,
                        "default": null,
                        "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,
                        "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."
                      },
                      "allow_decline": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. Inherits from the workspace or company setting when null."
                      },
                      "show_save_for_later": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Show the Save & Finish Later button on the signing page. Inherits from the workspace or company setting when null."
                      }
                    }
                  },
                  "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"
                  },
                  "document_ids": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Temporary upload ids from POST /documents, in document order, to create a multi-document template (available to every company). Exactly one of document, document_id or document_ids (`400 CONFLICTING_DOCUMENT_SOURCE`); a repeated id answers `400 DUPLICATE_DOCUMENT_ID`, more than 20 `400 MAX_DOCUMENTS_EXCEEDED`, an unknown or expired upload `400 DOCUMENT_UPLOAD_NOT_FOUND`, a set above 100 MB `413 DOCUMENT_SET_TOO_LARGE`. While multi-document editing is suspended, more than one entry in `document_ids` answers `409 MULTI_DOCUMENT_READ_ONLY`."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template created successfully",
            "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/TemplateCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Validation failed. Multi-document: `CONFLICTING_DOCUMENT_SOURCE`, `DUPLICATE_DOCUMENT_ID`, `MAX_DOCUMENTS_EXCEEDED`, `DOCUMENT_UPLOAD_NOT_FOUND`",
            "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"
          },
          "413": {
            "description": "DOCUMENT_SET_TOO_LARGE, or REQUEST_TOO_LARGE when the request payload exceeds 6,291,456 bytes. Upload large files with POST /documents, then pass document_id / document_ids instead of inline base64.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MultiDocumentError"
                    },
                    {
                      "$ref": "#/components/schemas/RequestTooLargeError"
                    }
                  ]
                },
                "example": {
                  "error": "Request exceeds the 6,291,456-byte payload limit. Upload large files with POST /documents and pass document_id / document_ids instead of inline base64.",
                  "code": "REQUEST_TOO_LARGE"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.createTemplate({\n    name: \"Employment Contract Template\",\n    document: \"JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c...\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}": {
      "get": {
        "summary": "Get Template",
        "description": "Retrieve a specific template by ID. The response includes `seal_participants`: 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.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.getTemplate({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Partially Update Template",
        "description": "Update template properties, a single user, OR a single field. Cannot mix multiple entity types in one request. Use PUT for comprehensive updates including users, fields, and reminders. A `seal_participant` that names a seal answers 404 `NOT_FOUND` when the seal does not exist or belongs to another company, and 400 `SEAL_UNAVAILABLE` when the seal is revoked, deleted or not the current version of its lineage. Adding a seal participant or changing its seal answers 503 `SEALS_DISABLED` when organization seals are not enabled. Adding a seal participant requires `order` (see the order contract).",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "description": "Update template properties",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Template name"
                      },
                      "description": {
                        "type": "string",
                        "description": "Template description"
                      },
                      "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,
                        "description": "Hours until expiration"
                      },
                      "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."
                          },
                          "allow_decline": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. Inherits from the workspace or company setting when null."
                          },
                          "show_save_for_later": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Show the Save & Finish Later button on the signing page. Inherits from the workspace or company setting when null."
                          }
                        }
                      }
                    }
                  },
                  {
                    "type": "object",
                    "description": "Update or create a single user",
                    "required": [
                      "user"
                    ],
                    "properties": {
                      "user": {
                        "type": "object",
                        "required": [
                          "first_name",
                          "email",
                          "designation",
                          "order"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Include to update existing user, omit to create new. An existing recipient cannot be changed between CC and Signer/Approver (400); delete it and create it again."
                          },
                          "first_name": {
                            "type": "string",
                            "maxLength": 255
                          },
                          "last_name": {
                            "type": "string",
                            "maxLength": 255,
                            "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"
                          }
                        }
                      }
                    }
                  },
                  {
                    "type": "object",
                    "description": "Update or create a single field",
                    "required": [
                      "field"
                    ],
                    "properties": {
                      "field": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Include to update existing field, omit to create new"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "text",
                              "signature",
                              "date",
                              "checkbox",
                              "initial",
                              "initials",
                              "dropdown",
                              "radio_buttons",
                              "textarea",
                              "text_area",
                              "url",
                              "file",
                              "stamp",
                              "approval_signature",
                              "approval_checkmark",
                              "approval_date"
                            ],
                            "description": "Field type. Accepts 'initial' or 'initials', 'textarea' or 'text_area'. Required for new fields. url fields are automatically read-only. file fields allow signers to upload attachments (images/PDF). stamp fields display a pre-configured image."
                          },
                          "x": {
                            "type": "number",
                            "description": "X position on document. Required for new fields."
                          },
                          "y": {
                            "type": "number",
                            "description": "Y position on document. Required for new fields."
                          },
                          "width": {
                            "type": "number",
                            "description": "Field width. Required for new fields."
                          },
                          "height": {
                            "type": "number",
                            "description": "Field height. Required for new fields."
                          },
                          "page": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Page number (1-indexed). Required for new fields."
                          },
                          "required": {
                            "type": "boolean",
                            "description": "Whether field is required"
                          },
                          "assigned_to_user_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "Template user ID to assign the field to; `null` removes the field's user and leaves the field unassigned."
                          },
                          "variable_name": {
                            "type": "string",
                            "description": "Variable name for prefilled data mapping"
                          },
                          "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."
                          },
                          "options": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Options for dropdown fields"
                          },
                          "format_rules": {
                            "type": "object",
                            "description": "Format rules (e.g., date format, urlDisplayText for url fields, acceptedFileTypes for file fields)"
                          },
                          "multi_group_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Group ID for radio button groups"
                          },
                          "default_to_signing_date": {
                            "type": "boolean",
                            "description": "For date fields, use signing date as default"
                          },
                          "read_only": {
                            "type": "boolean",
                            "description": "Whether field is read-only (automatically true for url fields)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Static value for read-only fields. For url fields, this is the URL to link to."
                          }
                        }
                      },
                      "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`."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "seal_participant"
                    ],
                    "description": "Add or update one seal participant of the template. Send only the `seal_participant` key.",
                    "properties": {
                      "seal_participant": {
                        "type": "object",
                        "description": "One of two uses, chosen by the keys sent; each answers `{ \"seal_participant\": ... }`. Add: send `seal_id` and `order` without `id`; answers 201. Update: send `id` with `order` to move the participant, with `seal_id` to change its seal, or with both; answers 200. A template seal participant cannot be swapped.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID of the seal participant to update. Omit it to add a seal participant."
                          },
                          "seal_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID of the organization seal. Required to add a seal participant; on an update it becomes the seal of the participant. The seal must belong to the company, be the current version of its lineage, and be neither revoked nor deleted."
                          },
                          "order": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Position in the template's order, shared with the users' order space. Required to add a seal participant; on an update it moves the participant."
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "examples": {
                "update-properties": {
                  "summary": "Update properties",
                  "value": {
                    "name": "Updated Template Name",
                    "expiration_hours": 72
                  }
                },
                "create-url-field": {
                  "summary": "Create URL field",
                  "value": {
                    "field": {
                      "type": "url",
                      "x": 100,
                      "y": 200,
                      "width": 150,
                      "height": 30,
                      "page": 1,
                      "read_only_value": "https://example.com/terms",
                      "format_rules": {
                        "urlDisplayText": "View Terms & Conditions"
                      }
                    }
                  }
                },
                "create-file-field": {
                  "summary": "Create file upload field",
                  "value": {
                    "field": {
                      "type": "file",
                      "x": 100,
                      "y": 300,
                      "width": 200,
                      "height": 40,
                      "page": 1,
                      "required": true,
                      "format_rules": {
                        "acceptedFileTypes": "image_and_pdf"
                      }
                    }
                  }
                },
                "update-field": {
                  "summary": "Update existing field",
                  "value": {
                    "field": {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "x": 120,
                      "y": 220
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template partially updated successfully. Updating a seal participant returns `{ \"seal_participant\": <SealParticipantApi> }`.",
            "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": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/TemplatePatchResponse"
                    },
                    {
                      "type": "object",
                      "description": "Response when updating a seal participant",
                      "required": [
                        "seal_participant"
                      ],
                      "properties": {
                        "seal_participant": {
                          "$ref": "#/components/schemas/SealParticipantApi"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "A field or a seal participant was created. The body is the created field object; for a seal participant it is `{ \"seal_participant\": <SealParticipantApi> }`. Updating a seal participant answers 200 with the same `{ \"seal_participant\": ... }` body.",
            "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": {
                  "anyOf": [
                    {
                      "type": "object",
                      "description": "The created field"
                    },
                    {
                      "type": "object",
                      "description": "The created seal participant",
                      "required": [
                        "seal_participant"
                      ],
                      "properties": {
                        "seal_participant": {
                          "$ref": "#/components/schemas/SealParticipantApi"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "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": {
            "description": "Template or seal participant not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": "Template not found",
                      "code": "NOT_FOUND"
                    }
                  },
                  "seal_not_found": {
                    "value": {
                      "error": "Seal not found",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "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"
          },
          "503": {
            "description": "Organization seals are not enabled and a seal participant is added or its seal is changed (`SEALS_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "patchTemplate",
        "x-participant-order-contract": {
          "membership": "Signer and Approver recipients plus organization seal participants share one contiguous 1-based order space. CC recipients use a separate sequence and never consume a participant position.",
          "patch": "On an unsent template, order must be in [1..n] for a move and [1..n+1] for a create. A move is shift-insert: every participant between the old and new positions is renumbered. A create with omitted order appends, except for a seal participant: its order is required, and an omitted order or an order of 0 answers 400 `VALIDATION_ERROR`. For any other participant an explicit order 0 is invalid.",
          "lockedStates": "An applied participant on an aborted-send request can narrow the reachable interval; this template operation has no sent state.",
          "create": "A template is created without participants: `POST /templates` ignores `recipients` and `seal_participants`, and participants are added with this operation.",
          "sideEffects": "Retrying a create after a later field write fails creates a second participant, matching the existing non-idempotent create contract. PARTICIPANTS_CHANGED is a concurrent-write signal: another write to the same participant set committed while this call was running. No route compares against a version you loaded; re-read and retry.",
          "errors": [
            "INVALID_SIGNING_ORDER",
            "PARTICIPANTS_CHANGED"
          ]
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.patchTemplate({\n    id: \"id\",\n    body: {\n        name: \"Updated Template Name\",\n        expiration_hours: 72\n    }\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "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.\n\n**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.\n\n**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`.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "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."
                          },
                          "allow_decline": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. Inherits from the workspace or company setting when null."
                          },
                          "show_save_for_later": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Show the Save & Finish Later button on the signing page. Inherits from the 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"
          }
        },
        "operationId": "updateTemplate",
        "x-participant-order-contract": {
          "membership": "Signer and Approver users plus organization seal participants share one contiguous 1-based order space. CC users use a separate sequence and never consume a participant position. users and deleted_users share this order space but are not applied atomically: each entry is saved on its own (see the operation description).",
          "patch": "On an unsent template, order must be in [1..n] for a move and [1..n+1] for a create. A move is shift-insert: every participant between the old and new positions is renumbered. A create with omitted order appends. Explicit order 0 is invalid.",
          "lockedStates": "An applied participant on an aborted-send request can narrow the reachable interval; this template operation has no sent state.",
          "create": "A template is created without participants: `POST /templates` ignores `recipients` and `seal_participants`, and participants are added with this operation.",
          "sideEffects": "Shift-insert changes every participant between the old and new positions. Retrying a create after a later field write fails creates a second participant, matching the existing non-idempotent create contract. PARTICIPANTS_CHANGED is a concurrent-write signal: another write to the same participant set committed while this call was running. No route compares against a version you loaded; re-read and retry.",
          "errors": [
            "INVALID_SIGNING_ORDER",
            "PARTICIPANTS_CHANGED"
          ]
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.updateTemplate({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete a template",
        "description": "Soft delete a template by ID. This marks the template as deleted but retains the data.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template deleted successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                },
                "example": {
                  "message": "Template deleted successfully"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.deleteTemplate({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/users": {
      "get": {
        "summary": "Get template users",
        "description": "Retrieve all recipients/users associated with a specific template",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template users retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateUserListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "abc12345-e89b-12d3-a456-426614174000",
                      "name": "John Doe",
                      "email": "john@example.com",
                      "first_name": "John",
                      "last_name": "Doe",
                      "designation": "Signer",
                      "order": 1,
                      "phone_number": null,
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": null,
                      "company": null,
                      "required_fields": [
                        "email",
                        "first_name"
                      ],
                      "missing_fields": [],
                      "required_read_only_fields": [],
                      "ready_to_send": true
                    },
                    {
                      "id": "def67890-e89b-12d3-a456-426614174000",
                      "name": null,
                      "email": null,
                      "first_name": null,
                      "last_name": null,
                      "designation": "Signer",
                      "order": 2,
                      "phone_number": null,
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": null,
                      "company": null,
                      "required_fields": [
                        "email",
                        "first_name",
                        "phone_number"
                      ],
                      "missing_fields": [
                        "email",
                        "first_name",
                        "phone_number"
                      ],
                      "required_read_only_fields": [
                        {
                          "variable_name": "contract_date",
                          "field_type": "date"
                        }
                      ],
                      "ready_to_send": false
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplateUsers",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplateUsers({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/fields": {
      "get": {
        "summary": "Get template fields",
        "description": "Retrieve all fields configured for a specific template",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template fields retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateFieldListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "type": "signature",
                      "required": true,
                      "recipient_id": "user123-uuid",
                      "variable_name": null,
                      "position": {
                        "x": 100,
                        "y": 200,
                        "width": 200,
                        "height": 50
                      },
                      "page_number": 1,
                      "dropdown_options": null,
                      "multi_group_id": null,
                      "date_signing_default": false,
                      "format_rules": null,
                      "validation_rules": null,
                      "read_only": false,
                      "read_only_value": null
                    },
                    {
                      "id": "field456-e89b-12d3-a456-426614174000",
                      "type": "date",
                      "required": true,
                      "recipient_id": "user123-uuid",
                      "variable_name": null,
                      "position": {
                        "x": 100,
                        "y": 250,
                        "width": 150,
                        "height": 30
                      },
                      "page_number": 1,
                      "dropdown_options": null,
                      "multi_group_id": null,
                      "date_signing_default": true,
                      "format_rules": {
                        "date_format": "MM/DD/YYYY"
                      },
                      "validation_rules": null,
                      "read_only": false,
                      "read_only_value": null
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplateFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplateFields({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/reminders": {
      "get": {
        "summary": "Get template reminders",
        "description": "Retrieve all reminders configured for a specific template",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template reminders retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Reminder"
                  }
                },
                "example": [
                  {
                    "id": "remind123-e89b-12d3-a456-426614174000",
                    "hours": 24,
                    "subject": "Reminder: Please sign the document",
                    "message": "This is a friendly reminder to complete your signature.",
                    "all_users": true,
                    "template_user_id": null,
                    "created_date": "2024-01-15T10:30:00Z",
                    "updated_date": "2024-01-15T10:30:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplateReminders",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplateReminders({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/replace-document": {
      "post": {
        "summary": "Replace template document",
        "description": "Replaces the PDF document of an existing template while preserving all field placements. The replacement document must have the same page count and matching page dimensions (within 1pt tolerance) as the original.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "description": "Base64-encoded PDF or DOCX 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"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document replaced successfully",
            "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/Template"
                }
              }
            }
          },
          "400": {
            "description": "Validation error (page count mismatch, dimension mismatch, invalid document). Multi-document: `PAGE_COUNT_MISMATCH`, `DIMENSION_MISMATCH` (document replacement)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "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`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "replaceTemplateDocument",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.replaceTemplateDocument({\n    id: \"id\",\n    document: \"document\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/duplicate": {
      "post": {
        "summary": "Duplicate template into signing request",
        "description": "Creates a new signing request by duplicating an existing template, including all fields, users, reminders, and settings.\n\n**Seals.** The new signing request carries the template's seal participants and the template fields that belong to them. This operation takes no `seal_participants` key. While multi-document editing is suspended, templates on the multi-document read-only path answer 409 `MULTI_DOCUMENT_READ_ONLY`. For templates on the single-document path during that suspension, a template seal follows the current version of its lineage: if that current version is revoked or deleted, or the lineage has no current version, the call answers 409 `SEAL_UNAVAILABLE` and creates nothing; a seal that the API key's company cannot see, or that is limited to a workspace other than the target workspace, is not copied and neither are its fields, and the 201 lists it in `seal_participants` as a dropped entry; if a seal would be kept while organization seals are not enabled, the call answers 503 `SEALS_DISABLED`; the 201 always carries `seal_participants` (an empty array when the template has no seal participants). For every company during normal operation, the copy attaches the template's stored seal version as it is, the 201 does not carry `seal_participants`, and a seal that was replaced, revoked or deleted since the template was saved fails when the request is sent.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID to duplicate"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Custom name for the new signing request (defaults to template name)"
                  }
                }
              },
              "example": {
                "name": "Q4 2025 Contract"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template duplicated successfully into a new signing request",
            "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/TemplateDuplicateResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "description": "Access to the source template or the target workspace was denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict: `SEAL_UNAVAILABLE`, `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_INCONSISTENT`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_DISPATCH_STALE`",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/MultiDocumentError"
                    },
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "required": [
                            "error",
                            "code"
                          ],
                          "properties": {
                            "code": {
                              "type": "string",
                              "enum": [
                                "SEAL_UNAVAILABLE"
                              ]
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "503": {
            "description": "Organization seals are not enabled and the template has a seal participant that would be kept (`SEALS_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "duplicateTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.duplicateTemplate({\n    id: \"id\",\n    name: \"Q4 2025 Contract\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests": {
      "get": {
        "summary": "List Signing Requests",
        "description": "Retrieve a paginated list of signing requests",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Page number"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Items per page"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by signing request name (partial match, case-insensitive)"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "not_sent",
                "in_progress",
                "finished",
                "cancelled",
                "declined",
                "deleted",
                "expired"
              ]
            },
            "description": "Filter by signing request status. Supports multiple comma-separated values.\n\n**Available statuses:**\n- `not_sent`: Request created but not yet sent to signers\n- `in_progress`: Sent to signers but not completed, cancelled, declined, or expired\n- `finished`: All signers have completed\n- `cancelled`: Request was cancelled by sender\n- `declined`: A signer declined to sign (request stopped)\n- `deleted`: Soft-deleted records (normally hidden)\n- `expired`: Sent but past expiration time (sent_on + expiration_hours < now)\n\n**Example:** `?status=in_progress,expired`\n\n**Note:** The `expired` status uses post-filtering which may have performance implications on large datasets."
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter signing requests created after this date (ISO 8601 format)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter signing requests created before this date (ISO 8601 format)"
          },
          {
            "name": "signer_email",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by signer email address (exact match)"
          },
          {
            "name": "signer_name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by signer name (partial match, case-insensitive)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "created_on",
                "expiration_hours",
                "sent_on",
                "finished_on"
              ],
              "default": "created_on"
            },
            "description": "Field to sort by"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort order"
          }
        ],
        "responses": {
          "200": {
            "description": "Signing requests retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequests",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequests();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Create Signing Request",
        "description": "Create a new signing request either from a PDF document (document-based) or from an existing template (template-based). For document-based creation, allow_editing_before_sending is automatically set to true. For template-based creation, properties are inherited from the template and can be overridden.\n\n**Temporary ID Pattern**: For document-based creation, you can reference recipients before they're created using temporary IDs (format: 'temp_X' where X is any identifier, e.g., 'temp_1', 'temp_alice'). Use these temporary IDs in recipient.id, field.recipient_id, and reminder.recipient_id. The API validates all references and automatically maps temporary IDs to real UUIDs after recipients are created. The response contains only real UUIDs.\n\n**Temporary ID Validation**: Temporary IDs must start with 'temp_', be unique across all recipients in the request, and all field/reminder references must point to recipients defined in the same request. Invalid format, duplicate IDs, or missing recipient references return a 400 error with detailed validation messages.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "document"
                    ],
                    "description": "Create signing request from a PDF document",
                    "properties": {
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "Base64-encoded PDF or DOCX document. DOCX files are automatically converted to PDF. Page count will be auto-extracted. For documents larger than 5 MB, use POST /documents and pass the document_id instead."
                      },
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Name for the signing request"
                      },
                      "description": {
                        "type": "string",
                        "description": "Description for the signing request"
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "default": 168,
                        "description": "Hours until the signing request expires (default: 168 = 7 days)"
                      },
                      "recipients": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/Recipient"
                        },
                        "description": "Recipients for the signing request. Use temporary IDs (e.g., 'temp_1') in the id field to reference recipients in fields/reminders."
                      },
                      "fields": {
                        "type": "array",
                        "items": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/Field"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "seal_attribute": {
                                  "type": "string",
                                  "enum": [
                                    "display_name",
                                    "signatory_title",
                                    null
                                  ],
                                  "nullable": true,
                                  "description": "Which text a seal-owned text field shows: the seal's display name (`display_name`) or the signatory title (`signatory_title`). It applies to a field that a seal participant owns (a field with `seal_participant_temp_id`, or a template field that belongs to a seal participant) and is ignored on any other field. It is stored on the field as `format_rules.sealAttribute`; on a template-based request it replaces the `sealAttribute` that the template field carries and leaves the rest of the template field's `format_rules` unchanged. Any other value answers 400 `VALIDATION_ERROR`; this check applies to every field in the body, whether or not a seal owns it."
                                }
                              }
                            }
                          ]
                        },
                        "description": "Fields to place on the document. Use recipient_id to assign fields to recipients."
                      },
                      "anchor_tags": {
                        "type": "array",
                        "maxItems": 100,
                        "items": {
                          "$ref": "#/components/schemas/AnchorTag"
                        },
                        "description": "Anchor tags for automatic field placement. Text markers in the PDF are located and converted to positioned fields. The anchor text is removed from the PDF after processing. Fields created from anchor tags are added alongside any manually specified fields. Only available for document-based creation (not template-based)."
                      },
                      "reminders": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/SigningRequestReminder"
                        },
                        "description": "Reminders to send to recipients"
                      },
                      "settings": {
                        "$ref": "#/components/schemas/SigningRequestSettings",
                        "description": "Signing request settings"
                      },
                      "language": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "en",
                          "es",
                          "it",
                          "pt",
                          "fr",
                          "de",
                          "el",
                          "ru",
                          "pl",
                          "cs",
                          "sv",
                          "nl",
                          "ro",
                          "nb",
                          "ca"
                        ],
                        "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
                      },
                      "completion_title": {
                        "type": "string",
                        "nullable": true,
                        "description": "Heading shown on the completion page after signing. Inherits from the workspace, then the company, when omitted or null.",
                        "maxLength": 200
                      },
                      "completion_message": {
                        "type": "string",
                        "nullable": true,
                        "description": "Body text shown on the completion page after signing. Inherits from the workspace, then the company, when omitted or null.",
                        "maxLength": 1000
                      },
                      "completion_redirect_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Inherits from the workspace, then the company, when omitted or null.",
                        "maxLength": 2000
                      },
                      "completion_redirect_delay": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Inherits from the workspace, then the company, when omitted or null.",
                        "minimum": 0,
                        "maximum": 30
                      },
                      "seal_participants": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/SealParticipantInput"
                        },
                        "description": "Organization seal participants to include in the signing sequence. `null` is treated like an absent key; any other value that is not an array answers 400 `VALIDATION_ERROR`. The seal `order` values and the recipients' `order` values must form one contiguous sequence starting at 1: a gap answers 400 `INVALID_SIGNING_ORDER`, two of them (recipients or seals) sharing an `order` answer 400 `SEAL_ORDER_COLLISION`, and every recipient needs an `order` when a seal is present. A non-empty array requires organization seals to be enabled; otherwise the call answers 503 `SEALS_DISABLED`.",
                        "nullable": true
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "template_id"
                    ],
                    "description": "Create signing request from a template. Supports partial updates for both recipients and fields.",
                    "properties": {
                      "template_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID of the template to create signing request from. The document, fields, and default recipients will be copied from the template.\n\n**Seals.** If the template has seal participants and `seal_participants` is absent or `null`, the request inherits them and the template fields that belong to them. An array, including `[]`, replaces them: the template's seal participants and their fields are not copied. Any other type answers 400 `VALIDATION_ERROR`. A kept seal and the recipients are renumbered together into one contiguous order sequence that keeps the template's relative order. When the template has no recipients of its own, its inherited seals keep their place first and the request's recipients follow them. A template seal follows the current version of its lineage: the request attaches the current version, not the version the template points at. If that current version is revoked or deleted, or the lineage has no current version, the call answers 409 `SEAL_UNAVAILABLE` and creates nothing. A template seal that the API key's company cannot see, or whose current version is limited to a workspace other than the API key's workspace, is not copied and neither are its fields; the request is still created and `seal_participants` lists the seal as a dropped entry (`dropped: true`). If a seal would be kept while organization seals are not enabled, the call answers 503 `SEALS_DISABLED`."
                      },
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Custom name for signing request (defaults to template name if not provided)"
                      },
                      "description": {
                        "type": "string",
                        "description": "Custom description (defaults to template description if not provided)"
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Override template expiration hours"
                      },
                      "recipients": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/Recipient"
                        },
                        "description": "Optional recipient overrides. Use template_user_id (preferred) or order (fallback) to match template users. Only user info (first_name, last_name, email, phone_number, address fields, title, company) can be updated - order and designation are always inherited from template. Recipients not provided will use template defaults. Recipients with designation CC are never matched to template users; they are added as CC recipients. The template's CC recipients are copied to the signing request, skipping any whose email (case-insensitive) is already on a CC recipient of the request."
                      },
                      "fields": {
                        "type": "array",
                        "items": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/Field"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "seal_attribute": {
                                  "type": "string",
                                  "enum": [
                                    "display_name",
                                    "signatory_title",
                                    null
                                  ],
                                  "nullable": true,
                                  "description": "Which text a seal-owned text field shows: the seal's display name (`display_name`) or the signatory title (`signatory_title`). It applies to a field that a seal participant owns (a field with `seal_participant_temp_id`, or a template field that belongs to a seal participant) and is ignored on any other field. It is stored on the field as `format_rules.sealAttribute`; on a template-based request it replaces the `sealAttribute` that the template field carries and leaves the rest of the template field's `format_rules` unchanged. Any other value answers 400 `VALIDATION_ERROR`; this check applies to every field in the body, whether or not a seal owns it."
                                }
                              }
                            }
                          ]
                        },
                        "description": "Optional field overrides for partial updates. Use template_field_id (preferred) or variable_name (fallback) to match template fields. Only provided properties override template defaults. Supported override properties: type, required, position, read_only, read_only_value, format_rules, validation_rules, dropdown_options, date_default, date_signing_default, multi_group_id. Fields not matched are ignored. If fields array is omitted, all template fields are used as-is."
                      },
                      "settings": {
                        "$ref": "#/components/schemas/SigningRequestSettings",
                        "description": "Override template settings"
                      },
                      "language": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "en",
                          "es",
                          "it",
                          "pt",
                          "fr",
                          "de",
                          "el",
                          "ru",
                          "pl",
                          "cs",
                          "sv",
                          "nl",
                          "ro",
                          "nb",
                          "ca"
                        ],
                        "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
                      },
                      "completion_title": {
                        "type": "string",
                        "nullable": true,
                        "description": "Heading shown on the completion page after signing. Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                        "maxLength": 200
                      },
                      "completion_message": {
                        "type": "string",
                        "nullable": true,
                        "description": "Body text shown on the completion page after signing. Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                        "maxLength": 1000
                      },
                      "completion_redirect_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                        "maxLength": 2000
                      },
                      "completion_redirect_delay": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Falls back to the template value, then the workspace and company defaults, when omitted or null.",
                        "minimum": 0,
                        "maximum": 30
                      },
                      "seal_participants": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/SealParticipantInput"
                        },
                        "description": "Organization seal participants for the new signing request: with `template_id`, omit the key or send `null` to inherit the template's seals, send `[]` for no seals, or send an array to replace them. A replaced template seal and its fields are not copied. Any other type answers 400 `VALIDATION_ERROR`. On a template-based request the seal orders and the recipients' orders are renumbered together into one contiguous sequence, whether the seals are inherited or sent in the array. A non-empty array, or an inherited seal that would be kept, requires organization seals to be enabled; otherwise the call answers 503 `SEALS_DISABLED`.",
                        "nullable": true
                      }
                    },
                    "example": {
                      "template_id": "21424147-11c0-43d5-ac5f-a1f7001b5607",
                      "name": "Contract for Client X",
                      "recipients": [
                        {
                          "template_user_id": "template-user-uuid-1",
                          "first_name": "Toni",
                          "last_name": "Campins",
                          "email": "acampins@cocodin.com"
                        }
                      ],
                      "fields": [
                        {
                          "template_field_id": "field-uuid-1",
                          "read_only": true,
                          "read_only_value": "Contract #12345"
                        },
                        {
                          "variable_name": "company_name",
                          "read_only_value": "Acme Corporation"
                        }
                      ]
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "document_ids"
                    ],
                    "description": "Create signing request from several uploaded documents (multi-document, available to every company)",
                    "properties": {
                      "document_ids": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 20,
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "description": "Temporary upload ids from POST /documents, in document order, to create a multi-document signing request (available to every company). Exactly one of document, document_id or document_ids or template_id (`400 CONFLICTING_DOCUMENT_SOURCE`); a repeated id answers `400 DUPLICATE_DOCUMENT_ID`, more than 20 `400 MAX_DOCUMENTS_EXCEEDED`, an unknown or expired upload `400 DOCUMENT_UPLOAD_NOT_FOUND`, a set above 100 MB `413 DOCUMENT_SET_TOO_LARGE`; more than one id while multi-document editing is suspended answers `409 MULTI_DOCUMENT_READ_ONLY`."
                      },
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Name for the signing request"
                      },
                      "description": {
                        "type": "string",
                        "description": "Description for the signing request"
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "default": 168,
                        "description": "Hours until the signing request expires (default: 168 = 7 days)"
                      },
                      "recipients": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/Recipient"
                        },
                        "description": "Recipients for the signing request. Use temporary IDs (e.g., 'temp_1') in the id field to reference recipients in fields/reminders."
                      },
                      "fields": {
                        "type": "array",
                        "items": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/Field"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "seal_attribute": {
                                  "type": "string",
                                  "enum": [
                                    "display_name",
                                    "signatory_title",
                                    null
                                  ],
                                  "nullable": true,
                                  "description": "Which text a seal-owned text field shows: the seal's display name (`display_name`) or the signatory title (`signatory_title`). It applies to a field that a seal participant owns (a field with `seal_participant_temp_id`, or a template field that belongs to a seal participant) and is ignored on any other field. It is stored on the field as `format_rules.sealAttribute`; on a template-based request it replaces the `sealAttribute` that the template field carries and leaves the rest of the template field's `format_rules` unchanged. Any other value answers 400 `VALIDATION_ERROR`; this check applies to every field in the body, whether or not a seal owns it."
                                }
                              }
                            }
                          ]
                        },
                        "description": "Fields to place on the document. Use recipient_id to assign fields to recipients."
                      },
                      "anchor_tags": {
                        "type": "array",
                        "maxItems": 100,
                        "items": {
                          "$ref": "#/components/schemas/AnchorTag"
                        },
                        "description": "Anchor tags for automatic field placement. Text markers in the PDF are located and converted to positioned fields. The anchor text is removed from the PDF after processing. Fields created from anchor tags are added alongside any manually specified fields. Only available for document-based creation (not template-based)."
                      },
                      "reminders": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/SigningRequestReminder"
                        },
                        "description": "Reminders to send to recipients"
                      },
                      "settings": {
                        "$ref": "#/components/schemas/SigningRequestSettings",
                        "description": "Signing request settings"
                      },
                      "language": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "en",
                          "es",
                          "it",
                          "pt",
                          "fr",
                          "de",
                          "el",
                          "ru",
                          "pl",
                          "cs",
                          "sv",
                          "nl",
                          "ro",
                          "nb",
                          "ca"
                        ],
                        "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
                      },
                      "completion_title": {
                        "type": "string",
                        "nullable": true,
                        "description": "Heading shown on the completion page after signing. Inherits from the workspace, then the company, when omitted or null.",
                        "maxLength": 200
                      },
                      "completion_message": {
                        "type": "string",
                        "nullable": true,
                        "description": "Body text shown on the completion page after signing. Inherits from the workspace, then the company, when omitted or null.",
                        "maxLength": 1000
                      },
                      "completion_redirect_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Inherits from the workspace, then the company, when omitted or null.",
                        "maxLength": 2000
                      },
                      "completion_redirect_delay": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Inherits from the workspace, then the company, when omitted or null.",
                        "minimum": 0,
                        "maximum": 30
                      },
                      "seal_participants": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/SealParticipantInput"
                        },
                        "description": "Organization seal participants to include in the signing sequence. `null` is treated like an absent key; any other value that is not an array answers 400 `VALIDATION_ERROR`. The seal `order` values and the recipients' `order` values must form one contiguous sequence starting at 1: a gap answers 400 `INVALID_SIGNING_ORDER`, two of them (recipients or seals) sharing an `order` answer 400 `SEAL_ORDER_COLLISION`, and every recipient needs an `order` when a seal is present. A non-empty array requires organization seals to be enabled; otherwise the call answers 503 `SEALS_DISABLED`.",
                        "nullable": true
                      }
                    }
                  }
                ],
                "properties": {
                  "seal_participants": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/SealParticipantInput"
                    },
                    "description": "Organization seal participants for the new signing request: with `template_id`, omit the key or send `null` to inherit the template's seals, send `[]` for no seals, or send an array to replace them. A replaced template seal and its fields are not copied. Any other type answers 400 `VALIDATION_ERROR`. On a template-based request the seal orders and the recipients' orders are renumbered together into one contiguous sequence, whether the seals are inherited or sent in the array. A non-empty array, or an inherited seal that would be kept, requires organization seals to be enabled; otherwise the call answers 503 `SEALS_DISABLED`.",
                    "nullable": true
                  },
                  "fields": {
                    "type": "array",
                    "items": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Field"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "seal_participant_temp_id": {
                              "type": "string",
                              "description": "Temporary ID of the seal participant this field is assigned to (matches temp_id in seal_participants array)"
                            },
                            "seal_attribute": {
                              "type": "string",
                              "enum": [
                                "display_name",
                                "signatory_title",
                                null
                              ],
                              "nullable": true,
                              "description": "Which text a seal-owned text field shows: the seal's display name (`display_name`) or the signatory title (`signatory_title`). It applies to a field that a seal participant owns (a field with `seal_participant_temp_id`, or a template field that belongs to a seal participant) and is ignored on any other field. It is stored on the field as `format_rules.sealAttribute`; on a template-based request it replaces the `sealAttribute` that the template field carries and leaves the rest of the template field's `format_rules` unchanged. Any other value answers 400 `VALIDATION_ERROR`; this check applies to every field in the body, whether or not a seal owns it."
                            }
                          }
                        }
                      ],
                      "properties": {
                        "seal_participant_temp_id": {
                          "type": "string",
                          "description": "Temporary ID of the seal participant this field is assigned to (matches temp_id in seal_participants array)"
                        },
                        "seal_attribute": {
                          "type": "string",
                          "enum": [
                            "display_name",
                            "signatory_title",
                            null
                          ],
                          "nullable": true,
                          "description": "Which text a seal-owned text field shows: the seal's display name (`display_name`) or the signatory title (`signatory_title`). It applies to a field that a seal participant owns (a field with `seal_participant_temp_id`, or a template field that belongs to a seal participant) and is ignored on any other field. It is stored on the field as `format_rules.sealAttribute`; on a template-based request it replaces the `sealAttribute` that the template field carries and leaves the rest of the template field's `format_rules` unchanged. Any other value answers 400 `VALIDATION_ERROR`; this check applies to every field in the body, whether or not a seal owns it."
                        }
                      }
                    },
                    "description": "Fields to place on the document"
                  }
                }
              },
              "examples": {
                "update-properties": {
                  "summary": "Update properties",
                  "value": {
                    "name": "Updated Contract Name",
                    "expiration_hours": 72
                  }
                },
                "update-recipient": {
                  "summary": "Update single recipient",
                  "value": {
                    "recipient": {
                      "id": "rec123-e89b-12d3-a456-426614174000",
                      "first_name": "John",
                      "last_name": "Smith",
                      "email": "john.smith@example.com",
                      "designation": "Signer",
                      "order": 1
                    }
                  }
                },
                "add-recipient": {
                  "summary": "Add new recipient",
                  "value": {
                    "recipient": {
                      "first_name": "Jane",
                      "last_name": "Doe",
                      "email": "jane@example.com",
                      "designation": "Signer",
                      "order": 2
                    }
                  }
                },
                "add-date-field": {
                  "summary": "Add date field with formatting",
                  "value": {
                    "field": {
                      "type": "date",
                      "position": {
                        "x": 70,
                        "y": 45,
                        "width": 15,
                        "height": 3
                      },
                      "page_number": 1,
                      "required": true,
                      "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                      "date_signing_default": true,
                      "format_rules": {
                        "dateFormat": "MMMM dd, yyyy"
                      }
                    }
                  }
                },
                "add-read-only-static-field": {
                  "summary": "Add read-only field with static value",
                  "description": "Creates a text field that displays a fixed value the signer cannot edit",
                  "value": {
                    "field": {
                      "type": "text",
                      "position": {
                        "x": 15,
                        "y": 20,
                        "width": 40,
                        "height": 3
                      },
                      "page_number": 1,
                      "required": false,
                      "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                      "read_only": true,
                      "read_only_value": "Contract #12345 - Acme Corporation"
                    }
                  }
                },
                "add-read-only-prefilled-field": {
                  "summary": "Add read-only field with recipient data",
                  "description": "Creates a text field that auto-populates with the recipient's email address (signer cannot edit)",
                  "value": {
                    "field": {
                      "type": "text",
                      "position": {
                        "x": 15,
                        "y": 30,
                        "width": 30,
                        "height": 3
                      },
                      "page_number": 1,
                      "required": false,
                      "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                      "read_only": true,
                      "prefilled_data": "email"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Signing request created successfully. The response may include non-blocking email or anchor-tag warnings.",
            "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/SigningRequestCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input - must provide either 'document' or 'template_id', not both. Document must be valid base64-encoded PDF under 6MB request payload (~4.5MB raw). Multi-document: `CONFLICTING_DOCUMENT_SOURCE`, `DUPLICATE_DOCUMENT_ID`, `MAX_DOCUMENTS_EXCEEDED`, `DOCUMENT_UPLOAD_NOT_FOUND`, `ANCHOR_DOCUMENT_REQUIRED`. Organization seals: `VALIDATION_ERROR` when `seal_participants` is neither an array nor `null`, when one of its entries has no `temp_id`, repeats a `temp_id` or has an `order` that is not a positive integer, or when the `seal_attribute` of a field is not `display_name`, `signatory_title` or `null`; `SEAL_UNAVAILABLE` when an entry omits `seal_id` and neither the workspace nor the company has an active default seal; on a document-based request with seal participants, `INVALID_SIGNING_ORDER` when a recipient has no `order` or the recipients and the seals do not form one sequence starting at 1, and `SEAL_ORDER_COLLISION` when two of them (recipients or seals) share an `order`.",
            "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"
          },
          "403": {
            "description": "The template is not in the API key's workspace (`INVALID_TEMPLATE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The template was not found; a template outside the API key's workspace can also answer 404 instead of 403. A seal named in `seal_participants` does not exist, belongs to another company or is limited to another workspace (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `SEAL_UNAVAILABLE` (a seal named in `seal_participants` is revoked or deleted, or is not the current version of its lineage; or the current version of an inherited template seal is revoked or deleted, or that seal has no current version), `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_INCONSISTENT`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_DISPATCH_STALE`",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/MultiDocumentError"
                    },
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "required": [
                            "error",
                            "code"
                          ],
                          "properties": {
                            "code": {
                              "type": "string",
                              "enum": [
                                "SEAL_UNAVAILABLE"
                              ]
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "413": {
            "description": "DOCUMENT_SET_TOO_LARGE, or REQUEST_TOO_LARGE when the request payload exceeds 6,291,456 bytes. Upload large files with POST /documents, then pass document_id / document_ids instead of inline base64.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MultiDocumentError"
                    },
                    {
                      "$ref": "#/components/schemas/RequestTooLargeError"
                    }
                  ]
                },
                "example": {
                  "error": "Request exceeds the 6,291,456-byte payload limit. Upload large files with POST /documents and pass document_id / document_ids instead of inline base64.",
                  "code": "REQUEST_TOO_LARGE"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "503": {
            "description": "Anchor-tag processing is disabled on the edge fallback (`ANCHOR_DISABLED_EDGE`): retry through the primary API route. Or organization seals are not enabled and either `seal_participants` is a non-empty array (answered before its entries are checked) or template inheritance keeps at least one seal (`SEALS_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "ANCHOR_DISABLED_EDGE",
                        "SEALS_DISABLED"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "createSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.createSigningRequest({\n    template_id: \"template_id\",\n    name: \"Updated Contract Name\",\n    expiration_hours: 72\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/create-and-send": {
      "post": {
        "summary": "Create and Send Signing Request (Atomic)",
        "description": "Create and immediately send a signing request in a single atomic operation. This endpoint combines the functionality of POST /signing-requests and POST /signing-requests/{id}/send.\n\n**Key Benefits:**\n- Single API call instead of two separate requests\n- Validates all send requirements BEFORE creating the signing request\n- Atomic credit deduction - only charges if everything succeeds\n- Returns status: 'sent' immediately with first signer details\n- More efficient (saves 1 API call + round-trip time)\n\n**Validation:**\n- All standard creation validations (document/template, recipients, fields)\n- Additional send validations:\n  - All signers must have first_name and valid email\n  - Required read-only fields must have final_value populated\n  - Prefilled data fields (variable_name) must have corresponding user data\n  - Company must have sufficient credits (≥1)\n\n**Atomicity:**\n- If any validation fails, nothing is created\n- Credit is only deducted after successful creation and before email send\n- If email send fails after creation, signing request remains in 'draft' status and credit is NOT deducted\n\n**Temporary ID Pattern:** For document-based creation, use temporary IDs (format: 'temp_X') to reference recipients before creation. The API validates all references and automatically maps temporary IDs to real UUIDs.\n\n**Rate Limit:** 120 requests/minute (same as write operations)",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Signing request name",
                    "example": "Employment Contract - John Doe"
                  },
                  "description": {
                    "type": "string",
                    "description": "Signing request description",
                    "example": "Full-time employment contract for Software Engineer position"
                  },
                  "document": {
                    "type": "string",
                    "format": "byte",
                    "description": "Base64-encoded PDF or DOCX document (mutually exclusive with template_id and document_id). DOCX files are automatically converted to PDF. For documents larger than 5 MB, use POST /documents and pass the document_id instead.",
                    "example": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c..."
                  },
                  "template_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Template ID to use (mutually exclusive with document and document_id).\n\n**Seals.** If the template has seal participants and `seal_participants` is absent or `null`, the request inherits them and the template fields that belong to them. An array, including `[]`, replaces them: the template's seal participants and their fields are not copied. Any other type answers 400 `VALIDATION_ERROR`. A kept seal and the recipients are renumbered together into one contiguous order sequence that keeps the template's relative order. When the template has no recipients of its own, its inherited seals keep their place first and the request's recipients follow them. A template seal follows the current version of its lineage: the request attaches the current version, not the version the template points at. If that current version is revoked or deleted, or the lineage has no current version, the call answers 409 `SEAL_UNAVAILABLE` and creates nothing. A template seal that the API key's company cannot see, or whose current version is limited to a workspace other than the API key's workspace, is not copied and neither are its fields; the request is still created and `seal_participants` lists the seal as a dropped entry (`dropped: true`). If a seal would be kept while organization seals are not enabled, the call answers 503 `SEALS_DISABLED`.",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  },
                  "expiration_hours": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 168,
                    "description": "Hours until signing request expires (default: 168 = 7 days)",
                    "example": 168
                  },
                  "recipients": {
                    "type": "array",
                    "description": "Array of recipients. At least one must be a Signer. For document-based: required. For template-based: optional (uses template recipients if omitted). Use template_user_id (preferred) or order (fallback) to match template users. Recipients with designation CC are never matched to template users; they are added as CC recipients. The template's CC recipients are copied to the signing request, skipping any whose email (case-insensitive) is already on a CC recipient of the request.",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/Recipient"
                    }
                  },
                  "fields": {
                    "type": "array",
                    "description": "Array of fields to be filled (document-based only)",
                    "items": {
                      "type": "object",
                      "required": [
                        "type",
                        "page",
                        "x",
                        "y"
                      ],
                      "properties": {
                        "recipient_id": {
                          "type": "string",
                          "description": "Temporary ID or UUID of recipient assigned to this field",
                          "example": "temp_signer_1"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "signature",
                            "initial",
                            "text",
                            "date",
                            "checkbox",
                            "dropdown",
                            "radio_buttons",
                            "text_area",
                            "url",
                            "file",
                            "stamp",
                            "approval_signature",
                            "approval_checkmark",
                            "approval_date"
                          ],
                          "description": "Field type. Accepts aliases: \"initials\" (normalized to \"initial\"), \"textarea\" (normalized to \"text_area\"), \"radio\" (normalized to \"radio_buttons\").",
                          "example": "signature"
                        },
                        "page": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "PDF page number (1-indexed)",
                          "example": 1
                        },
                        "x": {
                          "type": "number",
                          "description": "X coordinate on page",
                          "example": 100
                        },
                        "y": {
                          "type": "number",
                          "description": "Y coordinate on page",
                          "example": 200
                        },
                        "width": {
                          "type": "number",
                          "default": 200,
                          "example": 200
                        },
                        "height": {
                          "type": "number",
                          "default": 50,
                          "example": 50
                        },
                        "variable_name": {
                          "type": "string",
                          "description": "Variable name for prefilled data (e.g., 'phone_number', 'company'). If set, the corresponding recipient field must be populated.",
                          "enum": [
                            "first_name",
                            "last_name",
                            "full_name",
                            "email",
                            "phone_number",
                            "street_address",
                            "city",
                            "state_province",
                            "postal_code",
                            "country",
                            "title",
                            "company"
                          ],
                          "example": "phone_number"
                        },
                        "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": {
                          "type": "boolean",
                          "default": false,
                          "description": "Whether field is required"
                        },
                        "read_only": {
                          "type": "boolean",
                          "default": false,
                          "description": "Whether field is read-only (pre-filled)"
                        },
                        "final_value": {
                          "type": "string",
                          "description": "Pre-filled value for read-only fields (required if read_only=true and required=true)",
                          "example": "Software Engineer"
                        },
                        "background_color": {
                          "type": "string",
                          "nullable": true,
                          "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
                          "description": "Background color as hex (e.g., '#FFFDE7')",
                          "example": "#FFFDE7"
                        },
                        "dropdown_options": {
                          "description": "Options for dropdown fields. Required when type is \"dropdown\".",
                          "example": [
                            "Option A",
                            "Option B",
                            "Option C"
                          ],
                          "oneOf": [
                            {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            {
                              "type": "object"
                            }
                          ]
                        },
                        "seal_participant_temp_id": {
                          "type": "string",
                          "description": "Temporary ID of the seal participant this field is assigned to (matches temp_id in seal_participants array)"
                        },
                        "seal_attribute": {
                          "type": "string",
                          "enum": [
                            "display_name",
                            "signatory_title",
                            null
                          ],
                          "nullable": true,
                          "description": "Which text a seal-owned text field shows: the seal's display name (`display_name`) or the signatory title (`signatory_title`). It applies to a field that a seal participant owns (a field with `seal_participant_temp_id`, or a template field that belongs to a seal participant) and is ignored on any other field. It is stored on the field as `format_rules.sealAttribute`; on a template-based request it replaces the `sealAttribute` that the template field carries and leaves the rest of the template field's `format_rules` unchanged. Any other value answers 400 `VALIDATION_ERROR`; this check applies to every field in the body, whether or not a seal owns it."
                        }
                      }
                    }
                  },
                  "anchor_tags": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "$ref": "#/components/schemas/AnchorTag"
                    },
                    "description": "Anchor tags for automatic field placement. Text markers in the PDF are located and converted to positioned fields. The anchor text is removed from the PDF after processing. Fields created from anchor tags are added alongside any manually specified fields. Only available for document-based creation (not template-based)."
                  },
                  "reminders": {
                    "type": "array",
                    "description": "Array of reminder configurations",
                    "items": {
                      "type": "object",
                      "required": [
                        "hours_before_expiration"
                      ],
                      "properties": {
                        "hours_before_expiration": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Hours before expiration to send reminder",
                          "example": 24
                        }
                      }
                    }
                  },
                  "settings": {
                    "type": "object",
                    "description": "Signing request settings",
                    "properties": {
                      "use_signing_order": {
                        "type": "boolean",
                        "default": true,
                        "description": "Enforce signing order based on recipient.order. When false, all signers receive the document simultaneously."
                      },
                      "allow_download": {
                        "type": "boolean",
                        "default": true,
                        "description": "Allow recipients to download document"
                      },
                      "attach_pdf_on_finish": {
                        "type": "boolean",
                        "default": true,
                        "description": "Attach completed PDF to completion email"
                      },
                      "send_signing_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Send email notification to signers"
                      },
                      "send_finish_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Send email when all signatures complete"
                      },
                      "send_expiration_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Send email when request expires"
                      },
                      "send_cancellation_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Send email when request is cancelled"
                      },
                      "hand_drawn_only": {
                        "type": "boolean",
                        "default": false,
                        "description": "Require signers to hand-draw their signatures instead of using typed signatures"
                      },
                      "identity_editable_fields": {
                        "type": "array",
                        "nullable": true,
                        "items": {
                          "type": "string",
                          "enum": [
                            "name",
                            "company",
                            "title",
                            "phone",
                            "address"
                          ]
                        },
                        "description": "Identity fields signers can edit before signing; `null` disables the editing. When set, a confirmation dialog appears allowing signers to edit the specified fields.",
                        "example": [
                          "name",
                          "company"
                        ]
                      },
                      "notify_identity_change_webhook": {
                        "type": "boolean",
                        "default": false,
                        "description": "Send webhook event when a signer changes their identity"
                      },
                      "notify_identity_change_email": {
                        "type": "boolean",
                        "default": false,
                        "description": "Send email notification when a signer changes their identity"
                      },
                      "allow_decline": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. Inherits from the workspace or company setting when null."
                      },
                      "show_save_for_later": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Show the Save & Finish Later button on the signing page. Inherits from the workspace or company setting when null."
                      }
                    }
                  },
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID of a previously uploaded document (mutually exclusive with document and template_id). Obtain by calling POST /documents first.",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  },
                  "language": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb",
                      "ca"
                    ],
                    "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
                  },
                  "completion_title": {
                    "type": "string",
                    "nullable": true,
                    "description": "Heading shown on the completion page after signing. Falls back to the template value (when template_id is used), then the workspace and company defaults.",
                    "example": "Thank you for signing",
                    "maxLength": 200
                  },
                  "completion_message": {
                    "type": "string",
                    "nullable": true,
                    "description": "Body text shown on the completion page after signing. Falls back to the template value (when template_id is used), then the workspace and company defaults.",
                    "example": "Your signed copy is on its way to your inbox.",
                    "maxLength": 1000
                  },
                  "completion_redirect_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Falls back to the template value (when template_id is used), then the workspace and company defaults.",
                    "example": "https://example.com/thank-you",
                    "maxLength": 2000
                  },
                  "completion_redirect_delay": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Falls back to the template value (when template_id is used), then the workspace and company defaults.",
                    "example": 5,
                    "minimum": 0,
                    "maximum": 30
                  },
                  "seal_participants": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/SealParticipantInput"
                    },
                    "description": "Organization seal participants for the new signing request: with `template_id`, omit the key or send `null` to inherit the template's seals, send `[]` for no seals, or send an array to replace them. A replaced template seal and its fields are not copied. Any other type answers 400 `VALIDATION_ERROR`. On a template-based request the seal orders and the recipients' orders are renumbered together into one contiguous sequence, whether the seals are inherited or sent in the array. A non-empty array, or an inherited seal that would be kept, requires organization seals to be enabled; otherwise the call answers 503 `SEALS_DISABLED`.",
                    "nullable": true
                  },
                  "document_ids": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Temporary upload ids from POST /documents, in document order, to create a multi-document signing request (available to every company). Exactly one of document, document_id or document_ids or template_id (`400 CONFLICTING_DOCUMENT_SOURCE`); a repeated id answers `400 DUPLICATE_DOCUMENT_ID`, more than 20 `400 MAX_DOCUMENTS_EXCEEDED`, an unknown or expired upload `400 DOCUMENT_UPLOAD_NOT_FOUND`, a set above 100 MB `413 DOCUMENT_SET_TOO_LARGE`; more than one id while multi-document editing is suspended answers `409 MULTI_DOCUMENT_READ_ONLY`."
                  }
                },
                "oneOf": [
                  {
                    "required": [
                      "document"
                    ]
                  },
                  {
                    "required": [
                      "template_id"
                    ]
                  },
                  {
                    "required": [
                      "document_ids"
                    ]
                  }
                ]
              },
              "examples": {
                "document-based": {
                  "summary": "Create and send with document",
                  "value": {
                    "name": "Employment Contract - John Doe",
                    "description": "Full-time employment contract",
                    "document": "JVBERi0xLjQKJeLjz9MK...",
                    "expiration_hours": 168,
                    "recipients": [
                      {
                        "id": "temp_signer_1",
                        "first_name": "John",
                        "last_name": "Doe",
                        "email": "john.doe@example.com",
                        "designation": "Signer",
                        "order": 1,
                        "phone_number": "+1-555-0123",
                        "company": "Acme Corp",
                        "title": "Software Engineer"
                      }
                    ],
                    "fields": [
                      {
                        "recipient_id": "temp_signer_1",
                        "type": "signature",
                        "page": 1,
                        "x": 100,
                        "y": 500,
                        "width": 200,
                        "height": 50
                      },
                      {
                        "recipient_id": "temp_signer_1",
                        "type": "text",
                        "page": 1,
                        "x": 100,
                        "y": 400,
                        "width": 150,
                        "height": 30,
                        "variable_name": "phone_number",
                        "required": true,
                        "read_only": true
                      }
                    ],
                    "settings": {
                      "use_signing_order": true,
                      "send_signing_email": true
                    }
                  }
                },
                "template-based": {
                  "summary": "Create and send from template",
                  "value": {
                    "name": "NDA - Jane Smith",
                    "template_id": "123e4567-e89b-12d3-a456-426614174000",
                    "recipients": [
                      {
                        "first_name": "Jane",
                        "last_name": "Smith",
                        "email": "jane.smith@example.com",
                        "designation": "Signer",
                        "order": 1,
                        "company": "Tech Startup Inc"
                      }
                    ],
                    "expiration_hours": 72
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Signing request created and sent successfully. The response may include non-blocking anchor-tag warnings.",
            "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/CreateAndSendResponse"
                },
                "example": {
                  "id": "550e8400-e29b-41d4-a716-446655440000",
                  "name": "Employment Contract - John Doe",
                  "description": "Full-time employment contract",
                  "status": "sent",
                  "document_url": "https://storage.supabase.co/...",
                  "page_count": 3,
                  "expiration_hours": 168,
                  "settings": {
                    "use_signing_order": true,
                    "allow_download": true,
                    "attach_pdf_on_finish": true,
                    "send_signing_email": true,
                    "send_finish_email": true,
                    "send_expiration_email": true,
                    "send_cancellation_email": true,
                    "hand_drawn_only": false
                  },
                  "created_date": "2026-01-12T10:30:00Z",
                  "sent_date": "2026-01-12T10:30:00Z",
                  "template_id": null,
                  "first_signer": {
                    "id": "rec456-e89b-12d3-a456-426614174000",
                    "name": "John Doe",
                    "email": "john.doe@example.com",
                    "signing_link": "https://app.firma.dev/signing/rec456-e89b-12d3-a456-426614174000"
                  },
                  "recipients": [
                    {
                      "id": "rec456-e89b-12d3-a456-426614174000",
                      "first_name": "John",
                      "last_name": "Doe",
                      "name": "John Doe",
                      "email": "john.doe@example.com",
                      "designation": "Signer",
                      "order": 1
                    }
                  ],
                  "fields": [
                    {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "field_type": "signature",
                      "seal_participant_id": null
                    }
                  ],
                  "credits_remaining": 99
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid input or missing required signer data. Multi-document: `CONFLICTING_DOCUMENT_SOURCE`, `DUPLICATE_DOCUMENT_ID`, `MAX_DOCUMENTS_EXCEEDED`, `DOCUMENT_UPLOAD_NOT_FOUND`, `ANCHOR_DOCUMENT_REQUIRED`. Organization seals: `VALIDATION_ERROR` when `seal_participants` is neither an array nor `null`, when one of its entries has no `temp_id`, repeats a `temp_id` or has an `order` that is not a positive integer, or when the `seal_attribute` of a field is not `display_name`, `signatory_title` or `null`; `SEAL_UNAVAILABLE` when an entry omits `seal_id` and neither the workspace nor the company has an active default seal; on a document-based request with seal participants, `INVALID_SIGNING_ORDER` when a recipient has no `order` or the recipients and the seals do not form one sequence starting at 1, and `SEAL_ORDER_COLLISION` when two of them (recipients or seals) share an `order`. At the send step, `SEAL_NO_IMAGE_FIELD` when a seal participant of the request owns no field of type `stamp` (its seal image field): the request is not sent and no signing request is kept.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateAndSendValidationError"
                },
                "examples": {
                  "missing-recipient-data": {
                    "value": {
                      "error": "One or more signers are missing required information for sending",
                      "phase": "send_validation",
                      "validation_errors": [
                        {
                          "recipient_index": 1,
                          "recipient_email": "john@example.com",
                          "missing_fields": [
                            "phone_number",
                            "company"
                          ]
                        }
                      ]
                    }
                  },
                  "invalid-document": {
                    "value": {
                      "error": "Document must be valid base64-encoded PDF",
                      "phase": "create_validation"
                    }
                  },
                  "seal-no-image-field": {
                    "summary": "A seal participant has no seal image field",
                    "value": {
                      "error": "Each organization seal needs at least one seal image field.",
                      "code": "SEAL_NO_IMAGE_FIELD"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientCreditsError"
                }
              }
            }
          },
          "404": {
            "description": "The template was not found or is not in the API key's workspace. A seal named in `seal_participants` does not exist, belongs to another company or is limited to another workspace (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `SEAL_UNAVAILABLE` (a seal named in `seal_participants` is revoked or deleted, or is not the current version of its lineage; or the current version of an inherited template seal is revoked or deleted, or that seal has no current version), `MULTI_DOCUMENT_READ_ONLY`, `SEND_IN_PROGRESS`, `SEND_EFFECTS_EXIST`, `ALREADY_SENT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_INCONSISTENT`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_DISPATCH_STALE`. `SEND_EFFECTS_EXIST` and `ALREADY_SENT` may also carry `signing_request_id`: it is present when the signing request this call created was kept (its rollback was refused), so recover that request instead of retrying, since a retry creates a second request; without it, no request was kept.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/CreateAndSendConflictError"
                    },
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "required": [
                            "error",
                            "code"
                          ],
                          "properties": {
                            "code": {
                              "type": "string",
                              "enum": [
                                "SEAL_UNAVAILABLE"
                              ]
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "413": {
            "description": "DOCUMENT_SET_TOO_LARGE, or REQUEST_TOO_LARGE when the request payload exceeds 6,291,456 bytes. Upload large files with POST /documents, then pass document_id / document_ids instead of inline base64.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MultiDocumentError"
                    },
                    {
                      "$ref": "#/components/schemas/RequestTooLargeError"
                    }
                  ]
                },
                "example": {
                  "error": "Request exceeds the 6,291,456-byte payload limit. Upload large files with POST /documents and pass document_id / document_ids instead of inline base64.",
                  "code": "REQUEST_TOO_LARGE"
                }
              }
            }
          },
          "422": {
            "description": "Recipient email address is suppressed (previously bounced or marked as spam) and cannot be sent to",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnprocessableEntityError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Unexpected server error. Any partially-created signing request is rolled back, so no draft is left behind. Client-actionable send-step failures return 400, 402, or 422 instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Anchor-tag processing is disabled on the edge fallback (`ANCHOR_DISABLED_EDGE`): retry through the primary API route. Or organization seals are not enabled and either `seal_participants` is a non-empty array (answered before its entries are checked) or template inheritance keeps at least one seal (`SEALS_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "ANCHOR_DISABLED_EDGE",
                        "SEALS_DISABLED"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "createAndSendSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.createAndSendSigningRequest({\n    \"name\": \"Employment Contract - John Doe\",\n    \"description\": \"Full-time employment contract\",\n    \"document\": \"JVBERi0xLjQKJeLjz9MK...\",\n    \"expiration_hours\": 168,\n    \"recipients\": [\n        {\n            \"id\": \"temp_signer_1\",\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\",\n            \"email\": \"john.doe@example.com\",\n            \"designation\": \"Signer\",\n            \"order\": 1,\n            \"phone_number\": \"+1-555-0123\",\n            \"company\": \"Acme Corp\",\n            \"title\": \"Software Engineer\"\n        }\n    ],\n    \"fields\": [\n        {\n            \"recipient_id\": \"temp_signer_1\",\n            \"type\": \"signature\",\n            \"page\": 1,\n            \"x\": 100,\n            \"y\": 500,\n            \"width\": 200,\n            \"height\": 50\n        },\n        {\n            \"recipient_id\": \"temp_signer_1\",\n            \"type\": \"text\",\n            \"page\": 1,\n            \"x\": 100,\n            \"y\": 400,\n            \"width\": 150,\n            \"height\": 30,\n            \"variable_name\": \"phone_number\",\n            \"required\": true,\n            \"read_only\": true\n        }\n    ],\n    \"settings\": {\n        \"use_signing_order\": true,\n        \"send_signing_email\": true\n    }\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}": {
      "get": {
        "summary": "Get Signing Request",
        "description": "Retrieve a specific signing request by ID",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signing request retrieved successfully. Returns a detailed nested shape with status as an object and timestamps grouped together.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.getSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Partially Update Signing Request",
        "description": "Update signing request properties, a single recipient, OR a single field. Cannot update multiple entity types in one request. Cannot update after signing request has been sent, completed, or cancelled, except for a seal swap (see `seal_participant`). A `seal_participant` that names a seal answers 404 `NOT_FOUND` when the seal does not exist or belongs to another company, and 400 `SEAL_UNAVAILABLE` when the seal is revoked, deleted or not the current version of its lineage, and also when it is limited to a workspace other than the signing request's. These answers are for adding a seal participant and for changing its seal. A seal swap (`swap_to_seal_id`) answers differently for the new seal: 404 `NOT_FOUND` when it does not exist, belongs to another company or is limited to a workspace other than the signing request's; 409 `SEAL_UNAVAILABLE` when it is revoked, deleted or not the current version of its lineage; 400 `SEAL_FIELD_REQUIRED` when the seal participant has no stamp field on the signing request. Adding a seal participant or changing its seal answers 503 `SEALS_DISABLED` when organization seals are not enabled. Adding a seal participant requires `order` (see the order contract). A field that belongs to a seal participant accepts only `position` and `page_number` changes; every other key of `field`, `recipient_id` included, is ignored.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "description": "Update signing request properties only",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "New name for signing request"
                      },
                      "description": {
                        "type": "string",
                        "description": "New description"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "Replace document with new base64-encoded PDF. Page count will be auto-extracted."
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "New expiration hours"
                      },
                      "settings": {
                        "$ref": "#/components/schemas/SigningRequestSettings",
                        "description": "Update settings"
                      },
                      "language": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "en",
                          "es",
                          "it",
                          "pt",
                          "fr",
                          "de",
                          "el",
                          "ru",
                          "pl",
                          "cs",
                          "sv",
                          "nl",
                          "ro",
                          "nb",
                          "ca"
                        ],
                        "description": "Opt-in email language for this signing request. When set, all signer-facing emails (and their date formatting) use it. Omit or null to fall back to the workspace, then company, default language (unchanged behavior)."
                      },
                      "completion_title": {
                        "type": "string",
                        "nullable": true,
                        "description": "Heading shown on the completion page after signing. Null or an empty string clears the override; omitted leaves it unchanged.",
                        "maxLength": 200
                      },
                      "completion_message": {
                        "type": "string",
                        "nullable": true,
                        "description": "Body text shown on the completion page after signing. Null or an empty string clears the override; omitted leaves it unchanged.",
                        "maxLength": 1000
                      },
                      "completion_redirect_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "URL the signer is redirected to from the completion page. Must use https:// (http://localhost and http://127.0.0.1 are also accepted on test-mode signing requests). Null or an empty string clears the override; omitted leaves it unchanged.",
                        "maxLength": 2000
                      },
                      "completion_redirect_delay": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. Null clears the override; omitted leaves it unchanged.",
                        "minimum": 0,
                        "maximum": 30
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "recipient"
                    ],
                    "description": "Create or update a single recipient",
                    "properties": {
                      "recipient": {
                        "$ref": "#/components/schemas/Recipient",
                        "description": "Recipient to create (omit id) or update (include id). When updating first_name or last_name, the name field is automatically reconstructed using existing values from database for any field not provided. Result: 'First Last' if both exist, 'First' if only first_name."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "field"
                    ],
                    "description": "Create or update a single field",
                    "properties": {
                      "field": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Include to update existing field, omit to create new"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "text",
                              "signature",
                              "date",
                              "checkbox",
                              "initial",
                              "initials",
                              "dropdown",
                              "radio_buttons",
                              "textarea",
                              "text_area",
                              "url",
                              "file",
                              "stamp",
                              "approval_signature",
                              "approval_checkmark",
                              "approval_date"
                            ],
                            "description": "Field type. Accepts 'initial' or 'initials', 'textarea' or 'text_area'. Required for new fields. url fields are automatically read-only. file fields allow signers to upload attachments (images/PDF). stamp fields display a pre-configured image."
                          },
                          "position": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number",
                                "description": "X position on document"
                              },
                              "y": {
                                "type": "number",
                                "description": "Y position on document"
                              },
                              "width": {
                                "type": "number",
                                "description": "Field width"
                              },
                              "height": {
                                "type": "number",
                                "description": "Field height"
                              }
                            },
                            "description": "Position object. All properties required for new fields."
                          },
                          "page_number": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Page number (1-indexed). Required for new fields."
                          },
                          "required": {
                            "type": "boolean",
                            "description": "Whether field is required"
                          },
                          "recipient_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "Recipient ID to assign the field to; `null` removes the field's recipient and leaves the field unassigned."
                          },
                          "variable_name": {
                            "type": "string",
                            "description": "Variable name for prefilled data mapping"
                          },
                          "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."
                          },
                          "dropdown_options": {
                            "description": "Options for dropdown fields",
                            "oneOf": [
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              {
                                "type": "object"
                              }
                            ]
                          },
                          "format_rules": {
                            "type": "object",
                            "description": "Format rules (e.g., date format, urlDisplayText for url fields, acceptedFileTypes for file fields)"
                          },
                          "validation_rules": {
                            "type": "object",
                            "description": "Validation rules for the field"
                          },
                          "multi_group_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Group ID for radio button groups"
                          },
                          "date_default": {
                            "type": "string",
                            "description": "Default date value"
                          },
                          "date_signing_default": {
                            "type": "boolean",
                            "description": "For date fields, use signing date as default"
                          },
                          "read_only": {
                            "type": "boolean",
                            "description": "Whether field is read-only (automatically true for url fields)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Static value for read-only fields. For url fields, this is the URL to link to."
                          },
                          "final_value": {
                            "type": "string",
                            "description": "Final value of the field (for pre-filled read-only fields)"
                          }
                        }
                      },
                      "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 signing request 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`."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "seal_participant"
                    ],
                    "description": "Add, update or swap one seal participant of the signing request. Send only the `seal_participant` key.",
                    "properties": {
                      "seal_participant": {
                        "type": "object",
                        "description": "One of three uses, chosen by the keys sent; each answers `{ \"seal_participant\": ... }`. Add: send `seal_id` and `order` without `id`; answers 201. Update: send `id` with `order` to move the participant (a `seal_id` sent together with `order` is ignored), or `id` with `seal_id` alone to change its seal; answers 200. Add and update are possible only before the request is sent (409 `ALREADY_SENT` afterwards). Swap: send `id` with `swap_to_seal_id` to replace the seal of a paused seal participant; answers 200. A swap is possible only on a request that was sent and is not finished or cancelled (409 `SEAL_MUTATION_NOT_ALLOWED` on a request that was not sent, and when the participant is not paused), and only with an API key of the protected workspace (403 `PROTECTED_KEY_REQUIRED` otherwise). When `swap_to_seal_id` is sent, `seal_id` and `order` are ignored.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID of the seal participant to update or swap. Omit it to add a seal participant."
                          },
                          "seal_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID of the organization seal. Required to add a seal participant; on an update without `order` it becomes the seal of the participant. The seal must belong to the company, be the current version of its lineage, be neither revoked nor deleted, and not be limited to another workspace."
                          },
                          "order": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Position in the signing order, shared with the recipients' order space. Required to add a seal participant; on an update it moves the participant."
                          },
                          "swap_to_seal_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID of the organization seal that replaces the seal of a paused seal participant on a sent request."
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "examples": {
                "update-properties": {
                  "summary": "Update properties",
                  "value": {
                    "name": "Updated Contract Name",
                    "expiration_hours": 72
                  }
                },
                "update-recipient": {
                  "summary": "Update single recipient",
                  "value": {
                    "recipient": {
                      "id": "rec123-e89b-12d3-a456-426614174000",
                      "first_name": "John",
                      "last_name": "Smith",
                      "email": "john.smith@example.com",
                      "designation": "Signer",
                      "order": 1
                    }
                  }
                },
                "add-recipient": {
                  "summary": "Add new recipient",
                  "value": {
                    "recipient": {
                      "first_name": "Jane",
                      "last_name": "Doe",
                      "email": "jane@example.com",
                      "designation": "Signer",
                      "order": 2
                    }
                  }
                },
                "create-url-field": {
                  "summary": "Create URL field",
                  "value": {
                    "field": {
                      "type": "url",
                      "position": {
                        "x": 100,
                        "y": 200,
                        "width": 150,
                        "height": 30
                      },
                      "page_number": 1,
                      "read_only_value": "https://example.com/terms",
                      "format_rules": {
                        "urlDisplayText": "View Terms & Conditions"
                      }
                    }
                  }
                },
                "create-file-field": {
                  "summary": "Create file upload field",
                  "value": {
                    "field": {
                      "type": "file",
                      "position": {
                        "x": 100,
                        "y": 300,
                        "width": 200,
                        "height": 40
                      },
                      "page_number": 1,
                      "required": true,
                      "format_rules": {
                        "acceptedFileTypes": "image_and_pdf"
                      }
                    }
                  }
                },
                "update-field": {
                  "summary": "Update existing field position",
                  "value": {
                    "field": {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "position": {
                        "x": 120,
                        "y": 220
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signing request updated successfully. Response shape depends on what was updated: properties update returns {id, name, template_description, document_url, expiration_hours}; recipient update returns the full recipient object; field update returns the full field object; a seal participant update or swap returns `{ \"seal_participant\": <SealParticipantApi> }`. Response may include a 'warning' field for email format validation warnings (non-blocking).",
            "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": {
                  "anyOf": [
                    {
                      "type": "object",
                      "description": "Response when updating properties",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string"
                        },
                        "template_description": {
                          "type": "string",
                          "nullable": true
                        },
                        "document_url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "expiration_hours": {
                          "type": "integer"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "description": "Response when updating/creating a recipient"
                    },
                    {
                      "type": "object",
                      "description": "Response when updating/creating a field"
                    },
                    {
                      "type": "object",
                      "description": "Response when updating a seal participant or swapping its seal",
                      "required": [
                        "seal_participant"
                      ],
                      "properties": {
                        "seal_participant": {
                          "$ref": "#/components/schemas/SealParticipantApi"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "A recipient, a field or a seal participant was created. The body is the created recipient or field object; for a seal participant it is `{ \"seal_participant\": <SealParticipantApi> }`. Updating a seal participant answers 200 with the same `{ \"seal_participant\": ... }` body.",
            "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": {
                  "anyOf": [
                    {
                      "type": "object",
                      "description": "The created recipient"
                    },
                    {
                      "type": "object",
                      "description": "The created field"
                    },
                    {
                      "type": "object",
                      "description": "The created seal participant",
                      "required": [
                        "seal_participant"
                      ],
                      "properties": {
                        "seal_participant": {
                          "$ref": "#/components/schemas/SealParticipantApi"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Cannot update both properties and recipient in same request. Multi-document: `PAGE_COUNT_MISMATCH`, `DIMENSION_MISMATCH`, `ANCHOR_MISMATCH` (inline document replacement; `ANCHOR_MISMATCH`: the anchors of the replacement do not resolve as stored). Multi-document field writes: `VALIDATION_ERROR` with key `page` (a page beyond the document's page count) or `documents_layout_version`. Organization seals: `SEAL_FIELD_REQUIRED` when a seal swap is sent for a seal participant that has no stamp field on the signing request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "mixed-update": {
                    "value": {
                      "error": "Invalid request",
                      "message": "Cannot update both properties and recipient in the same request"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "description": "A seal swap (`swap_to_seal_id`) was sent with an API key that is not of the protected workspace (`PROTECTED_KEY_REQUIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Signing request or seal participant not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": "Signing request not found",
                      "code": "NOT_FOUND"
                    }
                  },
                  "seal_not_found": {
                    "value": {
                      "error": "Seal not found",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `ALREADY_SENT`, `ALREADY_FINISHED`, `ALREADY_CANCELLED`, `SEND_IN_PROGRESS`, `DOCUMENTS_LAYOUT_VERSION_REQUIRED`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`, `SIGNED_DATA_IMMUTABLE`, `MULTI_DOCUMENT_REPLACE_UNSUPPORTED`, `SEAL_MUTATION_NOT_ALLOWED`, `SEAL_UNAVAILABLE`. `MULTI_DOCUMENT_REPLACE_UNSUPPORTED`: an inline `document` on a request with more than one document (use the /documents routes). `SEAL_MUTATION_NOT_ALLOWED`: a seal swap on a request that was not sent, or of a seal participant that is not paused. `SEAL_UNAVAILABLE`: the new seal of a seal swap is revoked, deleted or not the current version of its lineage.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/MultiDocumentError"
                    },
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "required": [
                            "error",
                            "code"
                          ],
                          "properties": {
                            "code": {
                              "type": "string",
                              "enum": [
                                "SEAL_UNAVAILABLE"
                              ]
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "503": {
            "description": "Organization seals are not enabled and a seal participant is added or its seal is changed (`SEALS_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "patchSigningRequest",
        "x-participant-order-contract": {
          "membership": "Signer and Approver recipients plus organization seal participants share one contiguous 1-based order space. CC recipients use a separate sequence and never consume a participant position.",
          "patch": "On an unsent document, order must be in [1..n] for a move and [1..n+1] for a create. A move is shift-insert: every participant between the old and new positions is renumbered. A create with omitted order appends, except for a seal participant: its order is required, and an omitted order or an order of 0 answers 400 `VALIDATION_ERROR`. For any other participant an explicit order 0 is invalid.",
          "lockedStates": "A sent request accepts no membership or order change and answers 409 ALREADY_SENT (the one exception is swapping a paused seal participant of a sent request that is not finished). On an aborted-send request, an applied participant can narrow the reachable interval and an invalid move returns SIGNING_ORDER_LOCKED_APPLIED.",
          "create": "When no seal is present, tied recipient order values are resolved deterministically and compacted to [1..n]. A document-based create with seal participants rejects a non-contiguous space with INVALID_SIGNING_ORDER and two entries (recipients or seals) sharing an order with SEAL_ORDER_COLLISION. When use_signing_order is false, or any recipient omits order, participant orders follow array order; this fallback is a rule of request creation for requests without seal participants, and a document-based create with seal participants rejects a recipient without an order with INVALID_SIGNING_ORDER.",
          "sideEffects": "Retrying a create after a later field write fails creates a second participant, matching the existing non-idempotent create contract. PARTICIPANTS_CHANGED is a concurrent-write signal: another write to the same participant set committed while this call was running. No route compares against a version you loaded; re-read and retry.",
          "errors": [
            "INVALID_SIGNING_ORDER",
            "ALREADY_SENT",
            "SIGNING_ORDER_LOCKED_APPLIED",
            "PARTICIPANTS_CHANGED"
          ]
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.patchSigningRequest({\n    id: \"id\",\n    body: {\n        name: \"Updated Contract Name\",\n        expiration_hours: 72\n    }\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "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.\n\n**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.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "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 the updated signing request and 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": {
                  "$ref": "#/components/schemas/SigningRequestUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation errors. All section errors returned together. 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/SigningRequestUpdateError"
                },
                "example": {
                  "error": "Validation failed",
                  "message": "Multiple validation errors occurred",
                  "details": {
                    "recipients": [
                      "Recipient 1: email is invalid"
                    ],
                    "deleted_recipients": [
                      "Cannot reassign: designations must match"
                    ],
                    "fields": [
                      "Field 2: x coordinate must be between 0 and 100"
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `ALREADY_SENT`, `ALREADY_FINISHED`, `ALREADY_CANCELLED`, `SEND_IN_PROGRESS`, `DOCUMENTS_LAYOUT_VERSION_REQUIRED`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_SET_INCONSISTENT`, `SIGNED_DATA_IMMUTABLE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateSigningRequest",
        "x-participant-order-contract": {
          "membership": "Signer and Approver recipients plus organization seal participants share one contiguous 1-based order space. CC recipients use a separate sequence and never consume a participant position.",
          "patch": "On an unsent document, order must be in [1..n] for a move and [1..n+1] for a create. A move is shift-insert: every participant between the old and new positions is renumbered. A create with omitted order appends. Explicit order 0 is invalid.",
          "lockedStates": "A sent request accepts no membership or order change and answers 409 ALREADY_SENT (the one exception is swapping a paused seal participant of a sent request that is not finished). On an aborted-send request, an applied participant can narrow the reachable interval and an invalid move returns SIGNING_ORDER_LOCKED_APPLIED.",
          "create": "When no seal is present, tied recipient order values are resolved deterministically and compacted to [1..n]. A document-based create with seal participants rejects a non-contiguous space with INVALID_SIGNING_ORDER and two entries (recipients or seals) sharing an order with SEAL_ORDER_COLLISION. When use_signing_order is false, or any recipient omits order, participant orders follow array order; this fallback is a rule of request creation for requests without seal participants, and a document-based create with seal participants rejects a recipient without an order with INVALID_SIGNING_ORDER.",
          "sideEffects": "Retrying a create after a later field write fails creates a second participant, matching the existing non-idempotent create contract. PARTICIPANTS_CHANGED is a concurrent-write signal: another write to the same participant set committed while this call was running. No route compares against a version you loaded; re-read and retry.",
          "errors": [
            "INVALID_SIGNING_ORDER",
            "ALREADY_SENT",
            "SIGNING_ORDER_LOCKED_APPLIED",
            "PARTICIPANTS_CHANGED"
          ]
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.updateSigningRequest({\n    id: \"id\",\n    signing_request_properties: {\n        name: \"Updated Contract Name\",\n        expiration_hours: 72\n    },\n    recipients: [{\n            id: \"rec1-e89b-12d3-a456-426614174000\",\n            first_name: \"John\",\n            last_name: \"Smith\",\n            email: \"john.smith@example.com\",\n            designation: \"Signer\",\n            order: 1\n        }, {\n            first_name: \"Jane\",\n            last_name: \"Doe\",\n            email: \"jane@example.com\",\n            designation: \"Signer\",\n            order: 2\n        }],\n    deleted_recipients: [{\n            recipient_id: \"rec2-e89b-12d3-a456-426614174000\",\n            field_action: \"reassign\",\n            reassign_to_recipient_id: \"rec1-e89b-12d3-a456-426614174000\"\n        }],\n    fields: [{\n            id: \"field1-e89b-12d3-a456-426614174000\",\n            type: \"signature\",\n            position: {\n                x: 15,\n                y: 85,\n                width: 30,\n                height: 10\n            },\n            page_number: 1,\n            required: true,\n            recipient_id: \"rec1-e89b-12d3-a456-426614174000\"\n        }],\n    reminders: [{\n            hours: 48,\n            all_users: true,\n            subject: \"Reminder: Please sign the document\",\n            message: \"This is a reminder to complete your signature.\"\n        }]\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete a signing request",
        "description": "Deletes an unsent (draft) signing request. Only signing requests that have not been sent can be deleted. For sent signing requests, use the cancel endpoint instead.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Signing request deleted successfully",
            "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/SigningRequestDeleteResponse"
                },
                "example": {
                  "message": "Signing request deleted successfully",
                  "signing_request_id": "550e8400-e29b-41d4-a716-446655440000",
                  "deleted_on": "2026-05-30T10:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Cannot delete a signing request that has been sent. MULTI_DOCUMENT_READ_ONLY: an unsent multi-document request while multi-document editing is suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Cannot delete a signing request that has been sent. Use cancel instead.",
                  "code": "ALREADY_SENT"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.deleteSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/users": {
      "get": {
        "summary": "Get signing request users",
        "description": "Retrieve all recipients/users for a specific signing request",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signing request users retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestUserListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "user123-e89b-12d3-a456-426614174000",
                      "name": "Alice Johnson",
                      "email": "alice@example.com",
                      "first_name": "Alice",
                      "last_name": "Johnson",
                      "designation": "Signer",
                      "order": 1,
                      "finished_on": "2024-03-15T14:30:00Z",
                      "declined_on": null,
                      "decline_reason": null,
                      "phone_number": "+1-555-0101",
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": "CEO",
                      "company": "Acme Corp",
                      "custom_fields": null,
                      "required_fields": [
                        "email",
                        "first_name"
                      ],
                      "missing_fields": [],
                      "required_read_only_fields": [],
                      "ready_to_send": true
                    },
                    {
                      "id": "user456-e89b-12d3-a456-426614174000",
                      "name": "Bob Williams",
                      "email": "bob@example.com",
                      "first_name": "Bob",
                      "last_name": "Williams",
                      "designation": "Signer",
                      "order": 2,
                      "finished_on": null,
                      "declined_on": null,
                      "decline_reason": null,
                      "phone_number": null,
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": null,
                      "company": null,
                      "custom_fields": null,
                      "required_fields": [
                        "email",
                        "first_name",
                        "phone_number"
                      ],
                      "missing_fields": [
                        "phone_number"
                      ],
                      "required_read_only_fields": [
                        {
                          "variable_name": "contract_amount",
                          "field_type": "number",
                          "has_value": false
                        }
                      ],
                      "ready_to_send": false
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestUsers",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestUsers({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/fields": {
      "get": {
        "summary": "Get signing request fields",
        "description": "Retrieve all fields for a specific signing request with their values",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signing request fields retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestFieldListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "field789-e89b-12d3-a456-426614174000",
                      "type": "signature",
                      "recipient_id": "user456-e89b-12d3-a456-426614174000",
                      "required": true,
                      "read_only": false,
                      "value": "data:image/png;base64,iVBOR...",
                      "position": {
                        "x": 100.5,
                        "y": 200.75,
                        "width": 200,
                        "height": 50
                      },
                      "page_number": 1,
                      "variable_name": null,
                      "variable_defined_name": null,
                      "companies_workspaces_signing_requests_id": "sr123-e89b-12d3-a456-426614174000",
                      "companies_workspaces_signing_requests_users_id": "user456-e89b-12d3-a456-426614174000",
                      "field_type": "signature",
                      "x_postion": 100.5,
                      "y_position": 200.75,
                      "width": 200,
                      "heigh": 50,
                      "final_value": "data:image/png;base64,iVBOR...",
                      "deleted": 0
                    },
                    {
                      "id": "field012-e89b-12d3-a456-426614174000",
                      "type": "text",
                      "recipient_id": "user456-e89b-12d3-a456-426614174000",
                      "required": true,
                      "read_only": false,
                      "value": "Alice Johnson",
                      "position": {
                        "x": 150,
                        "y": 300,
                        "width": 250,
                        "height": 30
                      },
                      "page_number": 1,
                      "variable_name": "full_name",
                      "variable_defined_name": null,
                      "companies_workspaces_signing_requests_id": "sr123-e89b-12d3-a456-426614174000",
                      "companies_workspaces_signing_requests_users_id": "user456-e89b-12d3-a456-426614174000",
                      "field_type": "text",
                      "x_postion": 150,
                      "y_position": 300,
                      "width": 250,
                      "heigh": 30,
                      "final_value": "Alice Johnson",
                      "deleted": 0
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestFields({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/reminders": {
      "get": {
        "summary": "Get signing request reminders",
        "description": "Retrieve all reminders scheduled for a specific signing request",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signing request reminders retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Reminder"
                  }
                },
                "example": [
                  {
                    "id": "remind789-e89b-12d3-a456-426614174000",
                    "hours": 48,
                    "subject": "Urgent: Document signature required",
                    "message": "Please complete your signature at your earliest convenience.",
                    "all_users": false,
                    "template_user_id": "user456-e89b-12d3-a456-426614174000",
                    "date_created": "2024-03-10T09:00:00Z",
                    "date_changed": "2024-03-10T09:00:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestReminders",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestReminders({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/audit": {
      "get": {
        "summary": "Get signing request audit trail",
        "description": "Retrieve the complete audit trail for a signing request, combining admin actions (created, edited, sent, cancelled) and signer actions (viewed, signed, declined, downloaded). Events are sorted chronologically.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Audit trail retrieved successfully",
            "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/AuditTrailListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestAuditTrail",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestAuditTrail({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/send": {
      "post": {
        "summary": "Send signing request",
        "description": "Send a signing request to all recipients via email. This triggers email delivery and sets the sent_on timestamp.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signing request sent successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 60 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendSigningRequestResponse"
                },
                "example": {
                  "message": "Signing request sent successfully",
                  "signing_request_id": "123e4567-e89b-12d3-a456-426614174000",
                  "recipients_notified": 3,
                  "sent_date": "2024-03-20T10:15:00Z",
                  "expires_at": "2024-04-20T10:15:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Signing request already sent or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "alreadySent": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Signing request has already been sent"
                    }
                  },
                  "expired": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Signing request has expired"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "sendSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.sendSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/cancel": {
      "post": {
        "summary": "Cancel a signing request",
        "description": "Cancels a signing request that hasn't been completed yet. Can only cancel requests that have been sent and are not already finished or cancelled.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Optional cancellation reason"
                  },
                  "notify_signers": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether to notify signers of cancellation"
                  }
                }
              },
              "example": {
                "reason": "No longer needed",
                "notify_signers": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signing request cancelled successfully",
            "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/CancelSigningRequestResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Cannot cancel (already cancelled, finished, or not sent)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "cancelSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.cancelSigningRequest({\n    id: \"id\",\n    reason: \"No longer needed\",\n    notify_signers: true\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/resend": {
      "post": {
        "summary": "Resend signing request to specific recipients",
        "description": "Resends signing request notifications to one or more recipients who are currently eligible to sign. For requests with signing order enabled, can only resend to recipients at the current active order. Cannot resend to recipients who have already signed.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recipient_ids"
                ],
                "properties": {
                  "recipient_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Array of recipient user IDs to resend to",
                    "minItems": 1
                  },
                  "custom_message": {
                    "type": "string",
                    "maxLength": 1000,
                    "description": "Optional custom message to include in resend notification"
                  }
                }
              },
              "example": {
                "recipient_ids": [
                  "123e4567-e89b-12d3-a456-426614174000"
                ],
                "custom_message": "Gentle reminder to complete your signature"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signing request resent successfully",
            "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/ResendSigningRequestResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Cannot resend (recipients already signed, invalid signing order, or request not sent/cancelled/finished). SEND_IN_PROGRESS: a send of this request is in progress",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResendConflictError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "resendSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.resendSigningRequest({\n    id: \"id\",\n    recipient_ids: [\"123e4567-e89b-12d3-a456-426614174000\"],\n    custom_message: \"Gentle reminder to complete your signature\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks": {
      "get": {
        "summary": "List Webhooks",
        "description": "Retrieve a paginated list of webhooks",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Page number"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Items per page"
          },
          {
            "name": "enabled",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1"
              ]
            },
            "description": "Filter by enabled status (0=disabled, 1=enabled)"
          },
          {
            "name": "url",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by webhook URL (partial match, case-insensitive)"
          },
          {
            "name": "event",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by event type (e.g., 'signing_request.completed')"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter webhooks created after this date (ISO 8601 format)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter webhooks created before this date (ISO 8601 format)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "url",
                "enabled",
                "created_on",
                "last_changed_on",
                "consecutive_failures"
              ],
              "default": "created_on"
            },
            "description": "Field to sort by"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort order"
          },
          {
            "name": "workspace_id",
            "in": "query",
            "description": "Filter webhooks by workspace. When provided, returns only webhooks scoped to that workspace. When omitted, returns only company-level webhooks.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhooks retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid date format or sort parameters",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Invalid date format",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_before"
                          ],
                          "message": "created_before must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Invalid sort parameter",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "sort_by"
                          ],
                          "message": "Invalid sort field"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWebhooks",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.listWebhooks();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Create Webhook",
        "description": "Create a new webhook",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "signing_request.created",
                        "signing_request.sent",
                        "signing_request.viewed",
                        "signing_request.completed",
                        "signing_request.declined",
                        "signing_request.cancelled",
                        "signing_request.expired",
                        "signing_request.voided",
                        "signing_request.field.completed",
                        "signing_request.deleted",
                        "signing_request.resent",
                        "signing_request.credits.purchased",
                        "template.created",
                        "template.updated",
                        "template.deleted",
                        "template.field.added",
                        "template.used",
                        "workspace.created",
                        "workspace.updated",
                        "workspace.deleted",
                        "domain.verified",
                        "domain.verification.failed",
                        "organization_seal.created",
                        "organization_seal.updated",
                        "organization_seal.deleted",
                        "organization_seal.erased",
                        "signing_request.seal.applied",
                        "signing_request.seal.paused",
                        "signing_request.seal.swapped"
                      ]
                    },
                    "description": "Array of event types to subscribe to. See the full list for available events including organization seal and signing request seal events."
                  },
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Optional workspace ID. When provided, creates a workspace-scoped webhook. When omitted, creates a company-level webhook."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook created successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 60 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.createWebhook({\n    url: \"url\",\n    events: [\"events\"]\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/{id}": {
      "get": {
        "summary": "Get Webhook",
        "description": "Retrieve a specific webhook by ID",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.getWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Update Webhook",
        "description": "Update an existing webhook",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "signing_request.created",
                        "signing_request.sent",
                        "signing_request.viewed",
                        "signing_request.completed",
                        "signing_request.declined",
                        "signing_request.cancelled",
                        "signing_request.expired",
                        "signing_request.voided",
                        "signing_request.field.completed",
                        "signing_request.deleted",
                        "signing_request.resent",
                        "signing_request.credits.purchased",
                        "template.created",
                        "template.updated",
                        "template.deleted",
                        "template.field.added",
                        "template.used",
                        "workspace.created",
                        "workspace.updated",
                        "workspace.deleted",
                        "domain.verified",
                        "domain.verification.failed",
                        "organization_seal.created",
                        "organization_seal.updated",
                        "organization_seal.deleted",
                        "organization_seal.erased",
                        "signing_request.seal.applied",
                        "signing_request.seal.paused",
                        "signing_request.seal.swapped"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook updated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 60 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.updateWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete a webhook",
        "description": "Soft delete a webhook by ID. This marks the webhook as deleted but retains the data.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook deleted successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 60 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                },
                "example": {
                  "message": "Webhook deleted successfully"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.deleteWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "summary": "Test a webhook",
        "description": "Send a test payload to the webhook URL to verify it's working correctly",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Test webhook sent successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 10 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestWebhookResponse"
                },
                "example": {
                  "success": true,
                  "status_code": 200,
                  "webhook_event_id": "123e4567-e89b-12d3-a456-426614174000",
                  "message": "Test webhook delivered successfully",
                  "headers_sent": {
                    "X-Firma-Event": "webhook.test",
                    "X-Firma-Signature": "Generated HMAC-SHA256 signature",
                    "X-Firma-Delivery": "123e4567-e89b-12d3-a456-426614174000"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "testWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.testWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/rotate-secret": {
      "post": {
        "summary": "Rotate webhook signing secret",
        "description": "Generates a new webhook signing secret for the company. The old secret remains valid for 7 days to allow graceful migration. Rate limited to 1 request per minute.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Secret rotated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 1 request per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateSecretResponse"
                },
                "example": {
                  "message": "Webhook secret rotated successfully",
                  "new_secret": "a1b2c3d4e5f6...",
                  "grace_period_hours": 168,
                  "warning": "Update your webhook signature verification to use the new secret. The old secret will remain valid for 7 days."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "description": "Rate limit exceeded (1 rotation per minute)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "rotateWebhookSecret",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.rotateWebhookSecret();\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/secret-status": {
      "get": {
        "summary": "Get webhook secret rotation status",
        "description": "Returns information about the current webhook secret including rotation status and expiry of old secret if applicable.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Secret status retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretStatusResponse"
                },
                "example": {
                  "created_at": "2025-09-01T10:00:00Z",
                  "last_rotated_at": "2025-10-16T12:00:00Z",
                  "grace_period_active": true,
                  "grace_period_ends_at": "2025-10-23T12:00:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "No webhook configuration found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWebhookSecretStatus",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.getWebhookSecretStatus();\nconsole.log(response);"
          }
        ]
      }
    },
    "/generate-template-token": {
      "post": {
        "summary": "Generate JWT token for embedding templates",
        "description": "Creates a JWT token for embedding a template with 24-hour expiration. This is the standard endpoint for JWT generation.\n\n**Note**: The standalone `generate-embedded-template-token` function is deprecated in favor of this router-based endpoint.",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateJWTRequest"
              },
              "example": {
                "companies_workspaces_templates_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "JWT generated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateTemplateTokenResponse"
                },
                "example": {
                  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
                  "expires_at": "2024-04-20T10:00:00Z",
                  "jwt_record_id": "jwt123-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "generateTemplateToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.generateTemplateToken({\n    companies_workspaces_templates_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/revoke-template-token": {
      "post": {
        "summary": "Revoke Template JWT Token",
        "description": "Revoke a previously generated JWT token, preventing it from being used for template embedding. This is the standard endpoint for revoking template JWTs.",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeJWTRequest"
              },
              "example": {
                "jwt_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT revoked successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeJWTResponse"
                },
                "example": {
                  "message": "JWT revoked successfully",
                  "jwt_id": "123e4567-e89b-12d3-a456-426614174000",
                  "revoked_at": "2024-03-20T16:45:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - JWT already revoked or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "alreadyRevoked": {
                    "value": {
                      "error": "Bad Request",
                      "message": "JWT has already been revoked"
                    }
                  },
                  "invalidJwt": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Invalid JWT ID"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "revokeTemplateToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.revokeTemplateToken({\n    jwt_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/jwt/generate-signing-request": {
      "post": {
        "summary": "Generate JWT token for signing request",
        "description": "Generate a JWT token for embedding a signing request editor. JWT expires after 7 days.",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateSigningRequestJWTRequest"
              },
              "example": {
                "companies_workspaces_signing_requests_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT generated successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateSigningRequestJWTResponse"
                },
                "example": {
                  "jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
                  "jwt_id": "jwt123-e89b-12d3-a456-426614174000",
                  "expires_at": "2024-03-27T10:00:00Z",
                  "signing_request_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "generateSigningRequestToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.generateSigningRequestToken({\n    companies_workspaces_signing_requests_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/jwt/revoke-signing-request": {
      "post": {
        "summary": "Revoke a signing request JWT token",
        "description": "Revoke a previously generated JWT token for a signing request, preventing it from being used for embedded editing",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeSigningRequestJWTRequest"
              },
              "example": {
                "jwt_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT revoked successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Unix timestamp when rate limit resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeSigningRequestJWTResponse"
                },
                "example": {
                  "message": "JWT revoked successfully",
                  "jwt_id": "123e4567-e89b-12d3-a456-426614174000",
                  "revoked_at": "2024-03-20T16:45:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - JWT already revoked or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "alreadyRevoked": {
                    "value": {
                      "error": "Bad Request",
                      "message": "JWT has already been revoked"
                    }
                  },
                  "invalidJwt": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Invalid JWT ID"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "revokeSigningRequestToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.revokeSigningRequestToken({\n    jwt_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/email-templates": {
      "get": {
        "summary": "List workspace email templates",
        "description": "Retrieve all custom email templates for a workspace",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Email templates retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceEmailTemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaceEmailTemplates",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.listWorkspaceEmailTemplates({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/email-templates/{email_type}": {
      "get": {
        "summary": "Get workspace email template",
        "description": "Retrieve a specific email template by type for a workspace",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "resend_notification",
                "signing_expired",
                "signing_cancelled",
                "signing_declined",
                "signing_declined_admin",
                "signing_completed",
                "signer_identity_changed"
              ]
            },
            "description": "Email template type"
          }
        ],
        "responses": {
          "200": {
            "description": "Email template retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplate"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspaceEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.getWorkspaceEmailTemplate({\n    workspace_id: \"workspace_id\",\n    email_type: \"signing_invite\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Create or update workspace email template",
        "description": "Create or update a custom email template for a specific type. If a template already exists for this type, it will be updated. A warning is returned if the template body does not contain {{signing_link}}.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "resend_notification",
                "signing_expired",
                "signing_cancelled",
                "signing_declined",
                "signing_declined_admin",
                "signing_completed",
                "signer_identity_changed"
              ]
            },
            "description": "Email template type"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "body"
                ],
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Email subject line"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Email body (HTML). Use {{signing_link}} placeholder for the signing URL."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email template updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Email template created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspaceEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.updateWorkspaceEmailTemplate({\n    workspace_id: \"workspace_id\",\n    email_type: \"signing_invite\",\n    subject: \"subject\",\n    body: \"body\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete workspace email template",
        "description": "Delete a custom email template. The workspace will revert to using the company-level or default template for this type.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "resend_notification",
                "signing_expired",
                "signing_cancelled",
                "signing_declined",
                "signing_declined_admin",
                "signing_completed",
                "signer_identity_changed"
              ]
            },
            "description": "Email template type"
          }
        ],
        "responses": {
          "200": {
            "description": "Email template deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateDeleteResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWorkspaceEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.deleteWorkspaceEmailTemplate({\n    workspace_id: \"workspace_id\",\n    email_type: \"signing_invite\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/email-templates": {
      "get": {
        "summary": "List company email templates",
        "description": "Retrieve all custom email templates at the company level. Company templates serve as defaults for all workspaces that don't have workspace-specific templates.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Company email templates retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyEmailTemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listCompanyEmailTemplates",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.listCompanyEmailTemplates();\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/email-templates/{email_type}": {
      "put": {
        "summary": "Create or update company email template",
        "description": "Create or update a company-level email template for a specific type. Company templates are used as defaults for workspaces without workspace-specific templates.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "resend_notification",
                "signing_expired",
                "signing_cancelled",
                "signing_declined",
                "signing_declined_admin",
                "signing_completed",
                "signer_identity_changed"
              ]
            },
            "description": "Email template type"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "body"
                ],
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Email subject line"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Email body (HTML). Use {{signing_link}} placeholder for the signing URL."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Company email template updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Company email template created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompanyEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.updateCompanyEmailTemplate({\n    email_type: \"signing_invite\",\n    subject: \"subject\",\n    body: \"body\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete company email template",
        "description": "Delete a company-level email template. Workspaces will fall back to the built-in default template for this type.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "resend_notification",
                "signing_expired",
                "signing_cancelled",
                "signing_declined",
                "signing_declined_admin",
                "signing_completed",
                "signer_identity_changed"
              ]
            },
            "description": "Email template type"
          }
        ],
        "responses": {
          "200": {
            "description": "Company email template deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateDeleteResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteCompanyEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.deleteCompanyEmailTemplate({\n    email_type: \"signing_invite\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/signer-terms": {
      "get": {
        "summary": "List company signer terms",
        "description": "Retrieve all company-level signer terms. Company signer terms serve as defaults for workspaces without workspace-specific signer terms.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Company signer terms retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listCompanySignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.listCompanySignerTerms();\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/signer-terms/{language}": {
      "put": {
        "summary": "Create or update company signer terms",
        "description": "Create or update company-level signer terms for a specific language. The submitted statement is sanitized before storage.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb",
                "ca"
              ]
            },
            "description": "Language code"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "statement_text"
                ],
                "properties": {
                  "statement_text": {
                    "type": "string",
                    "description": "Signer consent statement as HTML. Sanitized before storage."
                  },
                  "terms_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Optional external terms link; `null`, an empty string or an omitted key stores no link."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Company signer terms updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsUpdateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompanySignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.updateCompanySignerTerms({\n    language: \"en\",\n    statement_text: \"statement_text\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete company signer terms",
        "description": "Delete company-level signer terms for a specific language.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb",
                "ca"
              ]
            },
            "description": "Language code"
          }
        ],
        "responses": {
          "200": {
            "description": "Company signer terms deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsDeleteResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteCompanySignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.deleteCompanySignerTerms({\n    language: \"en\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/signer-terms": {
      "get": {
        "summary": "List workspace signer terms",
        "description": "Retrieve all custom signer terms for a workspace",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace signer terms retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaceSignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.listWorkspaceSignerTerms({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/signer-terms/{language}": {
      "put": {
        "summary": "Create or update workspace signer terms",
        "description": "Create or update workspace-level signer terms for a specific language. The submitted statement is sanitized before storage.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb",
                "ca"
              ]
            },
            "description": "Language code"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "statement_text"
                ],
                "properties": {
                  "statement_text": {
                    "type": "string",
                    "description": "Signer consent statement as HTML. Sanitized before storage."
                  },
                  "terms_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Optional external terms link; `null`, an empty string or an omitted key stores no link."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Workspace signer terms updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsUpdateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspaceSignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.updateWorkspaceSignerTerms({\n    workspace_id: \"workspace_id\",\n    language: \"en\",\n    statement_text: \"statement_text\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete workspace signer terms",
        "description": "Delete workspace-level signer terms for a specific language.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb",
                "ca"
              ]
            },
            "description": "Language code"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace signer terms deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsDeleteResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWorkspaceSignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.deleteWorkspaceSignerTerms({\n    workspace_id: \"workspace_id\",\n    language: \"en\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/email-templates/defaults/{language}": {
      "get": {
        "summary": "Get default email templates",
        "description": "Retrieve the built-in default email templates for a specific language. These are the templates used when no custom company or workspace templates are configured.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb",
                "ca"
              ]
            },
            "description": "Language code"
          }
        ],
        "responses": {
          "200": {
            "description": "Default templates retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateDefaultsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getEmailTemplateDefaults",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.getEmailTemplateDefaults({\n    language: \"en\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/email-templates/placeholders": {
      "get": {
        "summary": "Get email template placeholders",
        "description": "Retrieve the list of available placeholders that can be used in email templates. Placeholders are replaced with actual values when emails are sent.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Placeholders retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplatePlaceholdersResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listEmailTemplatePlaceholders",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.listEmailTemplatePlaceholders();\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/settings": {
      "get": {
        "summary": "Get workspace settings",
        "description": "Retrieve workspace settings",
        "tags": [
          "Workspace Settings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace settings retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceSettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspaceSettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaceSettings.getWorkspaceSettings({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Update workspace settings",
        "description": "Update workspace settings",
        "tags": [
          "Workspace Settings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "signing_request_email_header": {
                    "type": "string"
                  },
                  "signing_request_email_body": {
                    "type": "string"
                  },
                  "team_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb",
                      "ca"
                    ],
                    "description": "Workspace language for email templates"
                  },
                  "show_credit_cost_in_editor": {
                    "type": "boolean",
                    "description": "Whether to display credit cost in embedded editors"
                  },
                  "require_otp_verification": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Whether signers must verify their email via OTP; `null` removes the workspace setting and inherits the company setting."
                  },
                  "require_terms_acceptance": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Whether signers must accept terms before signing; `null` removes the workspace setting and inherits the company-level setting."
                  },
                  "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."
                  },
                  "show_signature_frame": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Whether to render signature frames in completed PDFs; `null` inherits the company setting."
                  },
                  "color_primary": {
                    "type": "string",
                    "nullable": true,
                    "description": "Primary color override (#rrggbb hex). Null to inherit from company."
                  },
                  "color_primary_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Primary foreground color override. Null to inherit from company."
                  },
                  "color_background": {
                    "type": "string",
                    "nullable": true,
                    "description": "Background color override. Null to inherit from company."
                  },
                  "color_foreground": {
                    "type": "string",
                    "nullable": true,
                    "description": "Foreground/text color override. Null to inherit from company."
                  },
                  "color_card": {
                    "type": "string",
                    "nullable": true,
                    "description": "Card background color override. Null to inherit from company."
                  },
                  "color_border": {
                    "type": "string",
                    "nullable": true,
                    "description": "Border color override. Null to inherit from company."
                  },
                  "color_accent": {
                    "type": "string",
                    "nullable": true,
                    "description": "Editor chrome accent color. Null to inherit from company."
                  },
                  "color_accent_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Foreground color on accent surfaces. Null to inherit from company."
                  },
                  "color_canvas": {
                    "type": "string",
                    "nullable": true,
                    "description": "Editor document-canvas surround color. Null to inherit from company."
                  },
                  "color_muted": {
                    "type": "string",
                    "nullable": true,
                    "description": "Muted surface color. Null to inherit from company."
                  },
                  "color_muted_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Muted text color. Null to inherit from company."
                  },
                  "email_local_part": {
                    "type": "string",
                    "nullable": true,
                    "description": "The local-part (before the @) of the sender email address. Null to inherit from company setting.",
                    "pattern": "^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "allow_presigning_download": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Allow signers to download the original document before signing; `null` removes the workspace setting and inherits the company setting."
                  },
                  "show_partial_watermark": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Show an IN PROGRESS watermark on partial PDF downloads when not all signers have completed; `null` inherits the company-level 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."
                  },
                  "allow_decline": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Show the Decline to Sign button to every participant, signers and approvers alike, and accept a decline. null inherits the company-level setting."
                  },
                  "show_save_for_later": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Show the Save & Finish Later button on the signing page. null inherits the company-level setting."
                  },
                  "signing_button_label_overrides": {
                    "type": "object",
                    "nullable": true,
                    "description": "Per-language custom button labels for the signing view. Keys are language codes (en, de, etc.); values are objects mapping translation keys to custom text. Null to use defaults.",
                    "additionalProperties": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "completion_title": {
                    "type": "string",
                    "nullable": true,
                    "description": "Heading shown on the completion page after signing. Null (or an empty string) clears the override and inherits from company.",
                    "maxLength": 200
                  },
                  "completion_message": {
                    "type": "string",
                    "nullable": true,
                    "description": "Body text shown on the completion page after signing. Null (or an empty string) clears the override and inherits from company.",
                    "maxLength": 1000
                  },
                  "completion_redirect_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "URL the signer is redirected to from the completion page. Must use https://. Null (or an empty string) clears the override and inherits from company.",
                    "pattern": "^https://",
                    "maxLength": 2000
                  },
                  "completion_redirect_delay": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves. Null clears the override and inherits from company.",
                    "minimum": 0,
                    "maximum": 30
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Workspace settings updated successfully",
            "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/WorkspaceSettings"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspaceSettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaceSettings.updateWorkspaceSettings({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains": {
      "get": {
        "summary": "List workspace domains",
        "description": "List all email domains configured for a specific workspace. These domains are used for sending signing request emails from this workspace.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace domains retrieved successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "123e4567-e89b-12d3-a456-426614174000",
                      "domain": "sales.acme.com",
                      "verification_status": 2,
                      "domain_status": 1,
                      "is_primary": true,
                      "date_created": "2024-01-15T10:30:00Z",
                      "date_changed": "2024-01-16T14:00:00Z"
                    }
                  ],
                  "workspace_id": "456e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaceDomains",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.listWorkspaceDomains({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Add workspace domain",
        "description": "Add a new email domain for a specific workspace. This initiates the domain verification process. After creation, you must:\n1. Add a TXT record to your DNS with the verification token\n2. Call POST /workspace/{workspace_id}/domains/{id}/verify-ownership to verify domain ownership\n3. Call POST /workspace/{workspace_id}/domains/{id}/finalize to register with email provider\n4. Add the returned DNS records (SPF, DKIM, etc.)\n5. Call POST /workspace/{workspace_id}/domains/{id}/verify-dns to complete verification",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "Domain name to add (e.g., 'example.com'). Must be a valid domain format.",
                    "example": "sales.acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domain created successfully. Add the verification TXT record to your DNS.",
            "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/DomainCreateResponse"
                },
                "example": {
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 0,
                    "domain_status": 0,
                    "is_primary": false,
                    "verification_token": "firma-verify=abc123xyz",
                    "date_created": "2024-01-15T10:30:00Z",
                    "date_changed": "2024-01-15T10:30:00Z"
                  },
                  "verification_instructions": {
                    "record_type": "TXT",
                    "record_name": "_firma-verification.sales.acme.com",
                    "record_value": "firma-verify=abc123xyz",
                    "next_step": "Add this TXT record to your DNS, then call POST /workspace/{workspace_id}/domains/{id}/verify-ownership"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid domain format or domain already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidDomain": {
                    "value": {
                      "error": "Invalid domain format",
                      "message": "Please provide a valid domain name (e.g., example.com)"
                    }
                  },
                  "domainExists": {
                    "value": {
                      "error": "Domain already exists",
                      "message": "This domain is already configured for this workspace"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.createWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    domain: \"sales.acme.com\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}": {
      "get": {
        "summary": "Get workspace domain",
        "description": "Retrieve details of a specific domain in a workspace including verification status and DNS records",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.getWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete workspace domain",
        "description": "Remove a domain from the workspace. If the domain is the primary or only domain, sending reverts to the company or default sender.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainDeleteResponse"
                },
                "example": {
                  "message": "Domain deleted successfully",
                  "domain_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.deleteWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/verify-ownership": {
      "post": {
        "summary": "Verify workspace domain ownership",
        "description": "Verify domain ownership by checking the TXT record. Call this after adding the verification TXT record to your DNS. DNS propagation may take up to 48 hours, but typically completes within minutes.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain ownership verified successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyOwnershipResponse"
                },
                "example": {
                  "message": "Domain ownership verified",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 1,
                    "domain_status": 0
                  },
                  "next_step": "Call POST /workspace/{workspace_id}/domains/{id}/finalize to complete domain setup and receive DNS records for email sending"
                }
              }
            }
          },
          "400": {
            "description": "Verification failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "recordNotFound": {
                    "value": {
                      "error": "Verification failed",
                      "message": "TXT record not found. Please ensure the record is added correctly and DNS has propagated.",
                      "details": {
                        "expected_record": "_firma-verification.sales.acme.com",
                        "expected_value": "firma-verify=abc123xyz"
                      }
                    }
                  },
                  "alreadyVerified": {
                    "value": {
                      "error": "Already verified",
                      "message": "Domain ownership has already been verified"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyWorkspaceDomainOwnership",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyWorkspaceDomainOwnership({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/finalize": {
      "post": {
        "summary": "Finalize workspace domain setup",
        "description": "Finalize domain setup by registering with the email provider. This returns the DNS records (SPF, DKIM, DMARC) that must be added to enable email sending. Can only be called after domain ownership is verified.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain finalized successfully. Add the returned DNS records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainFinalizeResponse"
                },
                "example": {
                  "message": "Domain finalized. Add the following DNS records to enable email sending.",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 2,
                    "domain_status": 0
                  },
                  "dns_records": [
                    {
                      "type": "TXT",
                      "name": "@",
                      "value": "v=spf1 include:amazonses.com ~all",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "CNAME",
                      "name": "resend._domainkey",
                      "value": "resend._domainkey.amazonses.com",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "TXT",
                      "name": "_dmarc",
                      "value": "v=DMARC1; p=none;",
                      "ttl": "Auto",
                      "status": "pending"
                    }
                  ],
                  "next_step": "Add these DNS records, then call POST /workspace/{workspace_id}/domains/{id}/verify-dns to complete verification"
                }
              }
            }
          },
          "400": {
            "description": "Cannot finalize",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "notVerified": {
                    "value": {
                      "error": "Ownership not verified",
                      "message": "Please verify domain ownership first by calling POST /workspace/{workspace_id}/domains/{id}/verify-ownership"
                    }
                  },
                  "alreadyFinalized": {
                    "value": {
                      "error": "Already finalized",
                      "message": "Domain has already been finalized"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "finalizeWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.finalizeWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/verify-dns": {
      "post": {
        "summary": "Verify workspace domain DNS records",
        "description": "Verify that all required DNS records (SPF, DKIM, DMARC) are properly configured. Call this after adding all DNS records from the finalize step. Once verified, the domain is ready for sending emails.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "DNS verification result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyDnsResponse"
                },
                "examples": {
                  "verified": {
                    "summary": "All records verified",
                    "value": {
                      "verified": true,
                      "message": "Domain is fully verified and ready to send emails",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "sales.acme.com",
                        "verification_status": 2,
                        "domain_status": 1,
                        "is_primary": true
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "verified"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "verified"
                        }
                      ]
                    }
                  },
                  "pending": {
                    "summary": "Some records pending",
                    "value": {
                      "verified": false,
                      "message": "Some DNS records are not yet verified. Please check your DNS configuration.",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "sales.acme.com",
                        "verification_status": 2,
                        "domain_status": 0
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "pending"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "pending"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Domain not finalized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not finalized",
                  "message": "Please finalize domain setup first by calling POST /workspace/{workspace_id}/domains/{id}/finalize"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyWorkspaceDomainDns",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyWorkspaceDomainDns({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/set-primary": {
      "post": {
        "summary": "Set primary workspace domain",
        "description": "Set a domain as the primary sending domain for the workspace. Only fully verified domains (domain_status=1) can be set as primary.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Domain ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Primary domain updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainSetPrimaryResponse"
                },
                "example": {
                  "message": "Primary domain updated",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 2,
                    "domain_status": 1,
                    "is_primary": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Domain not verified",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not verified",
                  "message": "Only fully verified domains can be set as primary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "setWorkspacePrimaryDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.setWorkspacePrimaryDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/custom-fields": {
      "get": {
        "summary": "List workspace custom fields",
        "description": "Get all custom field definitions for a workspace",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Custom fields retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "listWorkspaceCustomFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.listWorkspaceCustomFields({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Create workspace custom field",
        "description": "Create a new custom field definition for a workspace",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "field_label"
                ],
                "properties": {
                  "field_label": {
                    "type": "string",
                    "description": "Display label (1-100 characters)",
                    "maxLength": 100
                  },
                  "field_name": {
                    "type": "string",
                    "description": "Optional machine-readable name (auto-generated from label if not provided)",
                    "maxLength": 50
                  },
                  "is_preset": {
                    "type": "boolean",
                    "description": "If true, field has a preset value for all users",
                    "default": false
                  },
                  "preset_value": {
                    "type": "string",
                    "description": "Preset value (max 500 characters, only used when is_preset=true)",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Custom field created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "409": {
            "description": "Conflict - A custom field with this name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "createWorkspaceCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.createWorkspaceCustomField({\n    workspace_id: \"workspace_id\",\n    field_label: \"field_label\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/custom-fields/{field_id}": {
      "put": {
        "summary": "Update workspace custom field",
        "description": "Update an existing custom field definition",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "field_label": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "is_preset": {
                    "type": "boolean"
                  },
                  "preset_value": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Custom field updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict - A custom field with this name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "updateWorkspaceCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.updateWorkspaceCustomField({\n    workspace_id: \"workspace_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Delete workspace custom field",
        "description": "Soft-delete a custom field definition",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Custom field deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "deleteWorkspaceCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.deleteWorkspaceCustomField({\n    workspace_id: \"workspace_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{template_id}/custom-fields": {
      "get": {
        "summary": "List template custom fields",
        "description": "Get all custom field definitions for a template",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Custom fields retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "listTemplateCustomFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.listTemplateCustomFields({\n    template_id: \"template_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Create template custom field",
        "description": "Create a new custom field definition for a template",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "field_label"
                ],
                "properties": {
                  "field_label": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "field_name": {
                    "type": "string",
                    "maxLength": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Custom field created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict - A custom field with this name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "createTemplateCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.createTemplateCustomField({\n    template_id: \"template_id\",\n    field_label: \"field_label\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{template_id}/custom-fields/{field_id}": {
      "delete": {
        "summary": "Delete template custom field",
        "description": "Soft-delete a custom field definition from a template",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Custom field deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "deleteTemplateCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.deleteTemplateCustomField({\n    template_id: \"template_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{request_id}/custom-fields": {
      "get": {
        "summary": "List signing request custom fields",
        "description": "Get all custom field definitions for a signing request",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Custom fields retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "listSigningRequestCustomFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.listSigningRequestCustomFields({\n    request_id: \"request_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Create signing request custom field",
        "description": "Create a new custom field definition for a signing request",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "field_label"
                ],
                "properties": {
                  "field_label": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "field_name": {
                    "type": "string",
                    "maxLength": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Custom field created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict - A custom field with this name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "createSigningRequestCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.createSigningRequestCustomField({\n    request_id: \"request_id\",\n    field_label: \"field_label\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{request_id}/custom-fields/{field_id}": {
      "delete": {
        "summary": "Delete signing request custom field",
        "description": "Soft-delete a custom field definition from a signing request",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Custom field deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "deleteSigningRequestCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.deleteSigningRequestCustomField({\n    request_id: \"request_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/webhooks/rotate-secret": {
      "post": {
        "summary": "Rotate workspace webhook secret",
        "description": "Generates a new webhook signing secret for the workspace. The old secret remains valid for 7 days.",
        "operationId": "rotateWorkspaceWebhookSecret",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secret rotated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateSecretResponse"
                }
              }
            }
          },
          "429": {
            "description": "Cooldown active — secret was recently rotated"
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.rotateWorkspaceWebhookSecret({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/webhooks/secret-status": {
      "get": {
        "summary": "Get workspace webhook secret status",
        "description": "Returns the status of the workspace webhook secret including creation date, rotation date, and grace period status.",
        "operationId": "getWorkspaceWebhookSecretStatus",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Workspace ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secret status retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretStatusResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.getWorkspaceWebhookSecretStatus({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/download": {
      "get": {
        "summary": "Download Signing Request Document",
        "description": "Retrieve a download URL for a signing request's signed document. For completed signing requests, returns the final signed PDF. For in-progress signing requests where partial download is enabled, returns a URL to the partially-signed document generated at the time of the last signer's completion.\n\n**Partial downloads:** Partial downloads are only available when the signing request has `allow_partial_download` enabled in settings. If the document has not been partially generated yet, a `503` is returned — retry after the `Retry-After` interval.\n\n**URL expiry:** The `download_url` is a pre-signed URL that expires. The expiry timestamp is provided in `expires_at`.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download URL retrieved successfully.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 200 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestDownloadResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "Signing request not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found"
                }
              }
            }
          },
          "409": {
            "description": "Signing request has not been sent yet. Download is only available after the request has been sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "no_document_available",
                  "message": "Signing request has not been sent yet"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "503": {
            "description": "Document generation is in progress. Retry after the indicated interval.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "generation_timeout": {
                    "summary": "Document generation timed out",
                    "value": {
                      "error": "generation_timeout"
                    }
                  },
                  "stale_at_publication": {
                    "summary": "Document was stale at publication time",
                    "value": {
                      "error": "stale_at_publication"
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "downloadSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.downloadSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/signature": {
      "get": {
        "operationId": "retrieveSignerSignature",
        "summary": "Retrieve Signer Signature Image",
        "description": "Retrieve a signer's adopted signature as a base64 PNG data URI, separate from the signed PDF. A signer adopts one signature applied to all their signature fields, so no field_id is needed. Drawn signatures return the captured image; typed signatures are rendered to PNG server-side. The `image` is a `data:image/png;base64,...` URI usable directly in an `<img src>`. By default a signer-ID frame is overlaid (`include_frame=false` to omit). Every successful retrieval is audit-logged. Rate limited to 60/min. Legal validity rests on the sealed PDF and completion certificate, not this image.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "Signer (recipient) ID — the recipient_id from GET /fields",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Overlay the signer-ID frame on the image (default true). Set to false for the bare mark.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The signer's mark as a base64 PNG data URI.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "signature",
                        "initials",
                        "stamp"
                      ]
                    },
                    "format": {
                      "type": "string",
                      "example": "png"
                    },
                    "framed": {
                      "type": "boolean",
                      "description": "Whether the signer-ID frame was overlaid."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG as a data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Signing request/signer/field not found or not in your workspace (NOT_FOUND), or no mark captured (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min for signature retrieval).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Rendering failed (RENDER_FAILED) or the required access-audit write failed (AUDIT_WRITE_FAILED); no image is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerSignature({\n    id: \"id\",\n    signer_id: \"signer_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/initials": {
      "get": {
        "operationId": "retrieveSignerInitials",
        "summary": "Retrieve Signer Initials Image",
        "description": "Retrieve a signer's adopted initials as a base64 PNG data URI. One initials mark per signer (no field_id). Same response shape, framing, audit, and rate limit as the signature endpoint.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "Signer (recipient) ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Overlay the signer-ID frame on the image (default true). Set to false for the bare mark.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The signer's mark as a base64 PNG data URI.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "signature",
                        "initials",
                        "stamp"
                      ]
                    },
                    "format": {
                      "type": "string",
                      "example": "png"
                    },
                    "framed": {
                      "type": "boolean",
                      "description": "Whether the signer-ID frame was overlaid."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG as a data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Signing request/signer/field not found or not in your workspace (NOT_FOUND), or no mark captured (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min for signature retrieval).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Rendering failed (RENDER_FAILED) or the required access-audit write failed (AUDIT_WRITE_FAILED); no image is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerInitials({\n    id: \"id\",\n    signer_id: \"signer_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/stamps/{field_id}": {
      "get": {
        "operationId": "retrieveSignerStamp",
        "summary": "Retrieve Signer Stamp Image",
        "description": "Retrieve a signer's stamp for a specific stamp field as a base64 PNG data URI. Stamps are per-field, so `field_id` is required (obtain it from GET /signing-requests/{id}/fields, filtering type=stamp). Same framing, audit, and 60/min limit.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "Signer (recipient) ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "Stamp field ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Overlay the signer-ID frame on the image (default true). Set to false for the bare mark.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The signer's mark as a base64 PNG data URI.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "signature",
                        "initials",
                        "stamp"
                      ]
                    },
                    "format": {
                      "type": "string",
                      "example": "png"
                    },
                    "framed": {
                      "type": "boolean",
                      "description": "Whether the signer-ID frame was overlaid."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG as a data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Field is not the expected type (INVALID_FIELD_TYPE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Signing request/signer/field not found or not in your workspace (NOT_FOUND), or no mark captured (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min for signature retrieval).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Rendering failed (RENDER_FAILED) or the required access-audit write failed (AUDIT_WRITE_FAILED); no image is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerStamp({\n    id: \"id\",\n    signer_id: \"signer_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/files/{field_id}": {
      "get": {
        "operationId": "retrieveSignerFile",
        "summary": "Retrieve Signer-Uploaded File",
        "description": "Retrieve a file a signer uploaded to a file field. Returns a short-lived (300s) pre-signed download URL, not the bytes. `field_id` is required (from GET /signing-requests/{id}/fields, filtering type=file). Every retrieval is audit-logged; 60/min limit. Download promptly server-side before the URL expires.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Signing request ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "Signer (recipient) ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "File field ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A short-lived pre-signed URL for the signer-uploaded file.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "example": "file"
                    },
                    "file_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "file_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "file_size": {
                      "type": "integer",
                      "nullable": true
                    },
                    "url": {
                      "type": "string",
                      "description": "Pre-signed download URL."
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 300,
                      "description": "Seconds until the URL expires."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Field is not a file field (INVALID_FIELD_TYPE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found / not in your workspace (NOT_FOUND) or no file uploaded (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The signed-URL generation failed (INTERNAL_ERROR, answered by serverErrorResponse) or the required access-audit write failed (AUDIT_WRITE_FAILED); no URL is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerFile({\n    id: \"id\",\n    signer_id: \"signer_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/logo": {
      "post": {
        "tags": [
          "Company"
        ],
        "summary": "Upload Company Logo",
        "description": "Upload a logo image for the company. Accepts PNG or JPEG, max 2MB. Replaces any existing logo.",
        "operationId": "uploadCompanyLogo",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Logo image file (PNG or JPEG, max 2MB)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file (wrong format, too large, or missing)"
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import * as fs from \"fs\";\nimport { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.uploadCompanyLogo({\n    file: fs.createReadStream(\"/path/to/your/file\")\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Company"
        ],
        "summary": "Remove Company Logo",
        "description": "Remove the company logo. Certificates will use the Firma default logo.",
        "operationId": "deleteCompanyLogo",
        "responses": {
          "200": {
            "description": "Logo removed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoDeleteResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.deleteCompanyLogo();\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/logo": {
      "post": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Upload Workspace Logo",
        "description": "Upload a logo for a specific workspace. Overrides the company logo on certificates and emails for this workspace. Accepts PNG or JPEG, max 2MB.",
        "operationId": "uploadWorkspaceLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Logo image file (PNG or JPEG, max 2MB)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file (wrong format, too large, or missing)"
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import * as fs from \"fs\";\nimport { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.uploadWorkspaceLogo({\n    file: fs.createReadStream(\"/path/to/your/file\"),\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Remove Workspace Logo",
        "description": "Remove the workspace logo. Certificates will fall back to the company logo, or the Firma default.",
        "operationId": "deleteWorkspaceLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Workspace ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Logo removed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoDeleteResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.deleteWorkspaceLogo({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/documents": {
      "post": {
        "summary": "Upload a document",
        "description": "Request a presigned upload URL for a document. Upload the file directly to the returned URL, then pass the document_id when creating a signing request. Use this for documents larger than 5MB that exceed the inline base64 request size limit.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "operationId": "uploadDocument",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_name",
                  "file_size",
                  "content_type"
                ],
                "properties": {
                  "file_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Name of the document file",
                    "example": "contract.pdf"
                  },
                  "file_size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 52428800,
                    "description": "File size in bytes. Maximum 50MB (52,428,800 bytes).",
                    "example": 15000000
                  },
                  "content_type": {
                    "type": "string",
                    "enum": [
                      "application/pdf",
                      "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
                    ],
                    "description": "MIME type of the document",
                    "example": "application/pdf"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload URL created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Document ID to pass in the signing request"
                    },
                    "upload_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "Presigned URL to PUT the document file to. Send the raw file bytes with Content-Type matching the requested content_type."
                    },
                    "upload_token": {
                      "type": "string",
                      "description": "Upload authentication token (included in the upload_url)"
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Seconds until the upload URL expires",
                      "example": 3600
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error (invalid file_size, content_type, etc.)"
          },
          "401": {
            "description": "Invalid or missing API key"
          },
          "413": {
            "description": "REQUEST_TOO_LARGE when the request payload exceeds 6,291,456 bytes. Upload large files with POST /documents, then pass document_id / document_ids instead of inline base64.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestTooLargeError"
                },
                "example": {
                  "error": "Request exceeds the 6,291,456-byte payload limit. Upload large files with POST /documents and pass document_id / document_ids instead of inline base64.",
                  "code": "REQUEST_TOO_LARGE"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.uploadDocument({\n    file_name: \"contract.pdf\",\n    file_size: 15000000,\n    content_type: \"application/pdf\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/copy": {
      "post": {
        "summary": "Copy template to another workspace",
        "description": "Deep-copies a template (including fields, recipients, CC, reminders, custom field definitions, and the PDF document) to a target workspace within the same company. Requires a company-level (protected) API key. Multi-document (available to every company): the copy of a template with more than one document is a template with ONE document, the merged document of the source; its content and the absolute page numbers of its fields are kept, the per-document labels and positions are not carried. While multi-document editing is suspended, copying a template on the multi-document read-only path answers `409 MULTI_DOCUMENT_READ_ONLY`; other templates use the single-document path.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID to copy"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "workspace_id"
                ],
                "properties": {
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Target workspace ID to copy the template into"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Name for the copied template (defaults to original name with \" (copy)\" suffix)"
                  }
                }
              },
              "example": {
                "workspace_id": "550e8400-e29b-41d4-a716-446655440000",
                "name": "My Template Copy"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template copied successfully",
            "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/TemplateCopyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing workspace_id or invalid name",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "description": "Protected API key required, or access denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protected_key_required": {
                    "value": {
                      "error": "This operation requires a protected workspace API key",
                      "code": "PROTECTED_KEY_REQUIRED"
                    }
                  },
                  "access_denied": {
                    "value": {
                      "error": "Template not found or access denied",
                      "code": "ACCESS_DENIED"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Template or target workspace not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "x-participant-order-contract": {
          "membership": "The copy preserves the source template's participant order. Seal participants whose seal is not in scope for the target workspace are dropped, along with their fields. The remaining participants are compacted to a contiguous [1..n] order. PARTICIPANTS_CHANGED is a concurrent-write signal: another write to the same participant set committed while this call was running. No route compares against a version you loaded; re-read and retry.",
          "errors": [
            "INVALID_SIGNING_ORDER",
            "PARTICIPANTS_CHANGED"
          ]
        }
      }
    },
    "/seals": {
      "get": {
        "summary": "List organization seals",
        "description": "List organization seal heads for the company. Returns active (non-revoked, non-deleted) seal heads by default. Pass include_revoked=true to include revoked heads.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "listOrganizationSeals",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "include_revoked",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Include revoked seal heads in the response"
          },
          {
            "name": "workspace_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter seals by workspace scope"
          }
        ],
        "responses": {
          "200": {
            "description": "Seal list retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "seals": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OrganizationSeal"
                      }
                    }
                  },
                  "required": [
                    "seals"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      },
      "post": {
        "summary": "Create an organization seal",
        "description": "Create a new organization seal with an uploaded, typed, or drawn image. Company-scope seals require a protected API key.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "createOrganizationSeal",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrganizationSealCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Seal created successfully",
            "headers": {
              "X-Firma-Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "Present when the operation is available but will be moved to the primary API host in a future release. The value describes the timeline."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationSeal"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "409": {
            "description": "Conflict. Possible codes: SEAL_ALREADY_REVOKED, SEAL_ORDER_COLLISION, SEAL_ERASE_NOT_ELIGIBLE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "$ref": "#/components/schemas/SealErrorCode"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "503": {
            "description": "Seal image processing is unavailable on this host (SEAL_CREATION_DISABLED_EDGE). Retry against the primary API host.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/seals/{id}": {
      "get": {
        "summary": "Get an organization seal",
        "description": "Retrieve a single organization seal by ID.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "getOrganizationSeal",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Seal retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationSeal"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      },
      "patch": {
        "summary": "Update an organization seal",
        "description": "Update a seal's name, display name, image, or default status. Any image-class change (image, typed, display_name, signatory_title, statement) creates a new version (replace) and requires a `statement` with accepted true, version 1, language, text equal to the seal's `statement_text` exactly, signatory_name, and optional signatory_title; otherwise the request fails with 400 `SEAL_STATEMENT_REQUIRED`. The new version records this request's acceptance: `signatory_name` and `signatory_title_attested` are the signatory sent, and `attested_at` is the replacement time. Requests already sent keep the version pinned when they were sent; requests sent after the replacement use the new version, and their certificates show the new signatory. The statement text never changes. Company-scope seals require a protected API key for mutations.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "updateOrganizationSeal",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 120,
                    "description": "New internal name"
                  },
                  "display_name": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "New display name (triggers image re-render)"
                  },
                  "signatory_title": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true,
                    "description": "New signatory title"
                  },
                  "image": {
                    "type": "string",
                    "description": "New base64 PNG data URI"
                  },
                  "typed": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      },
                      "style": {
                        "type": "string"
                      }
                    }
                  },
                  "statement": {
                    "$ref": "#/components/schemas/SealStatement"
                  },
                  "is_default": {
                    "type": "boolean",
                    "description": "Set as default seal for its scope"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seal updated successfully",
            "headers": {
              "X-Firma-Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "Present when the operation is available but will be moved to the primary API host in a future release. The value describes the timeline."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationSeal"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict. Possible codes: SEAL_ALREADY_REVOKED, SEAL_ORDER_COLLISION, SEAL_ERASE_NOT_ELIGIBLE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "$ref": "#/components/schemas/SealErrorCode"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "503": {
            "description": "Seal image processing is unavailable on this host (SEAL_CREATION_DISABLED_EDGE). Retry against the primary API host.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Revoke an organization seal",
        "description": "Revoke (soft-delete) a seal. Optionally stop pending signing requests that reference it. Company-scope seals require a protected API key.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "revokeOrganizationSeal",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal ID"
          },
          {
            "name": "stop_pending",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Cancel pending signing requests referencing this seal"
          }
        ],
        "responses": {
          "200": {
            "description": "Seal revoked successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "lineage_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Shared across versions of the same seal"
                    },
                    "version": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "companies_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "companies_workspaces_id": {
                      "type": "string",
                      "format": "uuid",
                      "nullable": true,
                      "description": "Null for company-scope seals"
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 120
                    },
                    "display_name": {
                      "type": "string",
                      "maxLength": 200
                    },
                    "signatory_title": {
                      "type": "string",
                      "maxLength": 200,
                      "nullable": true
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "uploaded",
                        "typed",
                        "drawn"
                      ]
                    },
                    "is_default": {
                      "type": "integer",
                      "enum": [
                        0,
                        1
                      ],
                      "description": "1 if this is the default seal for its scope"
                    },
                    "statement_language": {
                      "type": "string"
                    },
                    "statement_version": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "signatory_name": {
                      "type": "string",
                      "maxLength": 200
                    },
                    "signatory_title_attested": {
                      "type": "string",
                      "maxLength": 200,
                      "nullable": true
                    },
                    "attested_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "revoked_on": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "deleted": {
                      "type": "integer",
                      "enum": [
                        0,
                        1
                      ]
                    },
                    "in_flight_requests": {
                      "type": "integer",
                      "description": "Number of in-flight signing requests that referenced this seal"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict. Possible codes: SEAL_ALREADY_REVOKED, SEAL_ORDER_COLLISION, SEAL_ERASE_NOT_ELIGIBLE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "$ref": "#/components/schemas/SealErrorCode"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      }
    },
    "/seals/{id}/image": {
      "get": {
        "summary": "Get seal image",
        "description": "Retrieve the seal's rendered PNG image as a base64 data URI. Rate limited to 60/min. Each retrieval is audit-logged.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "getOrganizationSealImage",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Seal image retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SealImage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      }
    },
    "/seals/{id}/erase": {
      "delete": {
        "summary": "Erase a seal lineage",
        "description": "Permanently erase all versions of a seal lineage. The seal must be revoked first. This is irreversible and removes all image data. Requires a protected API key.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "eraseOrganizationSealLineage",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal ID (any version in the lineage)"
          }
        ],
        "responses": {
          "200": {
            "description": "Seal lineage erased successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "lineage_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "versions_erased": {
                      "type": "integer",
                      "description": "Number of versions erased"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflict. Possible codes: SEAL_ALREADY_REVOKED, SEAL_ORDER_COLLISION, SEAL_ERASE_NOT_ELIGIBLE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "$ref": "#/components/schemas/SealErrorCode"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      }
    },
    "/seals/{id}/applications": {
      "get": {
        "summary": "List seal applications",
        "description": "List signing requests where this seal has been applied, is pending, or was paused.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "listOrganizationSealApplications",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal ID"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Maximum results per page"
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Pagination cursor from a previous response"
          }
        ],
        "responses": {
          "200": {
            "description": "Seal applications retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "applications": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SealApplication"
                      }
                    },
                    "cursor": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page, null if no more results"
                    }
                  },
                  "required": [
                    "applications"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      }
    },
    "/seals/{id}/access-log": {
      "get": {
        "summary": "List seal access log",
        "description": "Retrieve the access log for a seal's lineage, including creation, replacement, revocation, rename, and image read events.",
        "tags": [
          "Organization Seals"
        ],
        "operationId": "listOrganizationSealAccessLog",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal ID"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Maximum results per page"
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Pagination cursor from a previous response"
          }
        ],
        "responses": {
          "200": {
            "description": "Access log retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SealAccessLogEntry"
                      }
                    },
                    "cursor": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page, null if no more results"
                    }
                  },
                  "required": [
                    "entries"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      }
    },
    "/signing-requests/{id}/seal-participants/{participant_id}": {
      "delete": {
        "summary": "Remove a seal participant from an unsent signing request",
        "description": "Remove a seal participant and the fields it owns from a signing request that has not been sent yet. After send, a seal participant can only be swapped (while paused) or the request cancelled.",
        "tags": [
          "Signing Requests"
        ],
        "operationId": "deleteSealParticipant",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          },
          {
            "name": "participant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Seal participant ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Seal participant removed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "deleted"
                  ],
                  "properties": {
                    "deleted": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "The request was sent (`SEAL_MUTATION_NOT_ALLOWED`), cancelled (`ALREADY_CANCELLED`) or finished (`ALREADY_FINISHED`), or the participant set was changed by another write while this call ran (`PARTICIPANTS_CHANGED`: a concurrent-write signal, not a comparison with a version you loaded; re-read the request and retry), or an applied participant prevents compaction (`SIGNING_ORDER_LOCKED_APPLIED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "sent": {
                    "value": {
                      "error": "Seal participants cannot be removed after the request is sent",
                      "code": "SEAL_MUTATION_NOT_ALLOWED"
                    }
                  },
                  "applied": {
                    "value": {
                      "error": "An applied organization seal cannot be moved.",
                      "code": "SIGNING_ORDER_LOCKED_APPLIED"
                    }
                  },
                  "changed": {
                    "value": {
                      "error": "The participants changed. Reload and try again.",
                      "code": "PARTICIPANTS_CHANGED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "x-participant-order-contract": {
          "membership": "Signer and Approver recipients plus organization seal participants share one contiguous 1-based order space. CC recipients use a separate sequence and never consume a participant position.",
          "patch": "On an unsent document, order must be in [1..n] for a move and [1..n+1] for a create. A move is shift-insert: every participant between the old and new positions is renumbered. A create with omitted order appends. Explicit order 0 is invalid.",
          "lockedStates": "A sent request accepts no seal participant removal and answers 409 SEAL_MUTATION_NOT_ALLOWED (a cancelled request answers ALREADY_CANCELLED and a finished one ALREADY_FINISHED). On an aborted-send request, an applied participant can narrow the reachable interval and an invalid move returns SIGNING_ORDER_LOCKED_APPLIED.",
          "create": "When no seal is present, tied recipient order values are resolved deterministically and compacted to [1..n]. A document-based create with seal participants rejects a non-contiguous space with INVALID_SIGNING_ORDER and two entries (recipients or seals) sharing an order with SEAL_ORDER_COLLISION. When use_signing_order is false, or any recipient omits order, participant orders follow array order; this fallback is a rule of request creation for requests without seal participants, and a document-based create with seal participants rejects a recipient without an order with INVALID_SIGNING_ORDER.",
          "sideEffects": "Retrying a create after a later field write fails creates a second participant, matching the existing non-idempotent create contract. PARTICIPANTS_CHANGED is a concurrent-write signal: another write to the same participant set committed while this call was running. No route compares against a version you loaded; re-read and retry.",
          "errors": [
            "INVALID_SIGNING_ORDER",
            "SEAL_MUTATION_NOT_ALLOWED",
            "SIGNING_ORDER_LOCKED_APPLIED",
            "PARTICIPANTS_CHANGED"
          ]
        }
      }
    },
    "/signing-requests/{id}/documents": {
      "post": {
        "summary": "Add a document to a signing request",
        "description": "Adds a document (a temporary upload from `POST /documents`) to the signing request's document set, at `position` or last. Documents at that position and after it move up by one. At most 20 documents and 100 MB per signing request. A sent, finished, cancelled or declined signing request answers `409 DOCUMENT_SET_LOCKED`.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document_id"
                ],
                "properties": {
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Temporary upload id from POST /documents (a PDF). Consumed once the document is added."
                  },
                  "position": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "1-based position of the new document; at most the current count + 1. Defaults to last."
                  },
                  "label": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 200,
                    "description": "Display name of the document (no control characters)."
                  },
                  "original_filename": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 255,
                    "description": "File name to record for the document (no control characters)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document added; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `VALIDATION_ERROR`, `DOCUMENT_UPLOAD_NOT_FOUND`, `MAX_DOCUMENTS_EXCEEDED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the signing request is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this signing request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_LOCKED`, `SEND_IN_PROGRESS`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "413": {
            "description": "DOCUMENT_SET_TOO_LARGE: the document set would exceed 104,857,600 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "addSigningRequestDocument"
      }
    },
    "/signing-requests/{id}/documents/order": {
      "put": {
        "summary": "Reorder a signing request's documents",
        "description": "Sets the order of the signing request's documents. `document_ids` must name every document of the signing request exactly once: a missing or repeated id answers `400 INVALID_DOCUMENT_ORDER`, an id that is not a document of this signing request `404 DOCUMENT_NOT_FOUND`. A sent, finished, cancelled or declined signing request answers `409 DOCUMENT_SET_LOCKED`.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document_ids"
                ],
                "properties": {
                  "document_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Every document id of the set (`documents[].document_id`), in the new order."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Documents reordered; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `VALIDATION_ERROR`, `INVALID_DOCUMENT_ORDER`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the signing request is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this signing request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_LOCKED`, `SEND_IN_PROGRESS`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "reorderSigningRequestDocuments"
      }
    },
    "/signing-requests/{id}/documents/{document_id}": {
      "delete": {
        "summary": "Remove a document from a signing request",
        "description": "Removes a document from the signing request. The last remaining document cannot be removed (`400 MIN_DOCUMENTS_REQUIRED`). A sent, finished, cancelled or declined signing request answers `409 DOCUMENT_SET_LOCKED`.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The document id (`documents[].document_id`)"
          }
        ],
        "responses": {
          "200": {
            "description": "Document removed; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `MIN_DOCUMENTS_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the signing request is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this signing request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_LOCKED`, `SEND_IN_PROGRESS`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "removeSigningRequestDocument"
      },
      "patch": {
        "summary": "Replace or rename a signing request document",
        "description": "Send exactly one of `document_id` (replace the document with a temporary upload from `POST /documents`: the same number of pages, every page the same size within 1 pt) or `label` (rename). Both, or neither, answers `400 VALIDATION_ERROR`. A document placed with anchor tags is replaced only when the anchors of the replacement resolve exactly as stored; otherwise `400 ANCHOR_MISMATCH`. A sent, finished, cancelled or declined signing request answers `409 DOCUMENT_SET_LOCKED`.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The document id (`documents[].document_id`)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Temporary upload id from POST /documents: the replacement PDF."
                  },
                  "label": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 200,
                    "description": "The new display name (null clears it)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document replaced or renamed; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `VALIDATION_ERROR`, `DOCUMENT_UPLOAD_NOT_FOUND`, `PAGE_COUNT_MISMATCH`, `DIMENSION_MISMATCH`, `ANCHOR_MISMATCH`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the signing request is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this signing request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_LOCKED`, `SEND_IN_PROGRESS`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "413": {
            "description": "DOCUMENT_SET_TOO_LARGE: the document set would exceed 104,857,600 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "updateSigningRequestDocument"
      }
    },
    "/signing-requests/{id}/documents/{document_id}/download": {
      "get": {
        "summary": "Download one document of a signing request",
        "description": "`type=original` (the default): a signed URL to the document as uploaded (`404 DOCUMENT_ORIGINAL_NOT_AVAILABLE` when it is no longer stored). `type=document`: a signed URL to the individually sealed document, available once the certificate is bound (`404 DOCUMENT_SIGNED_NOT_AVAILABLE` before). The URL is valid for 1 hour.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation remains available for parents on the multi-document read-only path; parents on the single-document path answer `404 NOT_FOUND`.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Signing request ID"
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The document id (`documents[].document_id`)"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "original",
                "document"
              ],
              "default": "original"
            },
            "description": "Which file to download"
          }
        ],
        "responses": {
          "200": {
            "description": "A signed download URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "download_url",
                    "expires_at"
                  ],
                  "properties": {
                    "download_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the signing request is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this signing request. DOCUMENT_SIGNED_NOT_AVAILABLE / DOCUMENT_ORIGINAL_NOT_AVAILABLE: see the operation description.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "downloadSigningRequestDocument"
      }
    },
    "/templates/{id}/documents": {
      "post": {
        "summary": "Add a document to a template",
        "description": "Adds a document (a temporary upload from `POST /documents`) to the template's document set, at `position` or last. Documents at that position and after it move up by one. At most 20 documents and 100 MB per template.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document_id"
                ],
                "properties": {
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Temporary upload id from POST /documents (a PDF). Consumed once the document is added."
                  },
                  "position": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "1-based position of the new document; at most the current count + 1. Defaults to last."
                  },
                  "label": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 200,
                    "description": "Display name of the document (no control characters)."
                  },
                  "original_filename": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 255,
                    "description": "File name to record for the document (no control characters)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document added; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `VALIDATION_ERROR`, `DOCUMENT_UPLOAD_NOT_FOUND`, `MAX_DOCUMENTS_EXCEEDED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the template is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "413": {
            "description": "DOCUMENT_SET_TOO_LARGE: the document set would exceed 104,857,600 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "addTemplateDocument"
      }
    },
    "/templates/{id}/documents/order": {
      "put": {
        "summary": "Reorder a template's documents",
        "description": "Sets the order of the template's documents. `document_ids` must name every document of the template exactly once: a missing or repeated id answers `400 INVALID_DOCUMENT_ORDER`, an id that is not a document of this template `404 DOCUMENT_NOT_FOUND`.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document_ids"
                ],
                "properties": {
                  "document_ids": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Every document id of the set (`documents[].document_id`), in the new order."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Documents reordered; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `VALIDATION_ERROR`, `INVALID_DOCUMENT_ORDER`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the template is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "reorderTemplateDocuments"
      }
    },
    "/templates/{id}/documents/{document_id}": {
      "delete": {
        "summary": "Remove a document from a template",
        "description": "Removes a document from the template. The last remaining document cannot be removed (`400 MIN_DOCUMENTS_REQUIRED`).\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID"
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The document id (`documents[].document_id`)"
          }
        ],
        "responses": {
          "200": {
            "description": "Document removed; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `MIN_DOCUMENTS_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the template is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "removeTemplateDocument"
      },
      "patch": {
        "summary": "Replace or rename a template document",
        "description": "Send exactly one of `document_id` (replace the document with a temporary upload from `POST /documents`: the same number of pages, every page the same size within 1 pt) or `label` (rename). Both, or neither, answers `400 VALIDATION_ERROR`.\n\n**Available to every company.** This operation is part of the multi-document contract (API 01.39.00). For a signing request or template the API key cannot see, it answers `404` with code `NOT_FOUND` (\"Endpoint not found\"), exactly as an unknown endpoint does. While multi-document editing is suspended, this operation returns `409 MULTI_DOCUMENT_READ_ONLY` for parents on the multi-document read-only path and `404 NOT_FOUND` for parents on the single-document path.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID"
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The document id (`documents[].document_id`)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Temporary upload id from POST /documents: the replacement PDF."
                  },
                  "label": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 200,
                    "description": "The new display name (null clears it)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document replaced or renamed; the full document set after the change",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSetMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: `VALIDATION_ERROR`, `DOCUMENT_UPLOAD_NOT_FOUND`, `PAGE_COUNT_MISMATCH`, `DIMENSION_MISMATCH`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "NOT_FOUND: the parent uses the single-document path while multi-document editing is suspended, or the template is absent, deleted or not visible to this API key (\"Endpoint not found\"). DOCUMENT_NOT_FOUND: no document with this id in this template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict: `MULTI_DOCUMENT_READ_ONLY`, `DOCUMENT_SET_VERSION_CONFLICT`, `DOCUMENT_SET_BUSY`, `DOCUMENT_SET_DISPATCH_STALE`, `DOCUMENT_CANDIDATE_EXPIRED`, `DOCUMENT_SET_INCONSISTENT`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "413": {
            "description": "DOCUMENT_SET_TOO_LARGE: the document set would exceed 104,857,600 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultiDocumentError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Internal error (code `INTERNAL`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "updateTemplateDocument"
      }
    }
  }
}
