Guides & Tutorials

White-Label Every Email: How Firma.dev's Custom Email Templates Work

Alt text: "Announcement graphic stating 'Firma.dev Now Speaks Greek' with two icons below: a colorful abstract design and a Greek flag, on a dark background."

When you embed e-signatures into your product, your customers shouldn't know which platform is powering it. The signing experience should feel like yours, including every automated email that goes out during the process. Firma.dev now lets you customize every notification email the platform sends on your behalf, with full control over subject lines, HTML bodies, and per-workspace overrides.

Your Customers See Your Brand, Not Ours

Every signing workflow triggers a series of automated emails: the initial invite, the next-signer notification in a sequential flow, expiry notices, cancellation messages, and decline notifications. Before custom email templates, those all went out with Firma.dev's default copy and formatting.

Now you control all five:

Email Type

When It Sends

signing_invite

When a signing request is first sent to a recipient

next_signer

When it's the next signer's turn in a signing order

signing_expired

When a signing request expires

signing_cancelled

When a sender cancels a signing request

signing_declined

When a signer declines to sign

Both the subject line (plain text, max 500 characters) and the body (HTML, max 50,000 characters) are fully customizable for each type. You can match your brand's tone, layout, colors, and copy exactly.

Dynamic Placeholders

Templates support a {{placeholder}} syntax for injecting live values at send time. The full list of available placeholders is discoverable via GET /email-templates/placeholders, and includes the ones you'll use most:

  • {{signing_link}} — the signer's unique link to access the document

  • {{signer_name}} — the recipient's name

  • {{document_name}} — the name of the signing request

A practical example of a signing_invite body:

<p>Hi {{signer_name}},</p>
<p>
  {{sender_name}} has sent you a document to review and sign.
  Please use the link below to access it.
</p>
<p>
  <a href="{{signing_link}}" style="background:#1a1a1a;color:#fff;padding:12px 24px;border-radius:4px;text-decoration:none;">
    Review and Sign
  </a>
</p>
<p>This link expires in {{expiration_hours}} hours.</p>
<p>The {{company_name}} Team</p>
<p>Hi {{signer_name}},</p>
<p>
  {{sender_name}} has sent you a document to review and sign.
  Please use the link below to access it.
</p>
<p>
  <a href="{{signing_link}}" style="background:#1a1a1a;color:#fff;padding:12px 24px;border-radius:4px;text-decoration:none;">
    Review and Sign
  </a>
</p>
<p>This link expires in {{expiration_hours}} hours.</p>
<p>The {{company_name}} Team</p>
<p>Hi {{signer_name}},</p>
<p>
  {{sender_name}} has sent you a document to review and sign.
  Please use the link below to access it.
</p>
<p>
  <a href="{{signing_link}}" style="background:#1a1a1a;color:#fff;padding:12px 24px;border-radius:4px;text-decoration:none;">
    Review and Sign
  </a>
</p>
<p>This link expires in {{expiration_hours}} hours.</p>
<p>The {{company_name}} Team</p>

One developer note: if your template body doesn't include {{signing_link}}, the API returns a warning on save. The save still succeeds, but the warning is there to catch the mistake before a signer receives an email with no way to access their document.

Company-Level and Workspace-Level Templates

The template system uses a three-tier hierarchy: workspace template takes precedence, then company template, then Firma.dev's built-in default. This gives you two natural integration patterns.

Setting a Company-Wide Default

Set your branded template once at the company level and it applies to every workspace that doesn't have its own override. The endpoint pattern from the API changelog:

PUT /company/email-templates/{email_type}
{
  "subject": "Please sign: {{document_name}}",
  "body": "<p>Hi {{signer_name}},</p><p>Please review and sign using this link: {{signing_link}}</p>"
}
PUT /company/email-templates/{email_type}
{
  "subject": "Please sign: {{document_name}}",
  "body": "<p>Hi {{signer_name}},</p><p>Please review and sign using this link: {{signing_link}}</p>"
}
PUT /company/email-templates/{email_type}
{
  "subject": "Please sign: {{document_name}}",
  "body": "<p>Hi {{signer_name}},</p><p>Please review and sign using this link: {{signing_link}}</p>"
}

Overriding Per Workspace

For partners using Firma.dev's customer workspace model, each workspace can carry its own email templates. This curl example is from the white-labeling guide:

curl -X PUT https://api.firma.dev/functions/v1/signing-request-api/workspace/{workspace_id}/email-templates/signing_invite \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Action required: Please sign {{document_name}}",
    "body": "<p>Hi {{signer_name}},</p><p>{{sender_name}} has requested your signature on {{document_name}}.</p><p><a href=\"{{signing_link}}\">Sign now</a></p><p>— The {{workspace_name}} Team</p>"
  }'
curl -X PUT https://api.firma.dev/functions/v1/signing-request-api/workspace/{workspace_id}/email-templates/signing_invite \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Action required: Please sign {{document_name}}",
    "body": "<p>Hi {{signer_name}},</p><p>{{sender_name}} has requested your signature on {{document_name}}.</p><p><a href=\"{{signing_link}}\">Sign now</a></p><p>— The {{workspace_name}} Team</p>"
  }'
curl -X PUT https://api.firma.dev/functions/v1/signing-request-api/workspace/{workspace_id}/email-templates/signing_invite \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Action required: Please sign {{document_name}}",
    "body": "<p>Hi {{signer_name}},</p><p>{{sender_name}} has requested your signature on {{document_name}}.</p><p><a href=\"{{signing_link}}\">Sign now</a></p><p>— The {{workspace_name}} Team</p>"
  }'

A workspace serving customers in Germany might use German-language templates with that customer's specific branding, while another workspace uses your company-wide defaults.

Deleting a workspace template reverts that workspace to the company-level default. Deleting the company template reverts to Firma.dev's built-in default. The fallback chain always has something to land on.

Full API Reference

Endpoint

Description

GET /company/email-templates

List all company-level templates

PUT /company/email-templates/{email_type}

Create or update a company template

DELETE /company/email-templates/{email_type}

Delete a company template

GET /workspace/{id}/email-templates

List all workspace templates

GET /workspace/{id}/email-templates/{email_type}

Get a specific workspace template

PUT /workspace/{id}/email-templates/{email_type}

Create or update a workspace template

DELETE /workspace/{id}/email-templates/{email_type}

Delete a workspace template

GET /email-templates/defaults/{language}

Get built-in defaults for a language

GET /email-templates/placeholders

Get all available placeholders

The GET /email-templates/defaults/{language} endpoint is particularly useful as a starting point: pull the built-in template for your target language, customize it, and save it back. No need to write email copy from scratch.

Getting Started

Custom email templates are available from API v1.8.0 onward with no breaking changes. If you're already integrated, you can start customizing emails today without touching any existing signing request logic.

Get started with Firma.dev for free, no credit card required. All signing requests are 0.029 per envelope, no monthly minimums.

  1. Heading

Background Image

Ready to add e-signatures to your application?

Get started for free. No credit card required. Pay only €0.029 per envelope when you're ready to go live.

Background Image

Ready to add e-signatures to your application?

Get started for free. No credit card required. Pay only €0.029 per envelope when you're ready to go live.

Background Image

Ready to add e-signatures to your application?

Get started for free. No credit card required. Pay only €0.029 per envelope when you're ready to go live.