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:
- A SignWell account with API access
- An API key from your SignWell dashboard
- 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.