Get documents signed without leaving your AI chat. Meet SignWell MCP →

How to integrate an eSignature API: A developer’s tutorial

How to integrate an eSignature API: A developer’s tutorial

Integrating an eSignature API into your application takes an afternoon if you know the four pieces to wire up: authentication, document creation, templates, and webhooks. This guide walks through each one using the SignWell API, a REST API that lets you create, send, track, and manage eSignatures from your application code. Authenticate with an API key, POST a document to /v1/documents, and SignWell handles recipient invitations, the signing flow, and the audit trail.

If you’re building eSignatures into a product (an HR tool, a contract management system, a marketplace, an onboarding flow), the API is what you want. If you just need to send eSignatures from a terminal or pipeline without writing integration code, use the SignWell CLI instead.

When to use the API versus the CLI

Both hit the same endpoints. Pick based on what you’re building.

  • Use the API if you’re writing application code that needs to send or manage eSignatures as part of a user-facing workflow. Custom integrations, embedded signing in your product, programmatic document generation tied to business events, anything where eSignature is a feature inside a larger system.
  • Use the CLI if you’re automating from outside your codebase. Scripts, CI/CD pipelines, ops workflows, AI agents, or one-off bulk sends without writing a full integration.

Many teams use both. The CLI for ad-hoc operations and bulk sends, and the API for the production integration.

Before you can integrate an eSignature API into your app, you need three things:

  1. A SignWell account with API access
  2. An API key from your SignWell dashboard
  3. A way to make HTTP requests in your language of choice (any modern HTTP client works)

The examples below use JavaScript with fetch. The patterns are the same in Python, Ruby, Go, or any language.

Authenticating to the SignWell eSignature API

Authentication uses an API key passed in the X-Api-Key request header. Treat the API key like any other secret. Store it in environment variables, not source code:

X-Api-Key: YOUR_API_KEY

Treat the API key like any other secret. Store it in environment variables, not source code:

const API_KEY = process.env.SIGNWELL_API_KEY;

const headers = {

  ‘X-Api-Key’: API_KEY,

  ‘Content-Type’: ‘application/json’

};

For different environments (production, staging, sandbox), use separate keys with separate accounts. Never share keys across environments.

Sending your first eSignature via the API

The simplest possible integration: send a PDF to a recipient for signature.

const response = await fetch(‘https://www.signwell.com/api/v1/documents/’, {

  method: POST,

  headers,

  body: JSON.stringify({

    name: Q2 Services Agreement,

    files: [{

      name: contract.pdf,

      file_base64: pdfBase64

    }],

    recipients: [{

      id: ‘1’,

      placeholder_name: Client,

      email: [email protected],

      name: Jane Smith

    }],

    draft: false

  })

});

const document = await response.json();

console.log(Sent:’, document.id);

That’s the whole flow. SignWell takes the file, creates a document, sends Jane an email with a signing link, and returns a document ID you can poll or hook into.

A few flags worth knowing on the create endpoint:

  • draft: true keeps the document in your account without sending it. Useful for review workflows.
  • text_tags: true enables embedded signing fields placed via tags inside the PDF text.
  • apply_signing_order enforces sequential signing across multiple recipients.
  • test_mode: true creates a real API object without sending an actual email. Safe for development

Using eSignature API Templates for Repeatable Workflows 

If you’re sending the same document repeatedly (offer letters, NDAs, terms of service), templates are the right pattern. Build the template once in the SignWell UI with placeholder roles and merge fields, then call it from the API:

const response = await

fetch(https://www.signwell.com/api/v1/document_templates/documents/, {

  method: POST,

  headers,

  body: JSON.stringify({

    template_ids: [tmpl_abc123],

    recipients: [{

      id: ‘1’,

      placeholder_name: Candidate,

      email: [email protected],

      name: Alex Lee

    }],

    template_fields: [

      { api_id: candidate_name, value: Alex Lee },

      { api_id: start_date, value: 2026-05-15 },

      { api_id: salary, value: $135,000 }

    ]

  })

});

For batch sends from arrays of recipient data, see the bulk-send eSignature workflow, which covers the same pattern at scale.

Tracking Signed Documents With Webhooks 

You don’t want to poll. Register a webhook, and SignWell will tell you when documents change state. Events you’ll care about:

  • document_completed — all recipients have signed
  • document_signed — a single recipient signed (fires per recipient)
  • document_declined — a recipient declined to sign
  • document_expired — the document expired before completion

Register the webhook (one-time setup):

await fetch(https://api.signwell.com/v1/hooks/, {

  method: POST,

  headers,

  body: JSON.stringify({

    callback_url: https://yourapp.com/webhooks/signwell

  })

});

SignWell sends every document event to your callback URL. There is no event filtering at registration. You handle filtering in your webhook handler based on the event type in the payload, typically with a switch statement on the events you care about. In your handler, verify the HMAC signature on every incoming request before trusting the payload. 

Error handling and retries

The API uses standard HTTP status codes. The ones to handle explicitly:

  • 401 Unauthorized — bad or missing API key
  • 403 Forbidden — key doesn’t have permission for this operation
  • 422 Unprocessable Entity — validation error in your request payload
  • 429 Too Many Requests — rate limit hit
  • 5xx — transient server error, retry with exponential backoff

A reasonable retry policy: retry 429 and 5xx with exponential backoff (start at 1 second, double up to 32 seconds, give up after five attempts). Do not retry 4xx errors other than 429; those are bugs in your request.

async function withRetry(fn, maxAttempts = 5) {

  for (let attempt = 0; attempt < maxAttempts; attempt++) {

    try {

      return await fn();

    } catch (err) {

      if (err.status !== 429 && err.status < 500) throw err;

      await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));

    }

  }

  throw new Error(Max retries exceeded);

}

eSignature API Production Checklist

Before going live, work through this list:

  • API keys stored in environment variables or a secret manager, not source code
  • Separate keys for production and staging
  • Webhook handler verifies HMAC signatures
  • Retry logic for 429 and 5xx
  • Logging on every API call (request ID, status, duration)
  • Test mode used in staging and CI to avoid sending real emails
  • Compliance posture documented (see security and compliance for SignWell’s certifications)

Wrap-up

The SignWell eSignature API is a standard REST API that you can wire into a production application in an afternoon. Authentication, your first document, templates, and webhooks are the core surface area. Add error handling, retries, and signature verification, and you have a production-ready eSignature integration.

Start by grabbing an API key, sending a single document, and registering a webhook. Once that round-trip works, the rest is incremental.

 

Frequently asked questions

What languages does the SignWell eSignature API support?

The API is REST/JSON, so any language with an HTTP client works. Common choices include Node.js, Python, Ruby, Go, Java, C#, and PHP. There are no language restrictions.

Does SignWell have official SDKs?

The SignWell CLI is the officially maintained tooling and works as a programmatic interface for any language that can shell out. For language-native SDKs, check the API documentation for current options or use the CLI directly.

How are SignWell API rate limits structured?

Rate limits are per account and apply across all API endpoints. The CLI handles 429 responses automatically with exponential backoff. If your application regularly hits limits, contact support to discuss higher tiers.

How do I test the SignWell API without sending real emails?

Set test_mode: true on document creation. The API creates a real document object you can inspect, but no actual emails are sent to recipients. Perfect for staging environments and integration tests.

What's the difference between the SignWell API and the SignWell CLI?

They hit the same endpoints. The API is for application integrations written in your codebase. The CLI is for use in terminals, scripts, pipelines, and AI agents.

Can I embed signing directly in my app?

Yes. SignWell supports embedded signing, where the signature flow occurs within an iframe or webview in your application rather than via email. Check the API documentation for the embedded signing endpoint.