Digital transformation

How to Embed E-Signatures in Your App with Anvil's Etch API

Mang-Git Ng
By Mang-Git Ng

A developer-focused how-to guide for SaaS builders who need to add embedded e-signature functionality to their product. The guide targets the specific intent of "I'm building a SaaS product and need to embed e-signature functionality – what API makes it easy to add signing without building from scratch?" It is distinct from the existing document automation evaluation guide, which covers webhook depth, audit trail schemas, and sandbox bakeoffs. This piece focuses on the SaaS product integration pattern: how to go from zero to embedded signing inside your app.

Etch E-sign
Back to all articles
Post hero image

TL;DR

  • Anvil's Etch API fills PDF fields and collects e-signatures in a single createEtchPacket call, so you skip the separate prefill step most providers require.
  • Setting signerType: "embedded" hands you control of the sign link, which you drop into an iframe or the AnvilEmbedFrame React component.
  • Your app tracks progress through signerLoad, signerComplete, and signerError postMessage events, then pulls the finished PDF when signing completes.
  • The Product plan charges a flat rate with no per-envelope fees, and the sandbox runs full webhook and iframe behavior for free.
  • Anvil is SOC 2 certified and built to support HIPAA, GDPR, and eIDAS compliance requirements, and supports white-label signing down to custom CSS injection.

Why Embedding Signatures Directly in Your SaaS App Matters

When you redirect a customer to DocuSign or Dropbox Sign to complete a signature, you hand them off to a separate vendor at the exact moment they're committing to yours. That handoff trains customers to see signing as a separate product they could buy elsewhere, which weakens the case for charging for it inside your own app. White-label embedded signing keeps the entire flow inside your interface, so signing reads as a native feature rather than a bolted-on integration.

One B2B HR SaaS company cut contract turnaround by 68% – from 4.2 days to 1.4 days – after embedding signing through an API, and pushed completion rates from 88% to 97% (as reported by WeSignature's analysis of e-signature SaaS applications). Embedded signing also drops the cost per document from the $6–$8 range for paper to under $1 at scale.

Every redirect also means managing return URLs, session state, and inconsistent branding across two products. Embedding the signing UI removes that overhead and gives you one surface to design, test, and own.

E-Signature APIs for SaaS Embedding: A Quick Comparison

Most e-signature APIs treat embedded signing and PDF prefill as separate, often paywalled features. Anvil fills the PDF and collects signatures in one call and ships embedded signing without per-envelope billing. The table below maps how each provider handles the four decisions that matter when you embed signing inside a SaaS product.

Provider

Embedded signing

PDF fill + sign in one API

Pricing model

White-label

SDK languages

Anvil

Yes, via signerType: "embedded"

Yes, data.payloads fills fields in the same createEtchPacket call

Flat Product plan, no per-envelope charges

Full, including custom CSS injection

Node.js, Python

DocuSign

Yes, but custom mobile and workflow experiences need higher tiers

Not documented in developer pricing

Per-envelope, billed even on uncompleted packets

Custom signing only on higher tiers

Not enumerated in sources

Dropbox Sign

Yes, requires the Standard API plan

No PDF prefill or document generation

Tiered monthly, no free production tier

Plan-dependent; some branding needs Standard or Premium

SDKs documented, languages not itemized

PandaDoc

Yes, "limited embedded editor & signing" at entry tier

Document generation included, single-call fill + sign not confirmed

Per-document, $4 per doc beyond plan allotment

Branding available, full controls need Enterprise

SDKs documented

SignWell

Yes, via iframe with "limited style control"

No PDF fill or document generation

Pay-as-you-go after 25 free monthly docs

Basic branding on paid plans, no full white-label

Not enumerated in sources

DocuSign and Dropbox Sign fit teams already standardized on those platforms, but they gate the embedded and white-label features SaaS builders need behind higher tiers, and DocuSign charges per envelope even when a packet is never completed (see Anvil's comparison of DocuSign API alternatives). Dropbox Sign and SignWell skip PDF prefill entirely, so you fill documents yourself before the API ever sees them. Among the options in this table, Anvil is the only one that handles prefill and signing in a single request and keeps embedded signing off a metered envelope count.

How Anvil's Etch API Works: The Integration Pattern

The Etch API moves a document from template to signed PDF in six stages. You create a PDF template and grab its castEid, then call createEtchPacket to fill fields and create the signing packet in one API call – most APIs split that into two separate requests. You set each signer's signerType to "embedded" so your code controls the routing instead of Anvil emailing them. You call generateEtchSignUrl to mint a short-lived signing URL, load it into an iframe or AnvilEmbedFrame, and listen for postMessage events to know when the signer finishes. The signed PDF is ready to pull the moment signerComplete fires.

Step 1: Create a PDF Template in Anvil

Every signature packet starts with a PDF, and Anvil gives you four ways to supply one. The fastest path uploads your PDF in the Anvil dashboard, where you drag fillable fields onto the page and tag where each signer signs. Once you save the template, Anvil assigns it a castEid. Copy that value, since your API call references it to know which document to fill and route for signing.

You aren't locked into a dashboard-built template. The files array in your createEtchPacket call accepts four input types, so you can pick whatever fits your build:

  • Existing template: reference a dashboard template by its castEid.
  • Binary upload: pass a raw PDF as Base64, a binary blob, or a URL Anvil fetches.
  • HTML and CSS: send a markup object and Anvil renders a PDF from your markup.
  • Markdown: generate a PDF from markdown when you want lightweight, code-driven documents.

The dashboard template suits documents with a fixed layout, like a standard NDA or an order form. The HTML and CSS path fits documents you generate programmatically, where the content changes per customer and you'd rather build the PDF in code than maintain a static template.

Start with a dashboard template and note its castEid – you'll pass that into createEtchPacket in the next step. The e-signature API docs cover all four files input types in full.

Step 2: Build the Signature Packet with createEtchPacket

The createEtchPacket mutation creates and sends a signature packet in one GraphQL call, filling your PDF fields and preparing the document for signing at the same time. Most APIs split this into a prefill request and a separate send request, but Anvil collapses both into a single round trip, so the field values you pass in data.payloads land on the document before any signer ever opens it.

Node.js, using the official SDK:

Python:

isDraft: false sends the packet immediately; isDraft: true holds it for later edits. isTest: true marks it as a sandbox run – the full signing flow and iframe behavior work normally, but the document is watermarked and doesn't count against your quota. Flip it to false for production.

The routingOrder field decides signing sequence. A 1-based integer assigns each signer a position, and higher numbers wait until lower ones finish. Give two signers the same routingOrder value to let them sign in any order. Unordered signing requires the Product pack or Enterprise plan, so confirm your plan before relying on it. The full parameter reference lives in Anvil's e-signature API docs.

Step 3: Set signerType to "embedded"

To embed the signing UI inside your own app, set signerType: "embedded" on each signer object in the packet. With this value, Anvil sends no email to the signer, and you control how the signer reaches the signing page. You generate a sign URL and route the user to it yourself, which is what makes the in-app, white-label experience possible.

The email field stays required even for embedded signers. Anvil uses it to record who signed and to attach the address to the audit trail, so a valid address still matters even though no notification goes out.

The default is signerType: "email", where Anvil handles the entire notification flow. It emails the signer a link, sends reminders, and manages the redirect after signing. That path takes less work to wire up, but the signer leaves your product to sign on an Anvil-hosted page. Pick "email" when you want Anvil to orchestrate everything, and pick "embedded" when you want the signing screen to live inside your app and your code to own the routing. A third option, signerType: "in-person", supports kiosk-style signing and is available by contacting Anvil sales.

Step 4: Generate the Sign URL with generateEtchSignUrl

With the packet created and a signer set to embedded, call generateEtchSignUrl to mint the link that loads the signing page. The call takes the signer's eid from the packet response and a clientUserId that ties the session to a user in your own system. In Node.js, it returns a single url you hand to your front end.

Python:

The clientUserId matters because it links the embedded session back to a record you control. When a signerComplete event fires later, you already know which of your users finished, so you can update your own database without a lookup.

This URL is short-lived by design, so generate it at the moment the user is about to open the signing page rather than minting it ahead of time and storing it. A link created during onboarding and opened an hour later may expire before the signer reaches it. Generate it on demand, on the request that renders the signing view, and you avoid stale tokens entirely.

When a token does expire, Anvil returns a recoverable error you can catch and resolve by requesting a fresh URL. The e-signature API docs cover this under "Recovering from token errors" and "Fetching token metadata," which show how to read token state and regenerate the link in place.

Step 5: Embed the Signing UI in an iframe or AnvilEmbedFrame

Drop the sign URL into a raw iframe src, or use the AnvilEmbedFrame React component, which wraps the same iframe and exposes postMessage events as props so you skip the manual listener wiring.

Before either path works, whitelist your domain. Open API Settings in the Anvil dashboard, enable iframe embedding, and add the origins your app loads from, including http://localhost:3000 during development. Anvil rejects iframe loads from any origin you haven't listed, so a blank frame in local development almost always means a missing whitelist entry.

The raw iframe takes one line.

The React component gives you the same frame plus typed event callbacks.

For flows where you want signing to open over your existing UI instead of inline, Anvil ships AnvilSignatureModal. It renders the same signing experience in a modal overlay, which fits dashboards where the document is one action among many rather than the whole page. Both components live in the same React package, so you can switch between inline and modal patterns without changing your packet or URL code.

White-labeling happens through custom CSS injection. Anvil lets you supply your own stylesheet that loads inside the signing frame, so the buttons, fonts, and colors match your product rather than Anvil's defaults. Your customers see a signing step that looks like a native part of your app, with no third-party branding to suggest they left it. For the full embedding walkthrough and component reference, see Anvil's e-signature API docs.

Step 6: Listen for postMessage Events

The Anvil iframe communicates with your page through postMessage, so you attach a single message listener to catch every state change during signing. Each event tells you where the signer is in the flow, and you respond by updating your UI or kicking off the next step in your backend.

signerLoad fires once the document renders inside the frame, which is the right moment to hide your loading spinner. signerComplete is the event you care about most, because it confirms the signer finished and signals that the signed PDF is ready to pull. Wire your retrieval logic to this event rather than polling the API on a timer.

signerError covers the failure cases, and an expired sign URL is the most common one. When you catch it, generate a fresh URL with generateEtchSignUrl and reload the frame instead of leaving the signer stuck on a blank screen.

If you use AnvilEmbedFrame, the component wraps this listener and exposes the same events through an onEvent callback, so you skip the manual addEventListener wiring. For the full payload schema on each event, including the fields inside signerComplete, read the Embedded Workflow & Webform events section of the Anvil docs.

Step 7: Retrieve the Signed PDF

Once signing completes, pull the finished PDF through the API. For packets with multiple files, download a zip of all documents. For a single-file packet, download the individual document by document ID – no extraction step needed.

Trigger retrieval off the signerComplete postMessage event rather than polling the API on a timer. The iframe fires signerComplete the moment the signer finishes, so your backend knows exactly when the document is ready and skips wasted requests.

Run the actual download from your server, not the browser. Your API key signs the request, and keeping it server-side prevents the key from leaking into client code. For a packet with multiple documents, request the zip and unpack it on your end. For a single-file packet, the individual download returns the PDF directly with no extraction step.

Compliance, White-Label, and Pricing Notes for SaaS Builders

Anvil is SOC 2 certified and built to support HIPAA, GDPR, and eIDAS compliance requirements – the checklist developers cite as mandatory when evaluating any signing API for production (according to WeSignature's overview of e-signature compliance requirements). If your customers operate in healthcare, finance, or the EU, that compliance coverage decides whether you can sell to them at all.

Anvil's Product plan charges a flat rate rather than billing per envelope, which removes the unit-economics math that complicates per-envelope vendors. ISVs evaluating per-envelope pricing have to ask what counts as one envelope, whether voided or test sends get billed, and how overages are triggered (as outlined in eversign's guide to embedded e-signature API costs). Flat pricing skips those questions, so your margin stays predictable as customer signing volume grows instead of eroding with every additional document.

White-label support closes the loop. Pass a stylesheetURL in signaturePageOptions.style and Anvil injects your CSS into the signing frame, so buttons, fonts, and colors match your product rather than Anvil's defaults. Custom stylesheet injection requires the Product pack or Enterprise plan – see the white labeling guide for setup details.

Compliance coverage determines who you can sell to. Flat pricing determines whether the economics hold at scale. CSS-level white-label determines whether signing reads as part of your product. For current plan terms, see Anvil's pricing page.

Frequently Asked Questions

Are embedded signatures legally valid? Embedded signatures collected through Anvil's Etch API carry the same legal weight as any compliant e-signature under the U.S. ESIGN Act and UETA, plus the EU's eIDAS regulation. The signing flow captures consent, intent, and an audit trail regardless of whether the signer arrives by email or through your embedded iframe. Anvil is SOC 2 certified and built for HIPAA, GDPR, and eIDAS compliance, so signatures hold up in regulated industries.

When should I use iframe embedding versus redirect signing? Use iframe embedding when you want signers to stay inside your product, which keeps the experience native and prevents customers from viewing signing as a separate tool. Redirect signing fits cases where you want Anvil to host the page and handle the session at its own URL, which means less frontend work on your side. Most SaaS builders embedding signing into their core workflow choose the iframe path with AnvilEmbedFrame for the white-label result.

How do I handle sign URL token expiration? Sign URLs from generateEtchSignUrl are short-lived, so generate them close to when the signer will actually open the page rather than minting them far in advance. If a signer hits an expired token, generate a fresh URL for the same signer eid and direct them to it again. Anvil's docs cover this in Recovering from token errors, which also explains how to fetch token metadata before the link goes stale.

Does sandbox usage count against my quota? Packets created with isTest: true run in sandbox mode and exercise the full webhook and iframe behavior without sending binding documents. Sandbox packets let you test the entire embedded flow, including postMessage events and signed PDF retrieval, before you flip to production. Test and production volume are tracked separately, so sandbox runs don't eat into your billable quota while you build. Check Anvil's pricing page for the exact quota treatment on your plan.

Start Embedding: Next Steps

To start building, open the e-signature API docs for the complete reference on createEtchPacket, generateEtchSignUrl, and the iframe events. The docs also cover domain whitelisting, the AnvilEmbedFrame component, and webhook configuration for server-side completion notices. The pricing page shows which plan unlocks unordered signing and white-label customization. Spin up the sandbox with isTest: true first and wire one signer end to end before moving to production.

Get a demo
(from a real person)

Schedule some time on our calendar to talk through your specific use case and see which Anvil products can help.
    Want to try Anvil first?
    Want to try Anvil first?