Skip to main content
This document provides a detailed changelog of all Firma API versions, documenting new features, breaking changes, and improvements between each release.

Version Summary


v1.40.3

Release Date: October 20, 2026 Release Type: Patch Release

One-time-code evidence in the audit trail

The audit trail now records that a signer entered the one-time code, with a reference to the verified code record, and verify-signing-otp answers more precisely when a code cannot be verified.
  • Audit events. GET /signing-requests/{id}/audit returns otp_verified events with details.channel = "email" and details.otp_code_id, described as Entered the one-time code sent by email. document_finished events carry details.otp_code_id when the finishing session was linked to a verified code. This applies to requests under 1,000 tracking rows; larger requests keep today’s truncation.
  • verify-signing-otp responses.
    • A database fault returns 500 INTERNAL instead of OTP_NOT_FOUND.
    • An unknown signer returns 404 SIGNING_USER_NOT_FOUND.
    • A signer of a deleted request returns 404 SIGNING_REQUEST_NOT_FOUND. Before, a live code on a deleted request still verified.
    • A malformed signingUserId returns 400 INVALID_INPUT.
    • A request that can no longer be verified (cancelled, declined, expired, already signed, not yet sent, not the signer’s turn, or seal paused) returns 200 with code: "SIGNING_STATE_CHANGED" and state.
    • A correct code with a transient fault no longer consumes an attempt.
  • No OpenAPI schema change. event remains free text. This release adds no reference version and links no OpenAPI document.
  • Admin audit descriptions. GET /signing-requests/{id}/audit and the dashboard audit trail describe a cancel from the dashboard as Signing Request Cancellation requested and a delete from the dashboard as Signing Request Deletion requested. A certificate retry adds Certificate regeneration requested. Firma.dev writes each line before the change, so the line stays when the action then fails or loses a race; “requested” does not confirm completion. Rows written before this release keep the old wording (Signing Request Cancelled / Signing Request Deleted).

v1.40.2

Release Date: October 19, 2026 Release Type: Patch Release OpenAPI Spec: Download v1.40.2 spec

Webhook event list

The events list of POST /webhooks and PUT /webhooks/{id} in the OpenAPI spec now names the 26 events Firma.dev sends, the same events the Webhooks guide describes. Since v1.37.0 the list had named events the API refuses and left out events it sends. The API itself has not changed.
  • Added, already sent: signing_request.updated, signing_request.certificate.generated, signing_request.reminder.sent, signing_request.recipient.signed, signing_request.recipient.declined, and signing_request.recipient.identity_changed.
  • Removed, never accepted by the API (a request that names one returns 400 VALIDATION_ERROR): signing_request.declined, signing_request.voided, signing_request.field.completed, signing_request.resent, and signing_request.credits.purchased. For a signer who declines, subscribe to signing_request.recipient.declined; for a cancelled request, to signing_request.cancelled.
  • Removed, accepted by the API but never sent: template.created, template.deleted, template.field.added, and workspace.deleted. A webhook that names them stays valid, but no event of these types arrives.

Migration notes

  • No change to requests, responses, or webhook deliveries.
  • If you generated a client or validation from the spec, regenerate it: the old list refused events you can subscribe to and offered events the API refuses.

v1.40.1

Release Date: October 18, 2026 Release Type: Patch Release OpenAPI Spec: Download v1.40.1 spec

Damaged PDFs

Since October 18, 2026, Firma.dev refuses a PDF in which a page has no valid content, for example a page whose content points to another page’s data instead of its own drawing instructions. Such a page renders blank, and Firma.dev cannot generate the completion certificate of a request that contains it. The request returns 400 MALFORMED_PDF:
  • malformed_pages lists the 1-based numbers of the damaged pages. The message names the first.
  • On POST /signing-requests, POST /signing-requests/create-and-send, and POST /templates, document_position (1-based, in the request’s document order) names the document, and document_id is added when the document came from document_id or document_ids.
  • Nothing is written: no template, no signing request, no credit charge, no email.
  • On POST /signing-requests, POST /signing-requests/create-and-send, and POST /templates, an upload named by document_id or document_ids is used up when this error is returned: upload the repaired file with POST /documents again for a new id. On the /documents add and replace routes, the upload is kept.
  • Re-exporting the file from the application that created it, or saving it again from a PDF editor, usually repairs it.
The routes that return it are the ones that accept a document: POST /templates, PATCH /templates/{id}, PUT /templates/{id}, POST /templates/{id}/replace-document, POST /templates/{id}/documents, PATCH /templates/{id}/documents/{document_id}, POST /signing-requests, POST /signing-requests/create-and-send, PATCH /signing-requests/{id}, POST /signing-requests/{id}/documents, and PATCH /signing-requests/{id}/documents/{document_id}.

Unreadable PDFs

Since October 17, 2026, a document that cannot be read as a PDF, including an encrypted PDF, returns 400 VALIDATION_ERROR with the message The uploaded document is not a readable PDF on the same routes. Before, it returned 500. The /documents add and replace routes already answered this way, and now also do for a file that starts like a PDF but whose page tree cannot be read.

Migration notes

  • Requests with valid PDFs behave as before.
  • Where you upload documents, handle 400 MALFORMED_PDF: show the message and ask for a repaired file. Sending the same file again returns the same error.
  • If you parse error responses strictly, accept malformed_pages, document_position, and document_id.
  • An unreadable PDF now returns 400, not 500. Do not retry it.

v1.40.0

Release Date: October 17, 2026 Release Type: Minor Release OpenAPI Spec: Download v1.40.0 spec

Signing page buttons

Two new settings control the buttons that signers and approvers see on the signing page, hosted or embedded:
  • allow_decline shows the Decline to Sign button. When it is false, the button is hidden for every signer and approver, and Firma.dev also refuses a decline. No one can decline the signing request in Firma.dev, so it can only be stopped by cancelling it.
  • show_save_for_later shows the Save & Finish Later button. When it is false, only the button is hidden.
Firma.dev uses the signing request’s value. When it is null, the workspace’s value applies, and when that is null too, the company’s. The company default is true, so signing pages are unchanged until you set a value.
  • A signing request created from a template (template_id on POST /signing-requests and POST /signing-requests/create-and-send, or POST /templates/{id}/duplicate) copies the template’s values when it is created. On the two create routes, a value in the request’s settings replaces the template’s; null there means the workspace value. POST /templates/{id}/duplicate always copies the template’s values. Changing the template later does not change signing requests already created from it.
  • POST /templates/{id}/copy copies both values to the new template.
  • A change to the workspace or company value applies to every signing request whose own value is null, including requests already sent and requests created before this release.
  • Responses return the values as true, false, or null: in settings on templates (GET /templates, GET /templates/{id}, POST /templates, PUT /templates/{id}) and signing requests (GET /signing-requests, GET /signing-requests/{id}, and the create responses), and at the top level of GET /company/settings and GET /workspace/{workspace_id}/settings. The company values are always true or false.
  • Any other value, such as a string or a number, returns 400 VALIDATION_ERROR naming the key (for example settings.allow_decline must be a boolean or null) and writes nothing. PUT /company/settings also refuses null.

Request size limit

Since October 13, 2026, a request body larger than 6,291,456 bytes (6 MiB) returns 413 REQUEST_TOO_LARGE with the standard error and code body. Before, the gateway answered 502. The API reference documents it on POST /templates, POST /signing-requests, POST /signing-requests/create-and-send, and POST /documents. To send a larger document, request an upload URL with POST /documents, upload the file to it, and pass document_id or document_ids instead of inline base64.

Migration notes

  • The change is additive. Requests that never send allow_decline or show_save_for_later behave as before, and both buttons stay visible until a value is set.
  • If you parse responses strictly, accept the two new keys in template, signing request, workspace settings, and company settings responses.
  • If you send large inline base64 documents, handle 413 REQUEST_TOO_LARGE, or upload through POST /documents.

v1.39.1

Release Date: October 12, 2026 Release Type: Patch Release OpenAPI Spec: Download v1.39.1 spec

Update, October 13, 2026

  • On POST /signing-requests and POST /signing-requests/create-and-send with template_id, when the template has no recipients of its own and seal_participants is absent or null, inherited seals now keep their template order first (1..k), followed by the request’s recipients (k+1..). Explicit replacement arrays, templates with recipients, and requests without seals retain their existing order behavior.
  • Replacements through PATCH /seals/{id} now require statement with accepted: true, version: 1, language, text exactly equal to the stored statement_text from GET /seals/{id}, and signatory_name (signatory_title optional). This applies to changes in image, typed, display_name, signatory_title, or statement. Without statement, the request returns 400 SEAL_STATEMENT_REQUIRED and writes nothing. POST /seals creation behavior is unchanged.
  • Each replacement records its own attestation time, caller, and supplied signatory. Statement text, hash, language, statement version, and authority_name remain those of seal version 1. Requests already sent keep their pinned version; requests sent after replacement use the new version, whose signatory and attestation date appear on their certificates.
  • Seal objects in POST /seals, GET /seals, GET /seals/{id}, PATCH /seals/{id}, and the organization_seal.created, organization_seal.updated, and organization_seal.deleted webhooks now include statement_text and statement_hash. Attester user and API key IDs, IP address, and user agent are excluded from these seal objects.

Organization seals from templates

POST /signing-requests and POST /signing-requests/create-and-send with a template_id now copy the template’s seal participants and their seal fields. The seal_participants key decides what happens:
  • Absent or null: the request inherits the template’s seals.
  • An array: the array replaces the template’s seals. The template’s seal fields are not copied.
  • []: the request is created without seals.
  • Any other type returns 400 VALIDATION_ERROR. This is checked on every create route, with or without template_id.
Body fields only override template fields, so on a template that has fields a replacement array’s seals cannot get a stamp field in that call, and sending returns 400 SEAL_NO_IMAGE_FIELD. To use your own seals with their fields, create from a document, or, on POST /signing-requests only, use a template without fields and assign body fields with seal_participant_temp_id. Otherwise inherit the template’s seals. An inherited seal uses the current version of its seal. If the seal has no current version, or that version is revoked or deleted, the create returns 409 SEAL_UNAVAILABLE and nothing is written. If at least one inherited seal is kept and organization seals are not enabled, the create returns 503 SEALS_DISABLED. An inherited seal that is limited to another workspace than the request’s, or that the API key’s company cannot see, is left out, along with its fields. It is listed in the response with dropped: true, after the other entries. Every other entry carries dropped: false.
seal is null when the API key’s company cannot see the seal. A company-wide seal is never left out.

Order with a template

When a create with template_id resolves at least one seal, recipients and seals are renumbered 1..n. Inherited seals keep their positions relative to the template’s recipients. Seals in a replacement array are placed by their order. A seal comes first when it ties with a recipient. Such a create returns 201 where it used to return 400 INVALID_SIGNING_ORDER or 400 SEAL_ORDER_COLLISION. The response reports the renumbered orders.
  • Since October 13, 2026, if the template has no recipients and seal_participants is absent or null, inherited seals keep their template order first (1..k); the request’s recipients follow (k+1..).
  • On POST /signing-requests, a numeric recipient_id on a field keeps counting recipients as they would be numbered without the seal.
  • Document-based creates (document, document_id, document_ids) with explicit seal participants are unchanged: the raw order checks apply.

Seal fields and sending

A seal needs at least one stamp field. Create does not check this, but sending a signing request whose seal has no stamp field returns 400 SEAL_NO_IMAGE_FIELD. Give every seal at least one stamp field.

Duplicating a template

Except for companies enabled for multi-document features, POST /templates/{id}/duplicate copies the template’s seal participants and their fields into the new signing request, and returns them in seal_participants ([] when there are none). Each kept seal uses the current version of its seal. If the seal has no current version, or that version is revoked or deleted, the route returns 409 SEAL_UNAVAILABLE. A seal limited to another workspace than the target workspace, or that the API key’s company cannot see, is left out and listed with dropped: true. If at least one seal is kept and organization seals are not enabled, the route returns 503 SEALS_DISABLED. Both errors are returned before anything is written. For companies enabled for multi-document features, this route attaches the template’s stored seal version as is. A seal that was replaced, revoked, or deleted since then fails when you send. The response has no seal_participants key.

seal_attribute

A seal-owned text field takes seal_attribute: display_name or signatory_title. It sets which seal property the field prints. POST /signing-requests and POST /signing-requests/create-and-send accept it, from a document or a template. Any other value returns 400 VALIDATION_ERROR; null is accepted.
  • POST /signing-requests/create-and-send from a document now keeps seal_attribute. Before, it was dropped.
  • A seal field copied from a template keeps the template field’s formatting. seal_attribute on the request replaces only which property it prints.

Templates

  • GET /templates/{id} and PUT /templates/{id} return seal_participants, ordered by order, [] when the template has none. Each entry has the shape of seal participants elsewhere.
  • POST /templates does not accept seal_participants, recipients, or fields. It ignores them and returns a warnings array with one string per key present, for example seal_participants is not accepted on POST /templates and was ignored; add it with PATCH or PUT /templates/{id}. Without those keys the response is unchanged.

Other changes

  • Fixed: seal_participants on GET /signing-requests/{id}, GET /signing-requests, POST /signing-requests, and POST /signing-requests/create-and-send now returns each organization seal participant with its seal (id, lineage, version, name and display name) for every company. Previously this list was empty, even though the seal itself was saved and applied correctly on the document. This fix changes only what the API returns; stored documents, signatures, and webhooks are not changed by it.
  • Completion certificates now draw the applied seal’s stamp, date, and text fields, and list each seal participant in the signers table, in signing order. The certificate is not generated while a seal is still outstanding (not applied, or paused). A seal applied automatically at completion, without a triggering recipient, no longer blocks the certificate; its audit line reads “after all preceding participants completed” (in the certificate’s language).

Documentation and API reference

The API reference for this version documents the following. They describe answers the API already gave.
  • Each entry of seal_participants on POST /signing-requests and POST /signing-requests/create-and-send requires temp_id and order. seal_id is optional: without it the workspace’s default seal is used or, when the workspace has none, the company’s default seal, and the call returns 400 SEAL_UNAVAILABLE when neither exists. The reference had seal_id as required and temp_id as optional.
  • The seal_participant body of PATCH /signing-requests/{id} and PATCH /templates/{id} is documented as the API reads it: id, seal_id, order, and on signing requests swap_to_seal_id. The key participant_id that earlier references showed was never read; use id. Adding a seal participant answers 201 and updating or swapping one answers 200, both with { "seal_participant": ... }. These routes return 503 SEALS_DISABLED when organization seals are not enabled and a seal participant is added or its seal is changed. On PATCH /signing-requests/{id}, a field that belongs to a seal participant accepts only position and page changes; other keys, recipient_id included, are ignored.
  • A seal swap on PATCH /signing-requests/{id} documents its answers: 403 PROTECTED_KEY_REQUIRED when the API key is not of the protected workspace; 404 NOT_FOUND when the new seal does not exist, belongs to another company, or is limited to another workspace; 409 SEAL_UNAVAILABLE when the new seal is revoked, deleted, or not the current version; 409 SEAL_MUTATION_NOT_ALLOWED when the request was not sent or the participant is not paused; 400 SEAL_FIELD_REQUIRED when the participant has no stamp field.
  • The 200 body of DELETE /signing-requests/{id}/seal-participants/{participant_id} is { "deleted": true }.
  • The fields array of the POST /signing-requests/create-and-send response lists all active fields, including the fields owned by seal participants. Each item is the stored field record, not the Field shape used in requests (for example the type is in field_type).
  • POST /templates/{id}/copy documents its seal_participants (unchanged behaviour).
  • PUT /templates/{id} documents its seal_participants request array (TemplateSealParticipantInput), which replaces the template’s seal set.
  • The 400 of POST /signing-requests/create-and-send lists SEAL_NO_IMAGE_FIELD (a seal without a stamp field refused when sending).
  • Settings whose null has a meaning (require_otp_verification, require_terms_acceptance, allow_presigning_download, terms_url, a field’s recipient_id or assigned_to_user_id, identity_editable_fields, and the workspace settings show_signature_frame and show_partial_watermark) now state what null does.

Migration notes

  • For seal replacements from October 13, 2026 onward, read GET /seals/{id} and send statement on PATCH /seals/{id}: accepted: true, version: 1, language, the exact stored statement_text as text, and signatory_name (signatory_title optional). Handle 400 SEAL_STATEMENT_REQUIRED and accept statement_text and statement_hash in seal objects.
  • A POST /signing-requests or POST /signing-requests/create-and-send with template_id and no seal_participants key now inherits the template’s seals. Send "seal_participants": [] to create without them. null inherits too (including a client that sends null for an unset field).
  • A seal_participants value that is not an array or null now returns 400 VALIDATION_ERROR on POST /signing-requests and POST /signing-requests/create-and-send; before, it was ignored.
  • If you parse responses strictly, accept the new keys: dropped on create responses, warnings on POST /templates, and seal_participants on GET /templates/{id}, PUT /templates/{id}, and POST /templates/{id}/duplicate.

v1.39.0

Update, October 13, 2026: Multi-document features are available to every company. No enablement is needed. The enablement restrictions in the original release notes below describe the initial rollout.
Release Date: October 12, 2026 Release Type: Minor Release OpenAPI Spec: Download v1.39.0 spec

Multiple documents per template and signing request

A template or signing request can now hold up to 20 documents, with a limit of 100 MB per document set. You can create one from several uploads, then add, replace, rename, reorder, remove, and download its documents one at a time.
At launch, before October 13, 2026, multi-document features required enablement for your workspace’s company. This covered the /documents routes, document_ids with more than one id, per-document anchor tags (anchor_tags[].document_index), and the documents, documents_version, and documents_layout_version response keys. At that time, if a company was not enabled:
  • The /documents routes return 404 NOT_FOUND, exactly like an unknown endpoint.
  • The three response keys are absent.
  • document_index on an anchor tag is not applied: a single-document create accepts it with an unknown-property warning and uses the only document.
  • POST /templates, POST /signing-requests, and POST /signing-requests/create-and-send with more than one entry in document_ids (repeated ids count) return 409 MULTI_DOCUMENT_READ_ONLY before anything is created.
While multi-document editing is suspended, writes to a multi-document template or signing request return 409 MULTI_DOCUMENT_READ_ONLY. Reads keep working.

Creating with several documents

POST /templates, POST /signing-requests, and POST /signing-requests/create-and-send accept document_ids. Pass 1 to 20 temporary upload ids from POST /documents, in document order.
  • Send exactly one document source: document, document_id, or document_ids (or template_id on the signing-request routes). Sending more than one returns 400 CONFLICTING_DOCUMENT_SOURCE.
  • A repeated id returns 400 DUPLICATE_DOCUMENT_ID. More than 20 ids return 400 MAX_DOCUMENTS_EXCEEDED. An unknown or expired upload returns 400 DOCUMENT_UPLOAD_NOT_FOUND. A set above 100 MB returns 413 DOCUMENT_SET_TOO_LARGE.
  • document is no longer marked as required on POST /templates, because document_id or document_ids can take its place.

Per-document anchor tags

For enabled companies, anchor tags take a new document_index: the 1-based position in document_ids of the document to search. It is only meaningful for multi-document requests.
  • With one document, document_index is optional and defaults to 1.
  • With more than one document, it is required. A missing value returns 400 ANCHOR_DOCUMENT_REQUIRED; a value out of range returns 400 VALIDATION_ERROR.

New endpoints

Every add, replace, rename, reorder, and remove returns the full document set after the change, with documents, documents_version, and documents_layout_version.
  • A replacement must have the same number of pages, and every page must be the same size within 1 pt. Otherwise it returns 400 PAGE_COUNT_MISMATCH or 400 DIMENSION_MISMATCH. On a signing request, a document placed with anchor tags is replaced only when the replacement’s anchors resolve exactly as stored. Otherwise it returns 400 ANCHOR_MISMATCH.
  • A sent, finished, cancelled, or declined signing request returns 409 DOCUMENT_SET_LOCKED on every document write.
  • A document id that is not part of the template or signing request returns 404 DOCUMENT_NOT_FOUND. A missing or repeated id in a reorder returns 400 INVALID_DOCUMENT_ORDER. Removing the last document returns 400 MIN_DOCUMENTS_REQUIRED.
  • The download returns 404 DOCUMENT_ORIGINAL_NOT_AVAILABLE when the uploaded file is no longer stored, and 404 DOCUMENT_SIGNED_NOT_AVAILABLE before the certificate is bound.

Documents in responses

For enabled companies, these responses carry documents, documents_version, and documents_layout_version: GET /templates, GET /templates/{id}, POST /templates, PUT /templates/{id}, GET /signing-requests, and GET /signing-requests/{id}.
  • Each entry of documents has document_id, position, label, original_filename, page_count, and document_url_kind. Outside list responses, each entry also includes a signed document_url, valid for 1 hour. Signing requests also include document_only_hash, the SHA-256 of the individually sealed document once the certificate is bound.
  • A template or signing request whose document set has never been changed returns its one document with document_id: null. In list responses, it shows documents: [].
  • documents_version increases with every document change. documents_layout_version increases when documents are added, removed, or reordered.

Field writes on multi-document templates and signing requests

PUT and PATCH on /templates/{id} and /signing-requests/{id} accept documents_layout_version alongside field writes. Send the value from your last read.
  • It is required for a field write when there is more than one document or the layout version is above 1. A missing value returns 409 DOCUMENTS_LAYOUT_VERSION_REQUIRED.
  • A stale value returns 409 DOCUMENT_SET_VERSION_CONFLICT. Reload and retry.
  • A value that is not a non-negative integer returns 400 VALIDATION_ERROR with the key documents_layout_version. A field placed on a page beyond its document’s page count returns 400 VALIDATION_ERROR with the key page.
  • An inline document on PATCH /signing-requests/{id} for a request with more than one document returns 409 MULTI_DOCUMENT_REPLACE_UNSUPPORTED. Use the /documents routes instead.

Templates with several documents

  • POST /templates/{id}/copy copies a template with more than one document as a template with one merged document. The content and the absolute page numbers of its fields are kept. The per-document labels and positions are not carried over.

Create and send conflicts

POST /signing-requests/create-and-send can return 409 with MULTI_DOCUMENT_READ_ONLY, SEND_IN_PROGRESS, SEND_EFFECTS_EXIST, ALREADY_SENT, DOCUMENT_SET_BUSY, DOCUMENT_SET_INCONSISTENT, DOCUMENT_SET_VERSION_CONFLICT, or DOCUMENT_SET_DISPATCH_STALE. SEND_EFFECTS_EXIST and ALREADY_SENT can also carry signing_request_id. It is present when the signing request this call created was kept. Recover that request instead of retrying, because a retry creates a second request. Without signing_request_id, no request was kept.

Error codes

New codes, all returned as { error, code }: The MultiDocumentErrorCode schema in the API reference lists all 42 codes that the multi-document routes and the routes they change can return. A server fault returns 500 with INTERNAL_ERROR or INTERNAL, depending on the route (the /documents routes use INTERNAL); neither carries detail.

Participant order

Signers, approvers, and organization seal participants share one order space. CC recipients are stored separately and never take a position in it.
  • PATCH /templates/{id} and PATCH /signing-requests/{id} move a recipient or seal participant by shift-insert: every participant between the old and new positions is renumbered. A target position above n returns 400 INVALID_SIGNING_ORDER. An order below 1 returns 400 INVALID_SIGNING_ORDER for a recipient and 400 VALIDATION_ERROR for a seal participant.
  • A new Signer or Approver on those routes is inserted at order within [1..n+1], or appended when order is omitted. order: 0 or a position outside that range returns 400 INVALID_SIGNING_ORDER.
  • A new seal participant requires order as a positive integer. A missing or zero order returns 400 VALIDATION_ERROR; a position outside [1..n+1] returns 400 INVALID_SIGNING_ORDER.
  • On PATCH /templates/{id} and PATCH /signing-requests/{id}, the seal must belong to your company: another company’s seal returns 404 NOT_FOUND. A revoked, deleted, or superseded seal returns 400 SEAL_UNAVAILABLE. A seal scoped to another workspace returns 400 SEAL_UNAVAILABLE on PATCH /signing-requests/{id}. On PATCH /templates/{id} it returns 404 NOT_FOUND when you add a seal participant or move one (order set); changing only the seal of an existing participant (id and seal_id, no order) does not check the seal’s workspace.
  • On a sent signing request, PATCH /signing-requests/{id} returns 409 ALREADY_SENT, except a protected caller’s swap of a paused seal participant. Removing a seal participant with DELETE /signing-requests/{id}/seal-participants/{participant_id} returns 409 SEAL_MUTATION_NOT_ALLOWED.
  • An order change that conflicts with a seal participant that has already been applied returns 409 SIGNING_ORDER_LOCKED_APPLIED.
  • POST /signing-requests and POST /signing-requests/create-and-send without seals number recipients in array order when use_signing_order is false or any recipient omits order. With seals, every recipient needs an order, and recipients and seals together must form 1..n: a missing order or a gap returns 400 INVALID_SIGNING_ORDER, and two participants (recipients or seals) on the same order return 400 SEAL_ORDER_COLLISION.
  • PUT /templates/{id} applies each entry of users and deleted_users as its own participant write. If one entry fails, the entries applied before it are kept.
  • POST /templates/{id}/copy keeps the source template’s order, drops seal participants whose seal is not in scope for the target workspace (along with their fields), and compacts the remaining participants to [1..n].

Organization seal authority name

Seals returned by POST /seals, GET /seals, GET /seals/{id}, and PATCH /seals/{id} include authority_name, the name the seal was attested for: the company for company scope or the protected workspace, otherwise the workspace. It is null for seals whose lineage was created before the name was pinned; those seals certify in the company’s current name.

Other changes

  • POST /signing-requests/{id}/resend returns 409 SEND_IN_PROGRESS while a send of that signing request is in progress.
  • Fixed: for companies enabled for multi-document signing, creating a signing request (POST /signing-requests) and creating and sending one (POST /signing-requests/create-and-send) now return each organization seal participant with its seal (id, lineage, version, name and display name) in seal_participants. Previously this list was empty, even though the seal itself was saved and applied correctly on the document. Signed documents, certificates and webhooks are not affected.
  • Documentation only: the POST /signing-requests/create-and-send response now documents seal_participants, which it already returned. The resend response now documents recipients_suppressed, the number of recipients not reminded because their address is suppressed.

Unchanged

  • PUT /signing-requests/{id} with a field id that does not belong to the signing request still returns 400, on multi-document requests too.
  • reminders on POST /signing-requests/create-and-send work as before, including on requests created with document_ids.

Migration notes

  • The change is additive. Requests that never use document_ids, document_index, or the /documents routes behave as before, and companies that are not enabled see no new response keys.
  • If you generate a client from the OpenAPI spec: document is optional on POST /templates, and the seal participant schema in signing-request responses is now named SealParticipantApi (previously SealParticipant).
  • If you parse error codes strictly, accept the new codes above.
  • On an enabled company, send documents_layout_version with field writes on templates and signing requests that have more than one document.

v1.38.0

Release Date: September 17, 2026 Release Type: Minor Release OpenAPI Spec: Download v1.38.0 spec

Catalan support

The supported language set grows from 14 to 15 with the addition of Catalan (ca), joining en, es, it, pt, fr, de, el, ru, pl, cs, sv, nl, ro, and nb. The new code is accepted at every language-bearing surface of the API:
  • Workspace settings: language on PUT /workspace/{workspace_id}/settings (and returned by the corresponding GET)
  • Company settings: language on the company settings endpoints
  • Per-signing-request email language: the language field on POST /signing-requests, POST /signing-requests/create-and-send, and PATCH / PUT /signing-requests/{id}
  • Signer terms: the {language} path parameter on the company and workspace signer-terms endpoints (PUT / DELETE)
  • Email template defaults: GET /email-templates/defaults/{language}
  • Organization seal statement: statement.language on seal creation and update, returned as statement_language on the seal
Setting Catalan localizes the full signer experience: signer-facing emails, the signing ceremony UI, the consent statement recorded at terms acceptance, and date formatting. The completion certificate follows the workspace language, so set Catalan on the workspace for a Catalan certificate. Validation errors for unsupported codes now list all 15 languages.

Migration notes

  • The API change is additive. The existing 14 language codes are accepted and returned exactly as before, and requests that never send ca validate as before.
  • Unless the signing URL carries a supported lang code, the signing page selects the first language in the signer’s browser preference list that Firma.dev supports. A signer whose browser lists ca or a ca- regional tag ahead of every other supported language now sees the signing page in Catalan. Before v1.38.0, the signer saw the next supported language in the list or English. Signing links sent by email do not include a lang parameter, so this behavior also applies to existing signers. A supported lang code you add to an embedded signing URL still sets the language; any other value is ignored.
  • The consent statement resolves in this order: workspace terms in the signer’s language, company terms in the signer’s language, workspace terms in the workspace’s configured language, company terms in the company’s configured language, then Firma.dev’s default terms in the signer’s language. If no Catalan terms or terms in the applicable configured language exist, a Catalan-first signer now accepts Firma.dev’s default Catalan statement instead of custom terms in another browser language, such as Spanish. Terms in the workspace’s or company’s configured language still apply when available.
  • Add Catalan signer terms at the company or workspace level to keep custom terms for these signers. Use PUT /company/signer-terms/ca, PUT /workspace/{workspace_id}/signer-terms/ca, or the dashboard terms settings.

v1.37.1

Release Date: September 15, 2026 Release Type: Patch Release OpenAPI Spec: Download v1.37.0 spec (unchanged in this release)

CC recipients

The update endpoints now store recipients with "designation": "CC", and the read endpoints now return them. Before this release they did neither.

Adding and updating CC recipients

  • PUT /templates/{id} (users[]) and PATCH /templates/{id} (user) store CC recipients. Previously these returned 400 and 500.
  • PUT /signing-requests/{id} (recipients[]) and PATCH /signing-requests/{id} (recipient) store CC recipients. Previously PUT returned 200 and counted the CC in summary.recipients_created without storing it, and PATCH returned 500.
  • On PUT /signing-requests/{id}, a recipient that fails to save is now listed in details.recipients of the 400 response instead of being counted in summary.recipients_created.
  • Existing CC recipients can be updated by id and removed through deleted_users / deleted_recipients, the same way as signers and approvers.
  • first_name and email are required for a new CC recipient.
  • designation is matched case-insensitively ("CC", "cc").

CC recipients in responses

CC recipients are returned with "designation": "CC", after signers and approvers, by:
  • GET /signing-requests/{id}/users
  • GET /templates/{id}/users
  • GET /templates/{id} and GET /templates (recipients)
  • the recipients array of the POST /signing-requests, POST /signing-requests/create-and-send, and PUT /signing-requests/{id} responses
CC entries carry the same keys as the other entries on that endpoint. They never get a signing link, and keys that only apply to signing hold neutral values (for example required_fields: [] and ready_to_send: true).

Template-based creation

  • POST /signing-requests and POST /signing-requests/create-and-send with template_id now copy the template’s CC recipients to the new signing request. A template CC is skipped when a CC with the same email (case-insensitive) is already on the request.
  • A request-body recipient with "designation": "CC" is always added as a CC recipient. It is never matched to a template user by template_user_id or order.

Validation

  • Changing an existing recipient between CC and Signer or Approver returns 400. PATCH /templates/{id} and PATCH /signing-requests/{id} return the message Cannot change designation between CC and Signer/Approver; delete the recipient and create it again, PUT /signing-requests/{id} lists it in details.recipients, and PUT /templates/{id} returns the generic Validation errors occurred. Delete the recipient and create it again with the new designation.
  • A field cannot be assigned to a CC recipient. On PUT /signing-requests/{id}, including for a CC created in the same request through _temp_id, the field error reads Cannot assign fields to CC recipient.; other field paths reject a CC id as an invalid recipient.
  • Updating or deleting a recipient by id now only matches recipients that have not been deleted. An already-deleted recipient is treated as not found instead of being written to.

Migration notes

  • No new endpoints, fields, or enum values, so the v1.37.0 spec still applies.
  • Recipient lists can now include CC entries. If your code treats every entry as a signer, check designation.
  • Signing requests created from a template that has CC recipients now include those CC recipients, and they receive the completed document. Remove the CC recipients from the template if you do not want this.
  • If you relied on PUT /signing-requests/{id} returning 200 when a recipient failed to save, handle the 400 response.

v1.37.0

Release Date: September 14, 2026 Release Type: Minor Release OpenAPI Spec: Download v1.37.0 spec

Organization Seals

Electronic seals applied automatically on behalf of a company, as participants in the signing order. Setup, scope rules, and certificate output are described in the Organization Seals guide.

New endpoints

Seal participants

Signing requests and templates accept a seal_participants[] array alongside recipients[] / users[] on POST /signing-requests, POST /signing-requests/create-and-send, PATCH /signing-requests/{id}, POST /templates, and PATCH /templates/{id}. Each entry takes temp_id (client id used to assign fields), seal_id, and order. Recipients and seals share one contiguous order space; order 1 applies at send. Fields owned by a seal set seal_participant_temp_id instead of a recipient. Seal fields are server-authored (read_only: 1, no recipient) and client-provided values on them are ignored. Signing-request responses now include seal_participants[].

Seal swap

PATCH /signing-requests/{id} accepts seal_participant: { "id": "<participant-id>", "swap_to_seal_id": "<seal-uuid>" } to move a paused participant on a sent request to a different in-scope seal. Requires a protected API key.

Webhook events

Error codes

SEALS_DISABLED, SEAL_NOT_FOUND, SEAL_SCOPE_FORBIDDEN, SEAL_IMAGE_INVALID, SEAL_ALREADY_REVOKED, SEAL_ERASE_NOT_ELIGIBLE, SEAL_MUTATION_NOT_ALLOWED, SEAL_ORDER_COLLISION, SEAL_PAUSED, SEAL_UNAVAILABLE, and SEAL_CREATION_DISABLED_EDGE (reserved for the edge fallback host; the primary API host performs seal creation).

Migration notes

  • Purely additive. recipients[], users[], and all existing endpoints are unchanged.
  • No breaking changes.

v1.36.0

Release Date: August 31, 2026 Release Type: Minor Release OpenAPI Spec: Download v1.36.0 spec

Anchor tags

  • add_white_background on anchor tag definitions draws a white background across the full resolved field rectangle, independently of anchor-text removal.

Error responses

  • Error objects carry a machine-readable code.
  • Validation failures also return errors[] with every error when multiple failures are reported together; the top-level error repeats the first item for backward compatibility.

Create and send

  • POST /signing-requests/create-and-send responses include warnings[]: optional non-blocking warnings, including unknown anchor-tag properties during the compatibility window and anchor-processing warnings.

Migration notes

  • Purely additive. No breaking changes.

v1.35.0

Release Date: August 13, 2026 Release Type: Minor Release OpenAPI Spec: Download v1.35.0 spec

Cross-workspace template copy

New endpoint POST /templates/{id}/copy deep-copies a template to another workspace within the same company. All child data is copied with correct ID remapping:
  • Template settings (expiration, signing order, email flags, completion page, etc.)
  • Recipients (signers, approvers) with designation preserved
  • Fields with required_conditions and visibility_conditions field references remapped
  • CC recipients
  • Custom field definitions
  • Reminders with recipient references remapped
  • PDF document (independently stored copy)
Request body:
  • workspace_id (required, uuid) - target workspace to copy the template into
  • name (optional, string, max 255) - name for the copy (defaults to original name with ” (copy)” suffix)
Authorization: requires a company-level (protected) API key. Workspace-scoped keys receive 403 PROTECTED_KEY_REQUIRED. New endpoint:
  • POST /templates/{id}/copy - copy template to another workspace

v1.34.0

Release Date: August 7, 2026 Release Type: Minor Release OpenAPI Spec: Download v1.34.0 spec

Completion page customization

Four new nullable fields on signing requests, templates, workspace settings, and company settings control what signers see after completing their signature:
  • completion_title (string, max 200 chars) - custom heading on the completion page
  • completion_message (string, max 1000 chars) - custom body text
  • completion_redirect_url (string, max 2000 chars, https only) - URL to redirect signers to after signing
  • completion_redirect_delay (integer, 0-30) - seconds before redirect (defaults to 5 when a URL is set)
Settings cascade from company to workspace to template to signing request. Each level can override the parent, and each field resolves independently. Setting a field to null (or omitting it) inherits from the parent level; the built-in translated completion page is the final fallback. Affected endpoints:
  • POST /signing-requests - accepts completion fields
  • POST /signing-requests/create-and-send - accepts completion fields
  • PUT /signing-requests/{id} - accepts completion fields
  • PATCH /signing-requests/{id} - accepts completion fields
  • GET /signing-requests/{id} - returns completion fields
  • POST /templates - accepts completion fields
  • PUT /templates/{id} - accepts completion fields
  • PATCH /templates/{id} - accepts completion fields
  • GET /templates/{id} - returns completion fields
  • PUT /workspace/{id}/settings - accepts completion fields
  • GET /workspace/{id}/settings - returns completion fields
  • PUT /company/settings - accepts completion fields
  • GET /company/settings - returns completion fields
Validation:
  • completion_redirect_url must use https://. For test-mode signing requests (is_test: true), http://localhost and http://127.0.0.1 are also accepted.
  • Redirect is time-limited: the auto-redirect only fires within 10 minutes of signing completion. After that, the custom title and message still display but no redirect occurs.

Migration guide

No breaking changes. All new fields are nullable and default to null. Existing signing requests, templates, and settings are unaffected - the completion page renders its built-in translated content when no custom settings are configured.

v1.33.0

Release type: Minor Release Released: 2026-08-03 Download OpenAPI Spec

Five new languages

The supported language set grows from 9 to 14: Czech (cs), Swedish (sv), Dutch (nl), Romanian (ro), and Norwegian Bokmål (nb) join en, es, it, pt, fr, de, el, ru, pl. The new codes are accepted at every language-bearing surface of the API:
  • Workspace settings — language on PUT /workspace/{workspace_id}/settings (and returned by the corresponding GET)
  • Company settings — language on the company settings endpoints
  • Per-signing-request email language — the language field on POST /signing-requests, POST /signing-requests/create-and-send, and PATCH / PUT /signing-requests/{id}
  • Signer terms — the {language} path parameter on the company and workspace signer-terms endpoints (GET / PUT / DELETE)
  • Email template defaults — GET /email-templates/defaults/{language}
Setting one of the new languages localizes the full signer experience: signer-facing emails, the signing ceremony UI, the consent statement recorded at terms acceptance, date formatting, and the completion certificate (including correct rendering of Czech and Romanian diacritics). Validation errors for unsupported codes now list all 14 languages.

Migration Guide

No action required. The change is purely additive — the existing 9 language codes behave exactly as before, and workspaces or signing requests that never set a language are unaffected.

v1.32.0

Release type: Minor Release Released: 2026-07-22 Download OpenAPI Spec

Explicit field font size

Text-bearing fields (text, textarea, email, name, phone, company, title, number, date, signing_date, approval_date, dropdown, url) now accept an optional fontSize inside format_rules — an integer between 8 and 48, in pixels. See the new TextFormatRules schema; DateFormatRules gains the same optional property, so a date field can carry both dateFormat and fontSize. The value is a starting/maximum size, not a guarantee: the signing view and the sealed PDF both start rendering the field value at the explicit size and still auto-shrink it to fit the field box when the content overflows. Omit the property for automatic sizing (the previous behavior, unchanged). Out-of-range values are clamped to 8-48; non-numeric values are ignored. Signature, initials, checkbox, radio, file, and stamp fields do not accept a font size. Set it wherever format_rules is accepted — template field create/update and signing-request field payloads — for example:

Anchor tags: font_size

Anchor tags gain an optional font_size property (integer, 8-48). When an anchor resolves to a field, the value is stored on the created field as format_rules.fontSize and behaves exactly as above.

Migration Guide

No action required. The properties are optional and additive — fields without fontSize render exactly as before, and existing templates and signing requests are unaffected.

v1.31.0

Release type: Minor Release Released: 2026-07-14 Download OpenAPI Spec

Opt-in signing-request email language

New optional language field on the signing-request create and update endpoints — POST /signing-requests, POST /signing-requests/create-and-send, and PATCH / PUT /signing-requests/{id}. Set it to one of en, es, it, pt, fr, de, el, ru, pl, and every signer-facing email for that signing request — invitation, reminders, OTP verification, completion and CC, expiry, cancellation, and decline — along with its date formatting, uses that language. The field is nullable and additive: language controls the signer-facing emails for the whole request.

Migration Guide

No action required. The field is optional — omit it or send null and behavior is unchanged: emails fall back to the workspace language, then the company language, then en. Existing signing requests are unaffected.

v1.30.0

Release type: Minor Release Released: 2026-07-08 Download OpenAPI Spec

Retrieve signer marks as images

Four new read-only endpoints return a signer’s captured marks individually, separate from the signed PDF:
  • GET /signing-requests/{id}/signers/{signer_id}/signature — the signer’s adopted signature
  • GET /signing-requests/{id}/signers/{signer_id}/initials — the signer’s adopted initials
  • GET /signing-requests/{id}/signers/{signer_id}/stamps/{field_id} — a stamp for a specific stamp field
  • GET /signing-requests/{id}/signers/{signer_id}/files/{field_id} — a file the signer uploaded to a file field
The signature, initials, and stamp endpoints return the mark as a base64 PNG data URI (data:image/png;base64,...), usable directly in an <img src>. The file endpoint returns a short-lived (300 second) pre-signed download URL. A signer adopts one signature and one initials, applied to all their fields of that type, so those endpoints take no field_id; stamps and files are per-field and require field_id (obtain field IDs from GET /signing-requests/{id}/fields). By default a signer-ID frame is overlaid on returned images; pass include_frame=false for the bare mark. These endpoints are rate limited to 60 requests per minute. The legal validity of a signature rests on the sealed PDF and its completion certificate, not on a retrieved image.

Migration Guide

No breaking changes. These are new additive endpoints; existing integrations require no changes.

v1.29.0

Release type: Minor Release Released: 2026-07-06 Download OpenAPI Spec

Two-step document upload

A new POST /documents endpoint enables uploading documents larger than the inline request size limit. Instead of sending a base64-encoded document in the request body, you can now:
  1. Call POST /documents with the file metadata to receive a presigned upload URL
  2. PUT the raw file bytes directly to the upload URL (supports up to 50MB)
  3. Pass the returned document_id in your POST /signing-requests or POST /signing-requests/create-and-send request
This is required for documents larger than approximately 5MB. Smaller documents can continue using the inline document field.

New request field: document_id

The POST /signing-requests/create-and-send endpoint now accepts document_id as an alternative to document and template_id. All three fields are mutually exclusive - provide exactly one.

Document size limit increase

The maximum document size has been increased from 20MB to 50MB when using the two-step upload flow.

Migration Guide

No breaking changes. Existing integrations using inline document or template_id continue to work unchanged. To upload larger documents, adopt the two-step flow via POST /documents.

v1.28.0

Release type: Minor Release Released: 2026-07-05 Download OpenAPI Spec

TypeScript SDK code samples

Every endpoint in the API reference now includes a copy-paste code sample for the official @firma-dev/sdk TypeScript client, showing the exact typed call for that operation. See the new TypeScript SDK guide to install the client and get started.

Reference surface changes

The following endpoints were removed from the API reference because they are not part of the documented partner API surface:

Migration Guide

No changes are required for integrations using the partner API endpoints documented here. If you were referencing the embedded signing-request endpoints, use the Embeddables guides instead; the embedded editor continues to rely on those endpoints. If you were using the legacy /documents endpoints, migrate to the template (POST /templates) and signing request (POST /signing-requests) endpoints.

v1.27.0

Release type: Patch Release Released: 2026-06-29 Download OpenAPI Spec

Settings fields now documented in responses

This release documents settings fields that the API already returns. All changes are additive and backward-compatible — no API behavior changed, only the OpenAPI specification was updated to match what the endpoints already send.

Signing request settings

The settings object returned by the signing request endpoints (POST /signing-requests, POST /signing-requests/create-and-send, GET /signing-requests, GET /signing-requests/{id}, PUT /signing-requests/{id}, PATCH /signing-requests/{id}) now documents four additional fields:

Template settings

The settings object returned by the template endpoints (POST /templates, PUT /templates/{id}, PATCH /templates/{id}, GET /templates, GET /templates/{id}, POST /templates/{id}/replace-document) now documents the show_qr_code field. Template settings cover the same options as signing request settings except the signer-identity fields (identity_editable_fields, notify_identity_change_email), which apply only to signing requests.

Cancel and resend responses

New schemas

Two new schemas split the settings shapes that differ across endpoints, so each response documents exactly the fields it returns:

Migration Guide

No breaking changes. These are documentation-only additions describing fields the API already returns. Existing integrations are unaffected. If you parse settings objects, you can now rely on the documented show_qr_code, allow_presigning_download, identity_editable_fields, and notify_identity_change_email fields, and on emails_sent / recipients_failed in cancel and resend responses.

v1.26.0

Release type: Minor Release Released: 2026-06-23 Download OpenAPI Spec

Workspace settings: four new fields

Four fields are now available on GET /workspace/{workspace_id}/settings and PUT /workspace/{workspace_id}/settings:

Button label overrides structure

Customizable button keys: common.finish, signing.approveAndFinish, signing.nextRequiredField, signing.saveAndFinishLater, signing.decline.confirm, signing.decline.title, signing.decline.cancel, signing.finishAnyway, signing.goBack. Values are sanitized server-side (HTML stripped, max 200 characters). Empty or whitespace-only values are ignored.

v1.25.2

Release type: Patch Release Released: 2026-06-18 Download OpenAPI Spec

Stricter validation for template field overrides

When creating a signing request from a template, any provided field that does not match a field in that template is now rejected with 400 VALIDATION_ERROR instead of being silently ignored. Previously such a field was dropped and the request still succeeded, so a mistyped identifier meant the field simply never appeared on the document with no error. A provided field matches a template field by template_field_id, variable_name, or variable_defined_name. The error names the offending field(s):
Applies to POST /signing-requests and POST /signing-requests/create-and-send. Migration: ensure every field you send on a template-based create references an existing template field. If you were relying on extra/unmatched fields being ignored, remove them.

Case-insensitive field types

Field type values are now normalized case-insensitively. "Initials", "Signature", "TextArea", etc. resolve to their canonical type (initial, signature, text_area) instead of being rejected as invalid. Lowercase values are unchanged.

v1.25.1

Release type: Patch Release Released: 2026-06-14 Download OpenAPI Spec

Accurate error responses for create-and-send

POST /signing-requests/create-and-send previously returned a generic 500 whenever the send step rejected a request, hiding the real reason. It now returns the client-actionable status (400, 402, or 422) with a machine-readable code and the relevant detail:
  • 400 VALIDATION_ERROR — request or send validation failed (e.g. a signer missing required information); the response includes validation_errors, field_errors, or details identifying what to fix.
  • 402 INSUFFICIENT_CREDITS — not enough credits to send; current_credits reports the balance.
  • 422 RECIPIENT_EMAIL_SUPPRESSED (new) — a recipient’s email address is suppressed (previously bounced or marked as spam) and cannot be sent to.
Genuine server-side failures still return 500. When the send step fails, the partially-created signing request is rolled back, so no orphaned draft is left behind. Migration guide: No action required for clients that already treat any non-2xx response as a failure. If you previously special-cased the opaque 500 from this endpoint, switch to branching on the HTTP status / code: 400 and 422 mean “fix the request, then retry,” 402 means “add credits.”

v1.25.0

Release type: Minor Release Released: 2026-06-14 Download OpenAPI Spec

Editor Brand Colors

The appearance settings now include five additional brand colors that theme the embedded editors (the template and signing-request editors you embed on your own pages):
  • color_accent — accent color for highlights, active tabs, switches, and primary controls in the editor chrome.
  • color_accent_fg — foreground (text/icon) color shown on accent surfaces.
  • color_canvas — the document-canvas surround color behind the page.
  • color_muted — muted surface color (separators, hover states, switch tracks).
  • color_muted_fg — muted text color.
These join the existing six color fields, so settings endpoints now carry eleven color_* fields:
  • GET/PUT /company/settings and GET/PUT /workspace/{workspace_id}/settings accept and return all five new fields. Each is a nullable #rrggbb hex string; null means inherit (workspace → company → Firma default).
  • The resolved color_palette object returned in embedded-editor payloads now contains eleven keys (the six existing plus accent, accent_fg, canvas, muted, muted_fg). When unset, muted defaults to the resolved card color and muted_fg is derived for readability, so the palette is always fully populated.
Workspace values override company values; unset values fall back to the Firma defaults, so existing integrations render unchanged. Migration guide: No action required. All five fields are additive and nullable. To brand the embedded editors, send any of the new color_* fields (valid #rrggbb hex, or null to clear) to the company- or workspace-settings endpoint.

v1.24.0

Release type: Minor Release Released: 2026-06-09 Download OpenAPI Spec

Workspace Test API Keys

Workspaces now expose a test-mode API key alongside the existing live key. Requests authenticated with a test key do not consume credits and produce test-flagged, watermarked signing requests.
  • POST /workspaces now provisions a live + test key pair and returns both api_key (live) and the new test_api_key field.
  • GET /workspaces/{id} and GET /workspaces now return both api_key and test_api_key.
  • POST /workspaces/{id}/api-key/regenerate and /api-key/expire accept an optional key_type ("live" or "test", default "live"). Regenerating one key type no longer affects the other.
  • Existing workspaces created via the API are backfilled with a test key.
All changes are additive and backward-compatible: consumers that read api_key continue to work unchanged. Migration guide: No action required. To use test mode, read test_api_key from any workspace create/get response and send it as the Authorization key for requests you want to run in test mode.

v1.23.0

Release type: Minor Release Released: 2026-06-04 Download OpenAPI Spec

Signer Terms

New Signer Terms endpoints let you manage custom signer consent statements at the company and workspace levels:
  • GET endpoints list company and workspace signer terms
  • PUT endpoints create or update per-language company and workspace signer terms
  • DELETE endpoints remove company and workspace signer terms

Company Settings

New GET /company/settings and PUT /company/settings endpoints expose company settings, including the terms acceptance gate.

Schema Changes

  • Company settings schema: added require_terms_acceptance (boolean)
  • Workspace settings schema: added require_terms_acceptance (boolean, nullable). Use null to inherit the company setting.

Migration Guide

No breaking changes. This release is additive, and no action is required for existing integrations.

v1.22.1

Release type: Patch Release Released: 2026-06-02 Download OpenAPI Spec

Email Domain Deletion

DELETE /company/domains/{id} and DELETE /workspace/{workspace_id}/domains/{id} now succeed when the target is the workspace’s primary domain or its only domain. Previously these returned 400 "Cannot delete primary domain". After deletion, outbound email falls back to the company default sender, or the platform default if none is set. To use a custom sending domain again, add and verify a new domain, then set it as primary.

Migration Guide

No breaking changes. The 400 "Cannot delete primary domain" and “cannot delete the only domain” responses are removed from both DELETE domain endpoints; they now return 200 in those cases. Integrations that special-cased that 400 can drop the handling.

v1.22.0

Release type: Minor Release Released: 2026-05-30 Download OpenAPI Spec

Delete Signing Request Endpoint

New DELETE /signing-requests/{id} endpoint for removing unsent (draft) signing requests. This endpoint only works on signing requests that have not been sent yet. For sent signing requests, use the existing cancel endpoint instead. Response:
  • 200 with signing_request_id and deleted_on on success
  • 409 ALREADY_SENT if the signing request has been sent
  • 404 if not found or already deleted

New Webhook Event

  • signing_request.deleted fires when a signing request is deleted via the API

Migration Guide

No breaking changes. The new DELETE method on /signing-requests/{id} is purely additive. Existing integrations are unaffected.

v1.21.1

Release type: Patch Release Released: 2026-05-19 Download OpenAPI Spec

Workspace Webhook Management

The PATCH /workspaces/{id} endpoint now supports two new fields for managing workspace-level webhooks via the API:
  • webhook_enabled (boolean) - Enable or disable workspace-level webhooks. When set to true for the first time, a webhook secret is automatically generated.
  • ignore_company_webhooks (boolean) - If true, company-level webhooks will not fire for events in this workspace.
Previously, these settings could only be configured through the dashboard UI.

Schema Changes

  • PATCH /workspaces/ request body: added webhook_enabled (boolean, optional) and ignore_company_webhooks (boolean, optional)
  • PATCH /workspaces/ response: now includes webhook_enabled, webhook_secret, webhook_secret_rotated_at, webhook_secret_created_at, and ignore_company_webhooks

Migration Guide

No breaking changes. Existing workspace webhook configurations are unaffected. Use PATCH /workspaces/{id} with webhook_enabled: true to enable workspace webhooks via API instead of the dashboard.

v1.21.0

Release type: Minor Release Released: 2026-05-14 Download OpenAPI Spec

New Settings

  • email_local_part (string, nullable) - Customize the local-part (before the @) of outgoing signing emails when using a verified custom domain. Available at two levels:
    • Company settings (GET/PATCH /company) - Sets the default for all workspaces. String with default "support".
    • Workspace settings (GET/PUT /workspace/{id}/settings) - Overrides company default. Nullable string (null inherits from company).
Emails are sent from {email_local_part}@{your-custom-domain}. For example, setting email_local_part to "noreply" sends emails from noreply@yourdomain.com instead of support@yourdomain.com. Validation: lowercase alphanumeric, dots, hyphens, and underscores. Must start and end with an alphanumeric character. 1-64 characters. Pattern: ^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$

Schema Changes

  • Company schema: added email_local_part (string, default "support")
  • Workspace settings schema: added email_local_part (string, nullable)

Migration Guide

No breaking changes. Existing configurations continue to send emails from support@{domain} by default. Set email_local_part at the company or workspace level to customize the sender address.

v1.20.0

Release type: Minor Release Released: 2026-05-12

New Settings

  • disable_guided_navigation (boolean, nullable) - Disable automatic scrolling to the next required field during signing. Available at four levels:
    • Company settings (GET/PUT /company/settings) - Sets the default for all workspaces. Boolean (not nullable).
    • Workspace settings (GET/PUT /workspace/{id}/settings) - Overrides company default. Boolean or null (null inherits from company).
    • Template (POST/PATCH /templates) - Copied to signing requests created from this template. Boolean or null.
    • Signing request (POST/PATCH /signing-requests) - Highest priority override. Boolean or null (null inherits from workspace/company).
The setting follows the same cascading pattern as require_otp_verification: signing request level takes priority, then workspace, then company settings.

Schema Changes

  • Company settings schema: added disable_guided_navigation (boolean)
  • Workspace settings schema: added disable_guided_navigation (boolean, nullable)
  • Template settings schema: added disable_guided_navigation (boolean, nullable)
  • Signing request settings schema: added disable_guided_navigation (boolean, nullable)

Migration Guide

No breaking changes. Existing signing requests and templates continue to work as before (auto-scroll enabled by default). To disable auto-scroll, set disable_guided_navigation: true at the desired level. Download OpenAPI Spec

v1.19.0

Release type: Minor Release Released: 2026-05-12

New Endpoints

  • POST /company/logo - Upload a company logo image (PNG or JPEG, max 2MB). The logo appears on signing certificates and emails.
  • DELETE /company/logo - Remove the company logo. Certificates fall back to the Firma default.
  • POST /workspaces/{id}/logo - Upload a workspace-specific logo that overrides the company logo for that workspace.
  • DELETE /workspaces/{id}/logo - Remove the workspace logo. Falls back to the company logo.

Schema Changes

  • Workspace schema now includes icon_url (string, nullable) - a publicly accessible URL to the workspace logo image
  • Company icon_url is now read-only in PATCH/PUT requests. Use the new POST /company/logo endpoint to manage logos.

Migration Guide

  • If you were setting icon_url directly via PATCH /company or PATCH /workspaces/{id}, switch to the new POST .../logo endpoints instead. The icon_url field is no longer accepted in update request bodies.
  • icon_url in GET responses now returns a publicly accessible URL instead of an internal reference.
Download OpenAPI Spec

v1.18.0

Release date: May 5, 2026

New Features

Identity Editable Fields

Signing requests now support per-field, per-signer identity editing. When configured, signers see a confirmation dialog before signing where they can review and edit specified identity fields (name, company, title, phone, address). New settings property: Valid field keys: name, company, title, phone, address Per-recipient override via identity_editable_fields on the recipient object:
  • null - use request default
  • [] - disabled for this signer
  • ["name", "company"] - custom fields for this signer
Example:
In this example, John inherits the request default (name + company editable), while Jane has identity editing explicitly disabled. New webhook event: signing_request.recipient.identity_changed is now available as a standard webhook event. Subscribe to it in your webhook configuration to receive notifications when a signer modifies their identity during signing.

Editable Prefilled Data Fields

Prefilled data fields can now be optionally editable by signers. Previously, all fields with prefilled_data set were automatically locked as read-only. A new prefilled_editable property lets you control this behavior. When prefilled_editable is true, the field value is still auto-populated from recipient data, but the signer can modify it during the signing process. Available on:
  • Template fields (PATCH /templates/{id}, PUT /templates/{id})
  • Signing request fields (POST /signing-requests, POST /signing-requests/create-and-send)
  • Field response objects (GET /signing-requests/{id})
Example - create a signing request with an editable prefilled field:

Field Value Source Validation

The API now validates that fields use only one value source at a time. Requests that combine read_only_value, prefilled_data, and explicit value on the same field will return a 400 VALIDATION_ERROR. This enforcement applies to:
  • POST /signing-requests
  • POST /signing-requests/create-and-send
  • PATCH /templates/{id} (field creation and update)
  • PUT /templates/{id} (field upsert)

Value Precedence

When prefilled_editable is true and both an explicit value and prefilled_data are set on a field, the explicit value takes precedence over the auto-populated recipient data.

Migration Guide

No breaking changes. New features are opt-in:
  • Identity editing is disabled by default (identity_editable_fields: null). Set it to an array of field keys to enable.
  • Existing prefilled data fields remain locked (read-only) by default. Set prefilled_editable: true in format_rules to make them editable.

v1.17.0

Release date: April 30, 2026 Download OpenAPI Spec

New Features

Color Customization for Signing Experience

Six new nullable color fields allow you to customize the signing experience appearance at both company and workspace levels. Colors follow a 3-tier cascade: Firma defaults are used unless overridden at the company level, and company colors are used unless overridden at the workspace level. New fields on Company (GET /company, PUT /company, PATCH /company): New fields on Workspace Settings (GET /workspace/{workspace_id}/settings, PUT /workspace/{workspace_id}/settings): The same six fields are available on workspace settings. Set a value to override the company default, or set null to inherit from the company.

ColorPalette Schema

A new ColorPalette schema represents the resolved color palette applied to the signing experience. All values are hex color strings (#rrggbb).

Migration Guide

From v1.16.0 to v1.17.0: This is a non-breaking additive change. Existing integrations continue to work without modification.
  • All six color fields default to null, which preserves the existing Firma default appearance.
  • To customize colors, set hex values on company settings (company-wide defaults) or workspace settings (per-workspace overrides).
  • The color cascade is: Firma defaults -> Company overrides -> Workspace overrides. Each level only overrides fields that are explicitly set (non-null).

v1.16.0

Release date: April 27, 2026 Download OpenAPI Spec

New Features

Download Signing Request Document

A new endpoint retrieves a download URL for a signing request’s document. For completed signing requests, the URL points to the final signed PDF. For in-progress, cancelled, declined, or expired requests, the URL points to a partial snapshot PDF capturing the document state at the time of the last signer action. Endpoint: GET /signing-requests/{id}/download Response fields: Behavior by status: Partial snapshots are generated on demand and cached. The first request may return 503 with a Retry-After header while the PDF is being generated — retry after the indicated interval. URL expiry: The download_url is a pre-signed URL. Fetch the endpoint again after expires_at to get a fresh URL.

Partial Download Watermark Setting

A new workspace setting show_partial_watermark controls whether partial PDF downloads include an “IN PROGRESS — NOT YET EXECUTED” diagonal watermark. Defaults to disabled. Can be set at the company level (default for all workspaces) or overridden per workspace. Endpoint: PUT /workspace/{workspace_id}/settings

Migration Guide

From v1.15.3 to v1.16.0: This is a non-breaking additive change. Existing integrations continue to work without modification.
  • The download endpoint is purely opt-in. No existing behavior changes.
  • Call GET /signing-requests/{id}/download — handle 503 with Retry-After until the document is ready.

v1.15.3

Release date: April 27, 2026 Download OpenAPI Spec

Clean field aliases for GET /signing-requests//fields

The fields endpoint now returns clean, consistently-named fields alongside the existing database column names: Additionally, required, read_only, and date_signing_default now return booleans (true/false) instead of integers (0/1). All deprecated fields remain in the response for backward compatibility and will be removed in a future major version.

Migration guide

Update your field parsing to use the new names. The deprecated names still work:

v01.15.02

Release Date: April 23, 2026
Download OpenAPI Spec

Bug Fixes

Create-and-Send Field Types Expanded

The create-and-send endpoint’s fields schema was missing several field types that were already supported by the backend and available via anchor_tags. The following types have been added to the fields.type enum:
  • dropdown (with dropdown_options property)
  • radio_buttons
  • text_area
  • url
  • file
These types were already accepted by the API and fully functional. This update aligns the OpenAPI specification with the actual backend behavior. Affected endpoint:
  • POST /signing-requests/create-and-send — fields[].type enum

v01.15.01

Release Date: April 17, 2026
Download OpenAPI Spec

Bug Fixes

Language Enum Updated

Added missing ru (Russian) and pl (Polish) language codes to all language enum fields across the API. These languages were already supported by the platform but were missing from the OpenAPI specification, preventing API users from setting them via documented endpoints. Affected endpoints:
  • PUT /workspace/{workspace_id}/settings — language field
  • PUT /company and PATCH /company — language field
  • GET /email-templates/defaults — language query parameter

v01.15.00

Release Date: April 16, 2026
Download OpenAPI Spec

New Features

Workspace-Scoped Webhooks

Webhooks can now be scoped to individual workspaces instead of applying company-wide. This allows different workspaces to have independent webhook configurations and signing secrets.
  • workspace_id parameter on webhook creation — Pass an optional workspace_id when creating a webhook to scope it to a specific workspace. Omitting it creates a company-level webhook (existing behavior).
  • workspace_id filter on webhook listing — Filter the webhook list by workspace. When omitted, only company-level webhooks are returned.
  • ignore_company_webhooks workspace field — Workspaces can opt out of receiving company-level webhook events by setting this flag to true.

Workspace Webhook Secret Management

Two new endpoints for managing workspace-level webhook signing secrets:
  • POST /workspaces/{id}/webhooks/rotate-secret — Generates a new webhook signing secret for the workspace. The old secret remains valid for a 7-day grace period.
  • GET /workspaces/{id}/webhooks/secret-status — Returns the status of the workspace webhook secret including creation date, rotation date, and grace period information.

Workspace Response Webhook Fields

The workspace GET response now includes webhook-related fields:
  • webhook_enabled — Whether workspace-level webhooks are enabled
  • webhook_secret — The current webhook signing secret
  • webhook_secret_created_at — When the current secret was created
  • webhook_secret_rotated_at — When the secret was last rotated
  • ignore_company_webhooks — Whether the workspace ignores company-level webhook events

Changes

  • Added optional workspace_id parameter to POST /webhooks and GET /webhooks
  • Added 5 new fields to the Workspace schema: webhook_enabled, webhook_secret, webhook_secret_created_at, webhook_secret_rotated_at, ignore_company_webhooks
  • Added 2 new endpoints: POST /workspaces/{id}/webhooks/rotate-secret, GET /workspaces/{id}/webhooks/secret-status
  • SSRF protection applied to webhook URL validation

Migration Guide

From v01.14.00 to v01.15.00: This is a non-breaking additive change. Existing integrations continue to work without modification.
  • Company-level webhooks remain the default. The workspace_id parameter is optional on both create and list endpoints.
  • Existing webhooks are unaffected. The new workspace fields on the workspace response default to webhook_enabled: false and ignore_company_webhooks: false.
  • To adopt workspace webhooks, create a webhook with a workspace_id, then use the workspace secret rotation endpoint to generate a signing secret for that workspace.

v01.14.00

Release Date: April 12, 2026
Download OpenAPI Spec

New Features

Recipient Designations

The designation field on signing request and template recipients now accepts three values: "Signer", "Approver", and "CC".
  • Signer — Signs the document (existing behavior, remains the default)
  • Approver — Approves the document using approval-specific fields. Approvers do not sign but must complete all assigned approval fields before the request can finish.
  • CC — Receives a completed copy of the signed document. CC recipients cannot sign or have fields assigned to them.
At least one Signer is still required per signing request.

Approval Field Types

Three new field types for Approver recipients:
  • approval_signature — An approval stamp placed by the approver
  • approval_checkmark — An approval checkbox
  • approval_date — Auto-filled date when the approver approves
These field types can only be assigned to recipients with "Approver" designation.

CC Recipients

CC recipients are now supported across all create and update endpoints for both templates and signing requests. CC recipients appear in the recipient list but have no fields and do not participate in the signing or approval flow.

Changes

  • Expanded designation enum from ["Signer"] to ["Signer", "Approver", "CC"] across 7 schemas
  • Added approval_signature, approval_checkmark, and approval_date to field type enums across 10 schemas

Migration Guide

From v01.13.00 to v01.14.00: This is a non-breaking additive change. Existing integrations continue to work without modification.
  • New designation values are opt-in. Omitting the designation field defaults to "Signer", preserving existing behavior.
  • New field types are additive. All existing field type values remain valid and unchanged.
  • If you integrate approval workflows, assign "Approver" designation to the relevant recipients and use the approval_* field types for their fields.

v01.13.00

Release Date: April 12, 2026
Download OpenAPI Spec

New Features

Stamp Field Type

New stamp field type for placing pre-configured image stamps or company seals on documents. Stamps are read-only PNG images set by the template or signing request creator, rendered at signing time with no signer interaction, and embedded in the final PDF.

Changes

  • Added stamp to field type enums across all field-related schemas (templates, signing requests, create-and-send)
  • Updated field type descriptions to document stamp behavior

Migration Guide

From v01.12.01 to v01.13.00: This is a non-breaking additive change. Existing integrations are not affected.
  • If you create fields via the API, you can now use "stamp" as a field type. Stamp fields should be set as read_only: true with the stamp image as a PNG data URL in read_only_value.
  • Stamp fields are also supported in anchor tags. When using anchor tags, the stamp image should be provided via read_only_value as a PNG data URL.

v01.12.01

Release Date: April 2, 2026
Download OpenAPI Spec

New Features

variable_defined_name on Field Responses

All API endpoints that return template or signing request fields now include a variable_defined_name property. This is the human-readable field_name from the custom field definition that the field is linked to. Previously, fields linked to custom field definitions only exposed variable_name, which contains the internal identifier (e.g. custom_template_a1b2c3d4-...). The new variable_defined_name returns the name you originally defined (e.g. artist_name), making it straightforward to map fields in your integration without cross-referencing the custom fields endpoint. Affected endpoints:
  • GET /templates (list and single)
  • GET /templates/{id}/fields
  • POST /templates/{id}/replace-document
  • GET /signing-requests (list)
  • GET /signing-requests/{id}/fields
  • GET /documents (legacy)
Example response:
For fields not linked to a custom field definition, variable_defined_name is null.

variable_defined_name as Input for Field Matching

When creating a signing request from a template via POST /signing-requests/create-and-send, you can now use variable_defined_name to target fields for overrides instead of the internal variable_name:
Both variable_name and variable_defined_name are accepted. variable_name takes precedence when both are provided.

No Breaking Changes

This is a non-breaking patch release. All existing API behavior is unchanged.

v01.12.00

Release Date: March 26, 2026
Download OpenAPI Spec

New Features

MCP Server Integration

Firma now supports the Model Context Protocol (MCP), allowing AI assistants like Claude to interact with the Firma API through natural language. The MCP server exposes Firma’s core API operations as tools that AI assistants can discover and call directly. Server URL: https://mcp.firma.dev/mcp Authentication:
  • API key authentication via the Authorization header
  • OAuth 2.1 with PKCE for browser-based clients (Claude.ai, Claude Desktop)
Available tool categories:
  • Workspaces — list, create, get, update
  • Templates — full CRUD, duplicate, view fields/users/reminders
  • Signing Requests — full CRUD, send, cancel, resend, audit trails
  • Webhooks — full CRUD, test delivery
  • Company — view and update company information
Transport: Streamable HTTP — compatible with Claude Code, Claude Desktop, Claude.ai, and any MCP client supporting the standard. See the MCP Integration guide for setup instructions and usage examples.

No Breaking Changes

This release adds no new API endpoints or schema changes. The OpenAPI specification is unchanged from v1.11.0.

v01.11.00

Release Date: March 19, 2026
Download OpenAPI Spec

New Features

File Upload Field Type

A new file field type allows signers to upload file attachments. Supported across signing requests and templates.
  • Signers can upload images (JPG, PNG) and/or PDF files depending on configuration
  • Files are validated by magic bytes, not just file extension
  • Maximum file size: 10MB
Configuration via format_rules:

Anchor Tags for Automatic Field Placement

A new anchor_tags array on signing request creation enables automatic field placement using text markers embedded in PDF documents (e.g., {{SIGN_HERE}}). The anchor text is removed from the PDF after processing by default.
  • Up to 100 anchor tags per request
  • Only available for document-based creation (not template-based)
  • Fields created from anchor tags are added alongside any manually specified fields
Key properties: Example:

Field Background Color

All field types now support a background_color property — a hex color string (e.g., #FFFDE7, #fff) useful for highlighting fields that need attention. Available on both standard fields and anchor tag definitions.

Schema Changes

New Schemas

Field / TemplateField / SigningRequestField

Field Type Enum

  • Added file to the list of accepted field types

format_rules

  • Now accepts FileFormatRules (with acceptedFileTypes) in addition to DateFormatRules and URL display text

Signing Request Creation

Breaking Changes

use_signing_order Default Changed

The use_signing_order setting default has changed from false to true. This means new signing requests will enforce signing order by default. When true, signers receive the document in sequence based on their order field. Set use_signing_order: false explicitly to preserve the previous behavior where all signers receive the document simultaneously.

Migration Guide

If you rely on the previous behavior where all signers receive documents simultaneously, explicitly set use_signing_order: false when creating signing requests. Review any integration code that creates signing requests without specifying this field.

v01.10.00

Release Date: March 10, 2026
Download OpenAPI Spec

New Features

Conditional Field Logic

Fields now support conditional rules for both required status and visibility. Two new nullable properties are available on field objects:
  • required_conditions — 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 — When set, the field is hidden unless the conditions evaluate to true. Hidden fields are not validated on submission.
Conditions use a nested group structure with logical operators: Supported operators: is_filled, is_empty, equals, not_equals, contains, not_contains, greater_than, less_than, greater_than_or_equal, less_than_or_equal Example — Make a field required only when another field is filled:

DOCX Document Support

All document upload endpoints now accept DOCX files in addition to PDF. DOCX files are automatically converted to PDF on upload. This applies to:
  • Template creation (POST /templates)
  • Template document replacement (POST /templates/{id}/replace-document)
  • Signing request creation (POST /signing-requests)
  • Template/signing request updates (PUT and PATCH)

Audit Trail Endpoint

A new endpoint retrieves 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. Endpoint: GET /signing-requests/{id}/audit Response fields:

Signature Frame Control

A new show_signature_frame setting controls whether a visual frame with Signature ID is rendered around signatures in completed PDFs. Available at company, workspace, and signing request levels. Values:
  • true — Show signature frame with Signature ID
  • false — Hide signature frame
  • null — Inherit from parent level

Force Remove Conditions on User Deletion

When deleting recipients whose fields are referenced by conditions in other fields, a new force_remove_conditions boolean parameter controls behavior:
  • false (default) — The request is rejected with an error listing the dependent fields
  • true — Automatically removes the condition references and proceeds with deletion
This applies to both template and signing request user deletion operations.

Schema Changes

Field

New Schemas

SigningRequestSettings / WorkspaceSettings / Company

Template & Signing Request User Deletion

New Endpoints

Migration Guide

No breaking changes. All new features are additive:
  • Conditional field properties default to null (no conditions)
  • show_signature_frame defaults to null (inherit, which is enabled by default)
  • force_remove_conditions defaults to false (preserving existing rejection behavior)
  • DOCX support is transparent — existing PDF uploads continue to work unchanged
  • The audit trail endpoint is purely additive

v01.09.00

Release Date: March 5, 2026
Download OpenAPI Spec

New Features

OTP Email Verification

A new require_otp_verification setting allows you to require signers to verify their email address with a one-time code before accessing signing documents. This adds an extra layer of identity verification. Where it’s available: Values:
  • true — Require OTP verification before document access
  • false — Do not require OTP verification
  • null — Inherit from parent level (workspace → company, signing request → workspace)
Example — Enable OTP at workspace level:
This route was part of the historical release note. The current endpoint is PUT /workspace/{workspace_id}/settings. Example — Override for a specific signing request:

Replace Template Document

A new endpoint allows replacing a template’s PDF document while preserving all field placements. This is useful when you need to update a document (e.g., fixing a typo) without recreating all the field configurations. Endpoint: POST /templates/{id}/replace-document Requirements:
  • The replacement document must have the same page count as the original
  • Page dimensions must match within 1pt tolerance
  • Document must be provided as a base64-encoded PDF
Example:
Error cases:

Schema Changes

SigningRequestSettings

WorkspaceSettings

New Endpoints

Migration Guide

No breaking changes. The require_otp_verification field defaults to null (inherit), so existing behavior is unchanged. The replace document endpoint is purely additive.

v01.08.00

Release Date: March 3, 2026
Download OpenAPI Spec

New Features

Email Templates API

A new Email Templates endpoint group allows you to customize the notification emails sent during the signing process. Templates can be configured at both company and workspace levels, with workspace-level templates overriding company-level defaults. Supported email types: New endpoints: Template hierarchy: Workspace templates → Company templates → Built-in defaults. Templates support HTML bodies with placeholders like {{signing_link}}, {{signer_name}}, etc. A warning is returned if the body does not contain {{signing_link}}. Example:

Language Support

New language field added to both the Company and WorkspaceSettings schemas to support multi-language email templates.

Schema Changes

Timestamp Corrections

Timestamp field names have been corrected in the spec to match actual API responses:
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

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.

Signing Request Response Shapes

The monolithic SigningRequest schema has been split into endpoint-specific response shapes: 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

Webhook Schema

SendSigningRequestResponse (Corrected)

The spec now accurately reflects the actual response shape:

WorkspaceSettings


v01.07.00

Release Date: February 25, 2026
Download OpenAPI Spec

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: 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:

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:
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

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: 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):

Schema Changes

Field Type Normalization

Field type enums now accept both original and normalized forms across all schemas. The API normalizes inputs automatically: Affected schemas:

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

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: Example Response:
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

New Features

New Field Types

Three new field types have been added: 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:

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:
Example - Update existing field:

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:
  • template_user_id is the preferred method for matching
  • order remains available as a fallback

Schema Changes

Field Type Enum

Updated from:
To:

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

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

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:

v01.01.00

Download OpenAPI Spec

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:

v01.00.02

Download OpenAPI Spec

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
TemplateCustomField
SigningRequestCustomField

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

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