Hi {{signer_name}},
Please sign using this link: {{signing_link}}
" } ``` #### Language Support New `language` field added to both the `Company` and `WorkspaceSettings` schemas to support multi-language email templates. | Field | Type | Values | Default | | - | - | - | - | | `language` | `string` | `en`, `es`, `it`, `pt`, `fr`, `de`, `el` | `en` | ### Schema Changes #### Timestamp Corrections Timestamp field names have been corrected in the spec to match actual API responses: | Schema | Previous Spec | Corrected | | - | - | - | | `Company` | `date_created`, `date_changed` | `created_date`, `updated_date` | | `Workspace` | `date_created`, `date_changed` | `created_date`, `updated_date` | | `Template` | `date_created`, `date_changed` | `created_date`, `updated_date` | | `Reminder` | `date_created`, `date_changed` | `created_at`, `updated_at` | | `Webhook` | `date_created`, `date_changed` | `created_at`, `updated_at` | > [!NOTE] > > These are spec corrections only — the API responses have not changed. If your integration already handles the actual API response fields, no code changes are needed. #### Company Schema | Change | Details | | - | - | | Corrected | `company_name` → `name` (matches actual API response) | | Added | `language` (enum, default `"en"`) | | Corrected | `date_created`/`date_changed` → `created_date`/`updated_date` | #### Template Schema (Expanded) The `Template` schema now includes inline recipients and fields when fetching a single template (`GET /templates/{id}`), reducing the need for separate API calls. | Added Field | Type | Description | | - | - | - | | `page_count` | `integer` | Number of pages in the document | | `expiration_hours` | `integer` | Hours until signing requests expire (default: 168) | | `settings` | `SigningRequestSettings` | Template-level settings | | `recipients` | `array` | Template recipients (inline) | | `fields` | `array` | Template fields (inline) | #### Signing Request Response Shapes The monolithic `SigningRequest` schema has been split into endpoint-specific response shapes: | Schema | Used By | | - | - | | `SigningRequestListItem` | `GET /signing-requests` (list) | | `SigningRequestCreateResponse` | `POST /signing-requests`, `POST /documents` | | `SigningRequestDetail` | `GET /signing-requests/{id}` (unchanged from v1.7.0) | The list and create responses now include inline `recipients` and `fields` arrays, and use standardized timestamp fields (`created_date`, `sent_date`, `finished_date`, etc.). #### SigningRequestSettings `use_signing_order` (boolean, default `false`) is now included in the settings object. Previously this was only available as a deprecated top-level integer field. #### Reminder Schema | Added Field | Description | | - | - | | `recipient_id` | Specific recipient to send reminder to (signing request context) | | `sent_on` | Timestamp when the reminder was actually sent | #### Webhook Schema | Added Field | Type | Description | | - | - | - | | `description` | `string` | Webhook description | | `consecutive_failures` | `integer` | Number of consecutive delivery failures | | `auto_disabled_at` | `datetime` | When the webhook was auto-disabled due to failures | #### SendSigningRequestResponse (Corrected) The spec now accurately reflects the actual response shape: | Previous Spec | Corrected | | - | - | | `success` (boolean) | `message` (string) | | `sentTo` (email) | `signing_request_id` (uuid) | | `sentAt` (datetime) | `recipients_notified` (integer), `sent_date`, `expires_at` | #### WorkspaceSettings | Added Field | Description | | - | - | | `name` | Workspace name | | `language` | Workspace language for email templates | *** ## v01.07.00 **Release Date:** February 25, 2026\ [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.07.00/openapi-v01.07.00.json) ### New Features #### Hand-Drawn Only Signatures A new `hand_drawn_only` setting allows you to require signers to hand-draw their signatures instead of using typed or font-based options. **Added to `SigningRequestSettings` schema:** | Field | Type | Default | Description | | - | - | - | - | | `hand_drawn_only` | `boolean` | `false` | When enabled, signers can only hand-draw their signatures | This setting is available in all places where signing request settings are configured: * Creating signing requests (`POST /signing-requests`) * Creating and sending signing requests (`POST /signing-requests/create-and-send`) * Comprehensive updates (`PUT /signing-requests/{id}`) * Partial updates (`PATCH /signing-requests/{id}`) * Template creation and updates **Example:** ```json theme={null} { "settings": { "hand_drawn_only": true, "use_signing_order": false, "allow_download": true } } ``` ### Schema Changes #### Deprecated Legacy Settings Fields The `SigningRequest` schema now includes deprecated top-level integer fields that mirror the boolean `settings` object. These exist for backward compatibility and should not be used in new integrations: | Deprecated Field | Type | Use Instead | | - | - | - | | `use_signing_order` | `integer` (0/1) | `settings.use_signing_order` | | `allow_download` | `integer` (0/1) | `settings.allow_download` | | `allow_editing_before_sending` | `integer` (0/1) | `settings.allow_editing_before_sending` | | `hand_drawn_only` | `integer` (0/1) | `settings.hand_drawn_only` | | `attach_pdf_on_finish` | `integer` (0/1) | `settings.attach_pdf_on_finish` | > [!WARNING] > > These deprecated fields use `0`/`1` integers instead of booleans. Always use the `settings` object for new integrations. ### Migration Guide No breaking changes. The `hand_drawn_only` setting defaults to `false`, preserving existing behavior. Deprecated top-level integer fields are purely additive. *** ## v01.06.00 **Release Date:** February 12, 2026\ [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.06.00/openapi-v01.06.00.json) ### New Features #### Split PDF Downloads Completed signing requests now support downloading the signed document and audit trail certificate as separate files, in addition to the existing combined download. **New fields on `SigningRequest` schema:** | Field | Description | | - | - | | `document_only_download_url` | Signed URL to download just the signed document (without certificate/audit trail pages) | | `document_only_download_error` | Error indicator if the document-only file is inaccessible | | `certificate_only_download_url` | Signed URL to download just the certificate/audit trail pages | | `certificate_only_download_error` | Error indicator if the certificate-only file is inaccessible | **Notes:** * Only available when the split PDF feature has been applied to the signing request * URLs expire after 1 hour — fetch the signing request again for a fresh URL * Error fields return `"file_not_accessible"` if the file path exists but the file is missing **Example Response (partial):** ```json theme={null} { "id": "sr-uuid", "status": "finished", "final_document_download_url": "https://storage.example.com/combined.pdf", "document_only_download_url": "https://storage.example.com/document.pdf", "document_only_download_error": null, "certificate_only_download_url": "https://storage.example.com/certificate.pdf", "certificate_only_download_error": null } ``` ### Schema Changes #### Field Type Normalization Field type enums now accept both original and normalized forms across all schemas. The API normalizes inputs automatically: | Input | Normalized To | | - | - | | `initials` | `initial` | | `textarea` | `text_area` | **Affected schemas:** | Schema | Change | | - | - | | `TemplateField.type` | `initials` → `initial`; enum now includes both `initial` and `initials` variants | | `Field.type` (signing requests) | Now accepts `initial`/`initials` and `textarea`/`text_area` | | `SigningRequestField.field_type` | `initials` → `initial`, `textarea` → `text_area` | | Template PATCH `field.type` | Now accepts both forms with normalization | | Signing Request PATCH `field.type` | Now accepts both forms with normalization | ### Migration Guide No breaking changes. Both old and new field type names are accepted. The split PDF download fields are purely additive. *** ## v01.05.00 **Release Date:** February 5, 2026\ [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.05.00/openapi-v01.05.00.json) ### New Features #### Email Validation Warnings Signing request endpoints now return non-blocking warnings when recipient email addresses have potentially invalid formats (e.g., unusual TLDs, missing dots). These warnings help identify potential delivery issues without failing the request. **Affected Endpoints:** | Endpoint | Response Field | | - | - | | `POST /signing-requests` (create) | `warnings` array | | `PATCH /signing-requests/{id}` (partial update) | `warning` field | | `PUT /signing-requests/{id}` (comprehensive update) | `warnings` array | **Example Response:** ```json theme={null} { "signing_request": { ... }, "warnings": [ "Recipient email 'user@compny' may have an invalid format" ] } ``` **Notes:** * Warnings are non-blocking — the request still succeeds * Useful for flagging potential typos or invalid email domains * Check the `warnings` or `warning` field in the response to surface these to users ### Migration Guide No breaking changes. Email validation warnings are purely additive and do not affect existing integrations. *** ## v01.04.00 **Release Date:** January 31, 2026\ [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.04.00/openapi-v01.04.00.json) ### New Features #### New Field Types Three new field types have been added: | Field Type | Description | | - | - | | `textarea` | Multi-line text input field | | `url` | Clickable link field (automatically read-only) | | `radio_buttons` | Radio button group (renamed from `radio`) | **URL Field Details:** * Automatically set to `read_only: true` * Use `read_only_value` to set the target URL * Use `format_rules.urlDisplayText` to customize the display text Example: ```json theme={null} { "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" } } } ``` #### PATCH Field Operations Both Template and Signing Request PATCH endpoints now support single-field operations: **Template PATCH** (`PATCH /templates/{id}`): * Can now update properties, a single user, **OR a single field** * Include `field` object in request body * Include `field.id` to update existing field, omit to create new **Signing Request PATCH** (`PATCH /signing-requests/{id}`): * Can now update properties, a single recipient, **OR a single field** * Same field object structure as templates Example - Create new field: ```json theme={null} { "field": { "type": "text", "x": 100, "y": 200, "width": 200, "height": 30, "page": 1, "required": true, "assigned_to_user_id": "user-uuid" } } ``` Example - Update existing field: ```json theme={null} { "field": { "id": "field-uuid", "x": 120, "y": 220 } } ``` #### Template User Matching for Recipients When creating signing requests from templates, you can now use `template_user_id` to explicitly match recipients to template users: ```json theme={null} { "template_id": "template-uuid", "recipients": [ { "template_user_id": "template-user-uuid", "first_name": "Jane", "last_name": "Smith", "email": "jane@example.com" } ] } ``` * `template_user_id` is the preferred method for matching * `order` remains available as a fallback ### Schema Changes #### Field Type Enum Updated from: ``` ["text", "signature", "date", "checkbox", "initials", "dropdown", "radio"] ``` To: ``` ["text", "signature", "date", "checkbox", "initials", "dropdown", "radio_buttons", "textarea", "url"] ``` #### Recipient Schema * Signing request creation now uses shared `Recipient` schema reference * Added `template_user_id` property for explicit template user matching *** ## v01.03.00 [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.03.00/openapi-v01.03.00.json) ### New Features #### Email Domains API A complete new API category for configuring custom email domains for sending signing request emails: **New Endpoints:** * `GET /company/domains` - List all company email domains * `POST /company/domains` - Add a new email domain * `GET /company/domains/{id}` - Get domain details * `DELETE /company/domains/{id}` - Delete a domain * `POST /company/domains/{id}/verify-ownership` - Verify domain ownership via TXT record * `POST /company/domains/{id}/finalize` - Complete domain setup with email provider * `POST /company/domains/{id}/verify-dns` - Verify SPF, DKIM, DMARC records * `POST /company/domains/{id}/set-primary` - Set primary sending domain **New Schemas:** * `Domain` - Email domain configuration with verification status * `DomainDnsRecord` - DNS record details for domain verification #### Credit Cost Tracking * Added `credit_cost` field to `Template` schema - Number of credits consumed when sending * Added `credit_cost` field to `SigningRequest` schema - Credits consumed when sent #### Signing Request Declined Status * Added `declined` to `SigningRequest.status` enum values * Added `date_declined` field to `SigningRequest` schema ### Schema Improvements #### Template Fields * Added `date_default` field for setting default date values (ISO 8601 format) * Enhanced `multi_group_id` description: explains mutually exclusive field grouping for checkboxes/radio buttons * Added clarification that `page_number` is 1-indexed and must not exceed document page count #### Signing Request Fields * Enhanced `multi_group_id` description with same improvements as template fields *** ## v01.02.00 [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.02.00/openapi-v01.02.00.json) ### Enhanced User Information #### TemplateUser Schema Enhancements Added comprehensive recipient information fields: * `first_name` - Recipient first name * `last_name` - Recipient last name * `phone_number` - Contact phone number * `street_address` - Street address * `city` - City * `state_province` - State or province * `postal_code` - Postal/ZIP code * `country` - Country * `title` - Job title * `company` - Company name #### Ready-to-Send Indicators New fields to help determine recipient readiness: * `required_fields` - List of required recipient data fields based on template configuration * `missing_fields` - List of required fields that are currently empty * `required_read_only_fields` - Read-only fields needing pre-filled values * `ready_to_send` - Boolean indicating if recipient has all required data #### SigningRequestUser Schema Enhancements Same enhancements as TemplateUser, plus: * `declined_on` - Timestamp when recipient declined to sign * `decline_reason` - Reason provided by recipient for declining * `custom_fields` - Custom field values for the recipient * `has_value` property in `required_read_only_fields` - Indicates if read-only field has a value ### Response Format Changes Template users endpoint (`GET /templates/{id}/users`) now returns: ```json theme={null} { "results": [ { "id": "uuid", "name": "John Doe", "first_name": "John", "last_name": "Doe", "email": "john@example.com", "designation": "Signer", "order": 1, "required_fields": ["email", "first_name"], "missing_fields": [], "ready_to_send": true } ] } ``` *** ## v01.01.00 [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.01.00/openapi-v01.01.00.json) ### New Endpoints #### Template Management Full CRUD support for templates: * `POST /templates` - Create a new template with base64-encoded PDF * `PATCH /templates/{id}` - Partial update (properties OR single user) * `PUT /templates/{id}` - Comprehensive update (properties, users, fields, reminders) * `DELETE /templates/{id}` - Soft delete a template #### Template Sub-Resources * `GET /templates/{id}/users` - Get all template recipients * `GET /templates/{id}/fields` - Get all template fields * `GET /templates/{id}/reminders` - Get all template reminders #### API Key Management New endpoints for workspace API key lifecycle: * `POST /workspaces/{id}/api-key/regenerate` - Generate new API key with 24-hour grace period * `POST /workspaces/{id}/api-key/expire` - Immediately expire pending keys ### Enhanced Operations #### Comprehensive Updates The PUT endpoint for templates supports: * `template_properties` - Update metadata and settings * `users` - Upsert users (include id to update, omit to create) * `deleted_users` - Delete users with field handling strategy (`delete` or `reassign`) * `fields` - Upsert fields * `reminders` - Upsert reminders Example request: ```json theme={null} { "template_properties": { "name": "Updated Template", "settings": { "allow_editing_before_sending": true } }, "users": [ { "id": "existing-uuid", "email": "updated@example.com" }, { "first_name": "New", "last_name": "Signer", "email": "new@example.com", "designation": "Signer", "order": 2 } ], "deleted_users": [ { "user_id": "user-to-delete", "field_action": "reassign", "reassign_to_user_id": "existing-uuid" } ] } ``` *** ## v01.00.02 [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.00.02/openapi-v01.00.02.json) ### New Features #### Custom Fields API Added custom field definition management for workspaces, templates, and signing requests. **New Tag:** * `Custom Fields` - Custom field definition management **New Schemas:** ##### WorkspaceCustomField ```json theme={null} { "id": "uuid", "field_name": "string", "field_label": "string", "is_preset": true, "preset_value": "string", "created_at": "datetime", "updated_at": "datetime" } ``` ##### TemplateCustomField ```json theme={null} { "id": "uuid", "field_name": "string", "field_label": "string", "created_at": "datetime", "updated_at": "datetime" } ``` ##### SigningRequestCustomField ```json theme={null} { "id": "uuid", "field_name": "string", "field_label": "string", "copied_from_template": true, "created_at": "datetime", "updated_at": "datetime" } ``` ### Schema Improvements #### TemplateField Schema Enhanced with clearer descriptions and additional properties: * Explicit `type` property with enum values * `position` object with x, y, width, height * `read_only` and `read_only_value` for pre-filled fields *** ## v01.00.01 [Download OpenAPI Spec](https://github.com/Firma-esign/firma-docs/raw/4b2cbdb9cd36b46fcbd1cf06f8e079533487c45d/api-reference/v01.00.01/openapi-v01.00.01.json) ### Initial Release The initial release of the Firma Partner API with the following core features: #### API Tags / Categories * **Company** - Company information and settings * **Workspaces** - Workspace management operations * **Templates** - Template management operations * **Signing Requests** - Document signing request operations * **Webhooks** - Webhook configuration and management * **JWT Management** - JWT token generation and revocation * **Legacy** - Deprecated endpoints for backward compatibility #### Authentication * API key authentication via `Authorization` header * Optional Bearer prefix support #### Rate Limiting Tiered rate limits based on operation type: * Read operations (GET): 200 requests/minute * Write operations (POST/PUT/PATCH/DELETE): 120 requests/minute * Webhook CRUD: 60 requests/minute * Webhook test: 10 requests/minute * API key operations: 1 request/minute * Secret rotation: 1 request/minute #### Core Schemas ##### Company * `id`, `company_name`, `account_owner`, `account_owner_email` * `website`, `icon_url`, `credits` (read-only) * `date_created`, `date_changed` ##### Workspace * `id`, `name`, `protected`, `api_key` * `date_created`, `date_changed` ##### Template * `id`, `name`, `description` * `document_url` (pre-signed, expires) * `document_url_expires_at` * `date_created`, `date_changed` ##### SigningRequest * `id`, `name`, `description` * `document_url`, `document_url_expires_at` * `document_page_count`, `status`, `expiration_hours` * `settings`, `template_id` * Date fields: `date_created`, `date_sent`, `date_finished`, `date_cancelled`, `expires_at` * `certificate` object with generation status * `final_document_download_url`, `final_document_download_error` ##### Recipient * Core: `id`, `first_name`, `last_name`, `email`, `designation`, `order` * Address: `street_address`, `city`, `state_province`, `postal_code`, `country` * Professional: `phone_number`, `title`, `company` * `custom_fields` for additional data * Temporary ID support for document-based creation ##### Field * `id`, `type`, `position`, `page_number`, `required` * `recipient_id`, `variable_name` * Type-specific: `dropdown_options`, `date_default`, `date_signing_default` * Read-only: `read_only`, `read_only_value`, `prefilled_data` * Formatting: `format_rules`, `validation_rules` ##### Webhook * `id`, `url`, `events`, `enabled` * `date_created`, `date_changed` #### JWT Management * Generate JWT for template embedding * Generate JWT for signing request embedding * Revoke JWT tokens *** ## Migration Guide ### Migrating from v01.00.01 to v01.00.02 * No breaking changes * Custom Fields API available for use ### Migrating from v01.00.02 to v01.01.00 * No breaking changes * New template management endpoints available * API key regeneration endpoints available ### Migrating from v01.01.00 to v01.02.00 * No breaking changes * Template and signing request users now include additional fields * `ready_to_send` boolean available to check recipient readiness ### Migrating from v01.02.00 to v01.03.00 * No breaking changes * Email domain configuration available for custom sending domains * `declined` status added to signing request status enum * Credit cost tracking available on templates and signing requests ### Migrating from v01.03.00 to v01.04.00 * No breaking changes * `radio` field type renamed to `radio_buttons` (both still accepted) * New field types available: `textarea`, `url` * PATCH endpoints now support single-field operations * Use `template_user_id` for explicit template user matching in signing requests ### Migrating from v01.04.00 to v01.05.00 * No breaking changes * Email validation warnings are purely additive ### Migrating from v01.05.00 to v01.06.00 * No breaking changes * Split PDF download URLs available on completed signing requests * Field type inputs `initials`/`initial` and `textarea`/`text_area` both accepted with automatic normalization ### Migrating from v01.06.00 to v01.07.00 * No breaking changes * New `hand_drawn_only` setting available in signing request settings (defaults to `false`) * Deprecated top-level integer settings fields now visible in `SigningRequest` schema — use `settings` object instead ### Migrating from v01.07.00 to v01.08.00 * No breaking changes — schema field name corrections reflect actual API responses * New Email Templates API for customizing signing notification emails * `language` field added to `Company` and `WorkspaceSettings` * Template schema expanded with inline `recipients`, `fields`, `settings`, `page_count`, `expiration_hours` * `use_signing_order` added to `SigningRequestSettings` * Webhook schema includes `description`, `consecutive_failures`, `auto_disabled_at` * Signing request responses split into endpoint-specific shapes with inline data ### Migrating from v01.08.00 to v01.09.00 * No breaking changes * New `require_otp_verification` setting available at company, workspace, and signing request levels * New `POST /templates/{id}/replace-document` endpoint for replacing template PDFs while preserving fields ### Migrating from v01.09.00 to v01.10.00 * No breaking changes * Conditional field logic available via `required_conditions` and `visibility_conditions` on fields * DOCX files now accepted alongside PDF in all document upload endpoints * New `GET /signing-requests/{id}/audit` endpoint for retrieving audit trails * New `show_signature_frame` setting at company, workspace, and signing request levels * New `force_remove_conditions` parameter on user deletion operations ### Migrating from v01.10.00 to v01.11.00 * **Breaking change:** `use_signing_order` default changed from `false` to `true` — explicitly set `use_signing_order: false` if you rely on simultaneous delivery * New `file` field type for signer file uploads * Anchor tags for automatic field placement from text markers in PDFs * `background_color` property available on all field types ### Migrating from v01.11.00 to v01.12.00 * No breaking changes * MCP Server integration for AI assistant access to the Firma API * No new API endpoints or schema changes — OpenAPI specification unchanged from v1.11.0 ### Migrating from v01.12.00 to v01.12.01 * No breaking changes * New `variable_defined_name` field on all field responses — returns the human-readable custom field definition name alongside the internal `variable_name` * `variable_defined_name` accepted as input for field matching on `POST /signing-requests/create-and-send` ### Migrating from v01.15.03 to v01.16.00 * No breaking changes * New `GET /signing-requests/{id}/download` endpoint for retrieving a download URL for the signed document * Partial downloads available when `allow_partial_download` is enabled in signing request settings ### Migrating from v01.16.00 to v01.17.00 * No breaking changes * Six new nullable color fields (`color_primary`, `color_primary_fg`, `color_background`, `color_foreground`, `color_card`, `color_border`) on Company and Workspace Settings * New `ColorPalette` schema for resolved signing experience colors * Colors follow a 3-tier cascade: Firma defaults -> Company -> Workspace ### Migrating from v1.19.0 to v1.20.0 * No breaking changes * New `disable_guided_navigation` setting available at company, workspace, template, and signing request levels * Follows the same cascading pattern as `require_otp_verification`: signing request -> workspace -> company (first non-null wins) * Defaults to `false` (auto-scroll enabled), preserving existing behavior ### Migrating from v1.20.0 to v1.21.0 * No breaking changes * New `email_local_part` setting on Company (`GET/PATCH /company`) and Workspace Settings (`GET/PUT /workspace/{id}/settings`) * Workspace value takes priority over company value; default is `"support"` * Only applies when a verified custom domain is configured ### Migrating from v1.38.0 to v1.39.0 * No breaking changes * At launch, before October 13, 2026, multi-document features required enablement for your company; companies that were not enabled saw no change * New `document_ids` on `POST /templates`, `POST /signing-requests`, and `POST /signing-requests/create-and-send`, and new `/documents` routes on templates and signing requests * On enabled companies, `anchor_tags[].document_index` selects the document an anchor tag is searched in on multi-document requests * Send `documents_layout_version` with field writes on templates and signing requests that have more than one document ### Migrating from v1.40.0 to v1.40.1 * No change for valid PDFs * A PDF with a page that has no valid content returns `400 MALFORMED_PDF` with `malformed_pages`; nothing is written * An unreadable PDF, including an encrypted one, returns `400 VALIDATION_ERROR` instead of `500` ### Migrating from v1.40.1 to v1.40.2 * No API change * The `events` list of `POST /webhooks` and `PUT /webhooks/{id}` now names the 26 events Firma.dev sends; regenerate clients built from the spec # API Versioning Source: https://docs.firma.dev/guides/api-versioning Learn how the Firma API handles versioning, deprecation, and breaking changes # API Versioning Guide The Firma API uses header-based versioning via the `X-API-Version` header. This allows you to specify which API version you want to use, with automatic deprecation warnings and a structured sunset process. ## How to Specify a Version Include the `X-API-Version` header in your request: ```bash cURL theme={null} curl https://api.firma.dev/functions/v1/signing-request-api/signing-requests \ -H "X-API-Version: 1" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const response = await fetch( 'https://api.firma.dev/functions/v1/signing-request-api/signing-requests', { headers: { 'X-API-Version': '1', 'Authorization': `Bearer ${process.env.FIRMA_API_KEY}` } } ); ``` ```python Python theme={null} import requests headers = { 'X-API-Version': '1', 'Authorization': f'Bearer {os.environ["FIRMA_API_KEY"]}' } response = requests.get( 'https://api.firma.dev/functions/v1/signing-request-api/signing-requests', headers=headers ) ``` > [!NOTE] > > If the `X-API-Version` header is omitted, the API defaults to the current stable version (currently **1**). ## Version Lifecycle Each API version goes through three stages: | Status | Description | Behavior | | - | - | - | | **active** | Fully supported version | Normal responses with `X-API-Version` header | | **deprecated** | Still functional but scheduled for removal | Responses include deprecation warning headers | | **sunset** | Removed from service | Returns `410 Gone` error | ## Response Headers ### For Active Versions ``` X-API-Version: 1 ``` ### For Deprecated Versions When a version is deprecated, the following headers are included in every response: ``` X-API-Version: 1 Deprecation: 2025-06-01 Sunset: 2025-12-01 X-Deprecated-Message: This API version is deprecated and will be removed on 2025-12-01. Please migrate to version 2. ``` | Header | Description | | - | - | | `Deprecation` | RFC 8594 compliant - Date when the version was deprecated | | `Sunset` | RFC 8594 compliant - Date when the version will be removed | | `X-Deprecated-Message` | Human-readable warning message | ## Error Responses ### Invalid Version Header ```json theme={null} // 400 Bad Request { "error": "Invalid X-API-Version header. Must be a positive integer.", "code": "INVALID_VERSION" } ``` ### Unsupported Version ```json theme={null} // 400 Bad Request { "error": "API version 99 is not supported. Supported versions: 1", "code": "UNSUPPORTED_VERSION" } ``` ### Sunset Version (Removed) ```json theme={null} // 410 Gone { "error": "API version 1 has been removed as of 2025-12-01. Please migrate to version 2.", "code": "VERSION_SUNSET" } ``` ## Breaking Changes Policy > [!NOTE] > > Breaking changes are only introduced in major version increments (e.g., v1 → v2). Non-breaking changes such as new optional fields or new endpoints do not require a new version. When a new major version is released: 1. **The previous version is marked as deprecated** 2. **You'll receive warning headers** for a recommended 6-month deprecation period 3. **After the sunset date**, the old version returns `410 Gone` ### What Constitutes a Breaking Change? Breaking changes include: * Removing or renaming existing fields * Changing field types or validation rules * Removing endpoints * Changing authentication requirements * Modifying rate limits significantly Non-breaking changes include: * Adding new optional fields * Adding new endpoints * Adding new enum values (if your client handles unknown values gracefully) * Improving error messages ## Best Practices > **Always check for deprecation headers** > > Implement automated checks in your API client code to detect `Deprecation` and `Sunset` headers. Log warnings when these headers are present. > > ```javascript theme={null} > const response = await fetch(url, options); > > if (response.headers.get('Deprecation')) { > console.warn('API Deprecation Warning:', { > deprecation: response.headers.get('Deprecation'), > sunset: response.headers.get('Sunset'), > message: response.headers.get('X-Deprecated-Message') > }); > } > ``` > **Explicitly specify the version** > > Rather than relying on the default version, always specify the `X-API-Version` header explicitly. This prevents unexpected breaking changes when the default version changes. > > ```javascript theme={null} > // Good - explicit version > headers: { 'X-API-Version': '1' } > > // Avoid - relies on default > headers: { } > ``` > **Subscribe to changelog updates** > > Stay informed about upcoming changes by subscribing to the changelog or API announcements. This gives you advance notice of: > > * New version releases > * Deprecation schedules > * Breaking changes > * Migration guides > **Test against new versions early** > > When a new version is announced, test your integration against it well before the sunset date of the old version. This gives you time to: > > * Identify breaking changes in your implementation > * Update your code and dependencies > * Test thoroughly in staging > * Deploy with confidence before the deadline ## Current Version Status The current active version is **v1** with no deprecation scheduled at this time. > [!NOTE] > > When new versions are released or deprecation schedules are announced, this guide will be updated with specific dates and migration information. ## Related Resources > **[Authentication](/guides/authentication)** > > Learn about API key authentication and JWT tokens > **[Complete Setup Guide](/guides/complete-setup-guide)** > > Get started with the Firma API > **[Webhooks](/guides/webhooks)** > > Set up webhook notifications for events > **[API Reference](/api-reference/v01.15.00/company/get-company-information)** > > Browse all API endpoints # Audit Trail Source: https://docs.firma.dev/guides/audit-trail Track every action on a signing request for compliance and reporting. Every signing request in Firma has a complete audit trail. Every document view, field interaction, signature, decline, and admin action is recorded with timestamps, actor identity, and IP addresses. The finalized PDF and its completion certificate include `Signing Request ID: