Skip to main content

Getting started & account

Yes. Your account’s main key is on the dashboard’s Dashboard page; each workspace’s own keys are on that workspace’s Info tab, and there’s no separate “Settings > API Keys” page. You can also fetch them via the API. Only the workspace Owner can generate or regenerate keys from the dashboard.See: API Authentication & JWT Tokens, Complete Setup Guide
No, Firma.dev doesn’t offer a separate trial period or sandbox account, and test mode doesn’t cost anything to use. Test-key requests are still subject to the normal API rate limits, same as live requests, and the embeddable editors and hosted signing page behave identically in test mode and live mode.See: API Authentication & JWT Tokens, Complete Setup Guide
No. Signing up is self-serve, with no contract and no sales demo required: create an account, accept the standard terms of service at signup, and get your API key from the dashboard. Pricing has no minimums, no contracts, and no monthly fees. You can integrate directly from the docs, the MCP server, or one of Firma.dev’s AI-coding-tool integration guides (Claude Code, Cursor, ChatGPT, and others) without ever talking to sales.
Firma.dev has three account roles: Owner, Admin, and View Only.
  • Owner: the only role that can manage billing, create, delete, or rename workspaces, and generate or regenerate API keys.
  • Owner and Admin: can both manage webhooks, custom domains, and workspace or company settings, invite or remove users (though an Admin can’t create or promote another Owner), and create signing requests.
  • View Only: can only read and copy existing data.
A few workspace toggle settings, like OTP verification or the signature frame display, are Owner-only on the backend. The UI doesn’t yet block Admin or View Only users from toggling them, so a non-Owner may see a “saved” confirmation even though the change didn’t apply. If a setting doesn’t seem to stick, have an Owner make the change.
By design, adding a team member creates their account immediately instead of sending an email invitation: the new user’s temporary password is shown once on screen at creation time, not emailed. Share that password with them so they can log in, then they’ll be prompted to set their own password on first login. If the temporary password is lost before it’s used, use Forgot password on the login page to reset it.
Change your login email from the My Profile dialog (open it from your avatar or “My Profile” in the sidebar); this triggers a standard email-change confirmation flow to the new address. The Account page’s Company Information tab also has an “Email” field, but that’s a separate company-level billing/notification contact address: changing it does not affect how you log in. Signing up with a different email always creates a separate account; Firma.dev has no self-serve way to merge accounts. To merge accounts or delete your account entirely, contact support.
You integrate through Firma.dev’s REST API, optionally paired with its embeddable editors. Firma.dev also provides a TypeScript SDK, and publishes step-by-step guides for platforms such as n8n, Supabase, and Lovable, beyond the AI coding-tool clients its MCP servers cover.See: Complete Setup Guide, Embeddable signing, MCP Integration
The API covers the full e-signature workflow, from creating a signing request to receiving a signed, sealed document. Fields can also be placed with anchor tags, with conditional and required-field rules, email OTP verification, and full control over every email Firma.dev sends. Completed documents are sealed as PAdES-B-LTA PDFs with a completion certificate, and each workspace isolates a customer’s branding, sending domains, and email templates.See: Sending a signing request, Webhooks, Audit Trail

Pricing & billing

One credit covers a single signing request, charged when you send it and never refunded afterward. One credit equals one signing request (envelope), regardless of how many signers or documents it contains. It’s deducted when the request is sent, right after the signing emails go out and before the request is marked sent, not when signers finish. Credits aren’t refunded if a signer declines or the request expires, and no credit is charged if send validation fails or the email itself fails to send.See: Complete Setup Guide
Firma.dev is pay-as-you-go, with no subscriptions, minimums, or seat fees. Credits don’t expire. Accounts created before Firma.dev’s most recent price change, or signed up through another customer’s referral code, keep that earlier, lower per-credit rate for the life of the account. A referral code doesn’t gate access (anyone can sign up freely), but it earns both parties bonus credits on the referred company’s first purchase.See: Complete Setup Guide
Download invoices from Account > Credits & Billing, and add your company details before checkout. Enter your company name, billing address, and VAT number in the Add tax number step of the Paddle checkout before you pay. To correct an already-issued invoice, email support@firma.dev with the invoice number, company name, billing address, and VAT ID. It’s reissued and shown via the same View link.See: Platform Updates: Invoice downloads
This is almost always caused by an ad blocker, privacy extension, or corporate network filter blocking Paddle’s checkout script from loading. Firma.dev surfaces this as “Failed to load payment system: Failed to load Paddle.js.” Try disabling the blocker for the site, or open the page in a private/incognito window or a different browser. If a purchase seems to have failed partway through, check Account > Credits & Billing > Transaction History to confirm whether it actually went through before retrying, so you don’t pay twice.
Yes, auto-recharge is available. Buy credits any time from Account > Credits & Billing, and turn on Auto-Recharge in that same tab to automatically purchase a set credit bundle whenever your balance drops below a threshold you choose. There are no volume-based discount tiers currently; every credit bundle is priced at your account’s standard per-credit rate regardless of how much you buy at once.See: Complete Setup Guide

Sending signing requests

POST /signing-requests only creates a draft. It never sends an email on its own, regardless of your settings.See: Sending a signing request: Create vs. create-and-send
The correct base URL is:
Append the resource path after it, e.g. .../signing-requests. 404s often come from two sources:
  • https://api.firma.dev/api/v1: a second, “Planned” server listed in the public OpenAPI spec for a future API shape, not a real endpoint, so a generated client pointed at it 404s on every call.
  • POST /signing-requests: the actual endpoint behind the “Create Signing Request” reference page, not a /create-signing-request route as the title might suggest.
See: Authentication: Code Examples
A valid payload has a recipients list and a fields list; each field points at a recipient and a position on the page.Each recipient needs first_name, email, and designation (Signer, Approver, or CC). last_name and order are optional.Each field needs:
  • type: one of the supported field types, which also include radio_buttons, text_area, url, file, and stamp.
  • page_number: the page the field appears on.
  • position: x, y, width, height as percentages of the page, not pixels.
  • recipient_id: the recipient the field belongs to.
To reference a recipient you haven’t created yet, give it a temporary id starting with temp_ (for example temp_alice) and set recipient_id on the field to the same value. The API maps it to a real UUID and never returns temp IDs.There’s no top-level metadata property. Use each recipient’s custom_fields object instead.See: Sending a signing request: Recipient Schema and Sending a signing request: Field types
The maximum document size is 50MB (52,428,800 bytes). Upload large files with the two-step process:
  • POST /documents: uploads the file and returns a presigned upload_url.
  • PUT: send the file to that upload_url.
  • document_id: pass this when you create the signing request.
Keep inline base64 in document under about 5MB, or the request can fail with a 502. The MCP server has no upload tool, so large files go through the REST API.
Yes, Firma.dev supports DOCX and converts it to PDF automatically on the server before the signing request is created.
  • POST /signing-requests: accepts a DOCX file when you create a signing request directly.
  • POST /documents: accepts a DOCX file when you upload a document separately.
That converter only renders text, headings, lists, and tables. It drops any images in the DOCX entirely, and it only loads a Latin/Cyrillic-style font set, so text in right-to-left scripts like Hebrew or Arabic can come out with missing glyphs or misrendered.If your document has images or non-Latin script you need preserved exactly, export it to PDF yourself first (e.g. LibreOffice, or Google Docs > File > Download > PDF) and send the PDF instead of the DOCX.
No. The write endpoints (create, create-and-send, send, resend) have no Idempotency-Key header.An auto-retried create or create-and-send call can create a duplicate, separately billed, legally binding signing request. Calling /send again on an already-sent request returns an error instead of duplicating.To avoid duplicates, store the id returned by the first call and check for it, or query existing requests, before retrying.See: n8n integration: Other common operations
No, you can’t edit a recipient’s email after sending. Cancel and recreate the request instead.You can cancel silently:
  • POST /signing-requests/{id}/cancel: the endpoint to call to cancel a request.
  • notify_signers: false: a parameter on that cancel call itself, not a creation-time setting, that suppresses the signer notification.
  • send_cancellation_email: a workspace setting that must also be enabled for a cancellation email to be sent at all.
See: Signing patterns: Error handling: 409 ALREADY_SENT
No, a signing request has exactly one source document.You provide exactly one of:
  • document: inline base64 content.
  • document_id: the ID returned from a POST request to /documents.
  • template_id: an existing template’s ID.
These are mutually exclusive, so to combine several files into one signer flow, merge them into a single PDF yourself before creating the request.For templates specifically, you don’t need to recreate a template to update its underlying file. POST to /templates/{id}/replace-document swaps a template’s PDF while preserving all existing field placements. The replacement must have the same page count and matching page dimensions (within 1pt) as the original, so it updates content on the existing layout rather than attaching an unrelated document.
GET /signing-requests/{id}/download returns the signed PDF as a pre-signed URL.It returns a single, short-lived pre-signed download_url, valid until the expires_at timestamp, for the final PDF. For a finished request, that one PDF already has the completion certificate and audit-trail pages appended to the signed document, and there’s no separate certificate-only download URL from this endpoint.Calling this endpoint behaves differently depending on the signing request’s state:
  • 409: returned if you call it before the request has been sent.
  • allow_partial_download: when enabled, lets you get a partial-progress snapshot while signing is still in progress.
  • 503: returned with a Retry-After header while a partial-progress snapshot is still being generated.
Yes, you can retrieve a signer’s signature image and any files they uploaded through the API.
  • GET /signing-requests/{id}/signers/{signer_id}/signature: returns the adopted signature as a data:image/png;base64,... data URI.
  • GET /signing-requests/{id}/signers/{signer_id}/initials: returns the adopted initials the same way.
  • GET /signing-requests/{id}/signers/{signer_id}/stamps/{field_id}: returns a stamp image for the given field_id, since stamps are per-field.
  • GET /signing-requests/{id}/signers/{signer_id}/files/{field_id}: returns a pre-signed download URL, valid for 300 seconds, for a file uploaded to a file-type field, not the file bytes directly.
  • GET /signing-requests/{id}/fields: filter to type=file to find the field_id for an uploaded file.
Uploaded files are never embedded into the final signed PDF or certificate; they only exist as retrievable attachments through these endpoints.
GET /signing-requests/{id}/fields returns every field of the request; read each entry’s value property for the resolved value and match on variable_name.See: Field Prefilling: Reading field values back

Templates / fields / anchor tags

x, y, width, and height are percentages of the page, not pixels. The origin is the top-left corner and y grows downward.A manually specified field returns a 400 error when x+width>100 or y+height>100. Fields placed by anchor tags are clamped back onto the page instead.
Place literal marker text in the document and pass an anchor_tags array on a document-based create request, up to 100 tags per request.Anchor tags accept every field type, and also dropdown_options, format_rules, multi_group_id, and conditions.
remove_anchor_text makes the matched text invisible in the PDF’s content stream rather than deleted.It can fail on embedded/subset (CID) fonts or when the marker text is split across separate PDF text-show operators. When that happens, the system automatically draws a white box over only the matched marker area, even without add_white_background set.
This error means the anchor marker’s text sat inside a PDF Form XObject or transparency group that was not replayed when reading glyph positions.This typically happens in HTML-to-PDF documents, where a Chromium print pipeline wraps an element with CSS opacity below 1, or a transform, inside a transparency-group Form XObject.The extractor replays text inside form and group contexts (annotation appearance streams excluded), so anchors placed there are found.If it recurs, the anchor is likely in a malformed or unusual font/geometry construct. Re-export the source PDF with standard font encoding.
Set format_rules.prefilledData on a field to auto-fill and lock it from recipient data.The signer can still edit the value if you also set format_rules.prefilledEditable to true.This works the same way on anchor-tag-placed fields, since anchor tags accept format_rules too.
Text fields automatically shrink to fit the field’s box when a value overflows, down to a default floor of 8px.Set format_rules.fontSize for an explicit starting size instead. If text is still cut off, enlarge the field or switch to a textarea.
Assign the same multi_group_id to a set of fields to link them into a group.
  • radio_buttons: fields sharing a multi_group_id form a mutually-exclusive group.
  • checkbox: fields sharing a multi_group_id form an independent group.
A selected radio option’s stored value is the literal string "true".A checkbox field renders as a native checkbox input, not a custom checkmark icon.
visibility_conditions and required_conditions are ConditionSet objects on a field that reference another field’s field_id on the same recipient.
  • GET /templates/{id}/fields: returns both properties, even though the public OpenAPI schema omits them.
When you create a signing request from a template (two-step flow, create-and-send, or /duplicate), both condition sets are copied and their field_id references remapped.
Add each field individually; there is no bulk option to place a field on every page.For initials on every page, add one initial field per page in the fields array, each with its own page_number. A single recipient can have multiple required fields of the same type, including several signature fields.
Use a date field to auto-fill the signing date.The field renders read-only in the signing view and fills with the signer’s browser-local date when they finish, not a server timezone.
  • date_signing_default: true: enables auto-fill; there’s no separate date_signed type.
  • timezone: the workspace setting checked first for certificate timestamps, defaulting to UTC until you set it.
  • default_timezone: the company-level fallback checked next, also defaulting to UTC until you set it.
No, templates aren’t shared across workspaces, not even within the same company.
  • POST /templates/{id}/copy: deep-copies the template’s fields, recipients, CC list, reminders, custom field definitions, and document into another workspace, using a company-level (protected) API key.
  • workspace_id: the target workspace you pass in the request body.
  • POST /templates/{id}/duplicate: creates a new signing request from the template instead, not a copy of the template.

Signing experience

Yes, you can redirect the signer or customize the completion page after signing.
  • completion_redirect_url: redirects the signer after they finish signing.
  • completion_title: customizes the completion page title, set alongside the redirect URL.
  • completion_message: customizes the completion page message, set alongside the redirect URL.
  • signing.completed: the event to listen for instead, if you embed the signing view.
See: Completion page customization (API changelog v1.34.0) and Embeddable signing - postMessage events
You can rename signing buttons, but not hide them or the language selector.Relabel button text per language with signing_button_label_overrides, covering Finish, Approve & Finish, Next Required Field, Save & Finish Later, and the Decline dialog. The Decline button, the Save & Finish Later button, and the language selector always render and can’t be hidden.disable_guided_navigation turns off auto-scroll to the next field, shown in the dashboard as “Disable Auto-Scroll”.See: Workspace settings
Yes, you can both disable it and customize its text. The terms-acceptance gate can be turned on or off per workspace, or at the company level as the default. It’s on by default. The consent banner text and its linked terms page are fully customizable per language from Workspace/Company Settings > Terms, for each of the 14 supported languages. Anything you don’t set falls back first to your company’s custom text, then to Firma.dev’s own built-in terms banner, which is already localized into all 14 languages.See: Legal validity
Signers can draw or type their signature, you can require hand-drawn signatures, and Cyrillic is supported.Typing auto-detects the signer’s script (Latin, Cyrillic, Greek, Japanese, Korean) from their name and offers matching font styles; there’s no separate upload-an-image option. Set hand_drawn_only to true on the signing request or template to remove the Type tab and require drawing.Firma.dev does not support signer-supplied X.509 certificates; it applies its own PAdES seal to the completed document server-side.See: Signing patterns
Ask the signer to hard-refresh the page. If that doesn’t help, open the link in a recent Chrome, Firefox, or Safari with content and ad blockers disabled, since blockers can interfere with the signing page’s scripts. On iOS Safari, make sure iOS and Safari are up to date and retry; older versions could run out of memory on very large or high-resolution PDFs.
Yes, add ?zoom= to the signing URL.See: Embeddable signing - URL parameters
No to both. There’s no built-in ‘either-signer’ mode; your application must decide who specifically signs before creating the request. There’s also no unattended or automatic signing on your own company’s behalf; every signer, including someone on your team, must open their link and complete the signing flow.See: Signing patterns - Pattern: Parallel signing
Turn on QR Code on Signing Page in Workspace Settings to enable QR-code signing on a phone.This sets show_qr_code to true. Add the {{signing_qr_code}} placeholder to your email templates so the QR code appears.See: Workspace settings - QR code in emails

Identity verification (OTP)

You can set the OTP email’s language per request, but not its wording. Set language on the signing request itself to override the workspace and company defaults for that request’s signer-facing emails, including the OTP email. Custom email templates can’t change the OTP email’s wording, but you can skip OTP entirely per request by setting settings.require_otp_verification to false.See: Localization, White-Labeling
No. Firma.dev currently supports only email-based OTP for signer identity verification; there’s no SMS OTP or national eID (BankID, MitID, FranceConnect, or similar) integration. Email OTP is included at no extra cost in Firma.dev’s flat per-envelope pricing. This isn’t stated anywhere as a near-term roadmap item, so treat it as not currently supported rather than something planned.

Webhooks

This usually means the account-level webhook switch is off, even though the workspace shows enabled with zero failures.Turn it on under Settings > Webhooks, or through the API:
  • PATCH /workspaces/{id}: set webhook_enabled to true in the body to enable webhooks without the dashboard.
  • ignore_company_webhooks: make sure this isn’t true on the workspace; it silently opts the workspace out of company webhooks.
The dashboard test button bypasses the master switch, which is why tests succeed while real events are skipped with zero failures.See: Webhooks
Company- and workspace-level webhooks differ in their signing secrets, opt-out behavior, and how the viewed event fires.
  • Secrets: company- and workspace-level webhooks each have their own signing secret.
  • ignore_company_webhooks: lets a workspace opt out of its company’s webhooks entirely, without affecting other workspaces.
  • signing_request.viewed: fires only on a recipient’s first view, not on every subsequent open.
See: Webhooks, Webhooks, Webhooks
Firma.dev does not follow HTTP redirects when delivering webhooks; this is deliberate SSRF protection, so a redirecting endpoint fails delivery outright. Register the exact URL your server serves; a mismatch in scheme, a www subdomain, the path, or a missing or extra trailing slash fails every delivery attempt.See: Webhooks
Your endpoint must answer with a 2xx within 5 seconds; failed deliveries are retried automatically, and the endpoint is disabled after 50 consecutive failures. You can retry a single event from the dashboard event log, but there is no bulk resend, and events from before the webhook existed are never backfilled.See: Webhooks
No, use webhooks instead of polling for status changes.
  • GET /signing-requests/{id}: don’t poll this endpoint for status; webhooks push updates instead.
See: Rate Limits, Webhooks

Email delivery & templates

RECIPIENT_EMAIL_SUPPRESSED (HTTP 422) means the recipient is on Firma.dev’s suppression list; contact support to get an address unblocked.See: Email Deliverability, Requesting removal
The sender name comes from the workspace name, falling back to the company name. The address uses your verified sending domain; set its local part with email_local_part at the company or workspace level.See: Custom email sender address
Control these through the signing request’s settings object:
  • send_finish_email: false: stops the completion email.
  • attach_pdf_on_finish: false: sends a download link instead of attaching the PDF.
  • document_only_download_url: shares the document without the certificate, instead of final_document_download_url.
  • certificate_only_download_url: returns the certificate on its own.
  • allow_download: false: disables download links entirely, as a separate control from attach_pdf_on_finish.
CC recipients receive the completed document as an email attachment under the same settings as the signer’s copy.See: Disabling Firma.dev emails
Custom templates use {{placeholder}} syntax.Legacy [bracket] syntax also works and is case-insensitive; an unresolved placeholder renders as nothing, not raw text.
  • {{team_name}}: an alias of {{workspace_name}}.
  • {{team_email}}: an alias of {{workspace_email}}.
  • {{download_link}}: resolves only in completion emails.
No, templates don’t vary by language: one template applies to every recipient, so per-language branded templates need a separate workspace each. There’s no live preview or custom per-request variables.See: Custom email templates
Yes, through the API; the setting isn’t exposed in the dashboard yet.
  • timezone: an IANA timezone set on the workspace through the settings API.
  • default_timezone: the company-level fallback when the workspace timezone isn’t set.
Placeholders such as {{expiration_date}} in signing emails use that timezone and the email’s language. UTC remains the default when neither is set.See: Supported timezones
Language resolves per signing request first, then workspace, then company.A company or workspace created through the API defaults to en unless you set language explicitly. Set it on the workspace, or pass language on the request, and new signer emails will use it.See: Email language settings

Custom sending domains

Setting up a custom sending domain requires a few DNS records added in two stages: one to verify ownership, then a few more to finalize. No MX record is needed at any step, since Firma.dev only sends mail through the domain and never receives it.See: DNS records you’ll need
A ‘Domain Conflict’ status (or a stuck ‘Configuring’) means the domain is already registered under a different Resend account, often your own; the fix is a dedicated subdomain like sign.yourcompany.com, which verifies independently. Removing the domain from Firma.dev releases Firma.dev’s own registration for reuse elsewhere, but has no effect on a registration in someone else’s Resend account.See: Already using Resend for your own email?
Call verify-dns again; it checks live every time, so a transient hiccup can report the domain as unverified even when the DNS is correct.See: Verification states, Known display quirk
A verified domain moves to ‘Failed’ when its DNS records stop checking out. Firma.dev only marks it invalid after two consecutive failed background checks, not the first blip, to avoid flapping on a transient hiccup. While a domain is failed or not yet verified, Firma.dev automatically sends from its own default domain instead of yours.See: Verified domain later shows Failed
Yes, add and verify the domain separately in each workspace where you want to use it.See: Custom Domains, Custom email domains
Firma.dev provides an Advanced Electronic Signature (AES) under eIDAS Art. 3(11)/26, meeting the eIDAS admissibility floor and ESIGN Act/UETA requirements for most contracts; Firma.dev is not a Qualified Trust Service Provider and doesn’t issue Qualified Electronic Signatures. The seal itself is PAdES-B-LTA (Baseline Long-Term Archival), issued from Firma.dev’s own certificate authority, with an embedded RFC 3161 timestamp.See: Legal Validity & eIDAS Compliance
Firma.dev’s digital seal is issued by Firma.dev’s own certificate authority, not one chaining to Adobe’s Approved Trust List (AATL) or the EU Trusted List (EUTL), so Acrobat and similar viewers won’t show the automatic green checkmark; the seal itself is still fully valid. Verify it in your PDF viewer’s signature panel, or independently at app.firma.dev/validate-signature.See: Why there’s no green checkmark in Adobe Acrobat
Your data stays entirely within the EU, and Firma.dev is not SOC 2 or ISO 27001 certified, though its practices align with both frameworks.See: Security & Compliance
You can delete an unsent (draft) signing request at any time, from the dashboard or via the API:
Once a request has been sent it can no longer be deleted, only cancelled. A completed, signed document is a legal record: the data a signer captured is never modified after signing, and there is no self-serve endpoint for removing a single signer’s data from it. If you need a completed signing request removed to satisfy a data-protection request, contact support@firma.dev.
The completion certificate is generated in your workspace’s configured language, not the individual signer’s language or a signing-request-level override, and yes, it can show your logo. It uses a fallback chain: workspace logo, then company logo, then Firma.dev’s default logo, and it prints the workspace’s own name. Certificate timestamps use the workspace’s configured timezone, falling back to UTC if none is set.
No. Firma.dev applies its PAdES-B-LTA seal once, at signing time, and never re-stamps or renews it afterward; for very long retention windows, apply your own re-timestamping when you archive the file. If a signature is challenged, signer-identity, consent, and record-keeping responsibilities are set out in Firma.dev’s Terms of Service.See: Legal Validity: What Firma.dev provides, Audit Trail
No, you can’t remove the Signing Request ID header from the signed PDF.Signing Request ID: <id> is drawn on every page of the signed PDF and completion certificate, in small gray text near the top margin; there is no workspace or API setting to turn it off.The header is drawn with an embedded font, so sealed documents pass PDF/A-2b validation.
Firma.dev is suitable for most French use cases under eIDAS and GDPR, but not for HDS-regulated health data: Firma.dev does not hold an HDS (French health-data hosting) certification. Signatures are sealed as PAdES-B-LTA. For GDPR, Firma.dev acts as the data processor; a Data Processing Agreement is available on request from support@firma.dev.See: Security, Legal Validity & eIDAS Compliance

Workspaces & multi-tenant

Yes, giving each end customer their own workspace is Firma.dev’s recommended default for multi-tenant platforms; data in one workspace is never visible from another. There’s no limit on how many workspaces you can create under one company, and no extra cost per workspace.See: Multi-Tenant Architecture, Workspaces
Every company gets exactly one default workspace, created automatically at signup and flagged protected.It’s meant to be managed from the dashboard rather than the API; calling a management endpoint against it with a regular API key returns a 403 with code PROTECTED_WORKSPACE.For account-wide settings, use:
This endpoint accepts default_timezone and language, among other fields. For anything you need to manage directly via the API, create separate, non-protected workspaces instead.See: Workspaces: Edge cases & troubleshooting, Workspace Settings: Update workspace settings

White-labeling & embedding

You can white-label signing-request emails, signer terms-acceptance text, and the signing page and embeds, but api.firma.dev itself can’t be proxied under your own domain, only the email-sending domain is customizable. The completion certificate can also be white-labeled, with your logo replacing Firma.dev’s. show_custom_branding_only only strips Firma.dev’s support contact line from emails; it doesn’t remove Firma.dev’s presence from the signing page itself.
Set workspace colors and a logo with these two endpoints:
These settings apply across the signing page, embeds, and signing emails.See: White Labeling
Set initialZoom to control the embedded template editor’s initial zoom directly.autoFit (boolean) is the alternative; initialZoom (number) takes precedence when both are set. Every document canvas supports panning via middle-mouse-button drag, leaving left-click free for field interaction.Signed document URLs expire after 1 hour. The embedded template editor auto-requests a fresh URL and retries up to 3 times instead of failing.If downloads are blocked, check for a sandbox attribute on your own page; Firma.dev’s embed examples don’t set one.See: Embeddable template editor
Neither is currently supported. Firma.dev’s embeds (the template editor, signing-request editor, and the signing page) don’t accept custom CSS, and there’s no option to render only a signature field instead of the full document. If this is blocking your integration, share the use case with Firma.dev support.

Tools / SDKs / limits

Firma.dev provides two MCP servers, the Data MCP for account access and the Docs MCP for documentation lookup; most developers connect both.See: MCP Integration
Firma.dev offers one official SDK, the TypeScript client @firma-dev/sdk, generated from the same OpenAPI spec as the API reference:
There’s no official Python SDK and no published roadmap commitment for one; call the REST API directly, for example with the requests library.See: TypeScript SDK for the Firma.dev API
Rate limits are enforced per API key and vary depending on which operation you’re calling.See: Rate Limits
This client-side error means your browser’s request to an edge function never reached the server:
It comes from Supabase’s JS SDK, for example due to an ad blocker, DNS filter, offline connection, or CORS block; it’s a different error class than a genuine error response from the function itself.On Firma.dev’s signing page, this most commonly comes from a background analytics call, which fails silently and doesn’t affect your ability to view or sign the document.If it’s happening on a call that’s actually blocking your integration rather than analytics, check your network conditions before treating it as a Firma.dev-side error.

For signers (received a document)

By default, everyone on the signing request, including CC’d recipients, is emailed a copy of the completed document once every signer has finished, not immediately after you personally sign. The email attaches the PDF automatically when it’s under 8MB; larger files come as a download link instead. There’s no signer login or dashboard to retrieve past documents yourself, so if you need a copy before everyone else has finished, ask the person who sent it to you (named in your invitation email).