Skip to content

API reference · v1

Send documents for signature from your own software.

A small, boring REST API: upload a PDF, say who signs where, and get told when it's done. JSON in, JSON out, one bearer key.

Authentication

Create a key in Settings → Developers and send it on every request as Authorization: Bearer es_live_…. We show the key once and store only a hash, so keep it in your secrets manager, not in client-side code. Errors always look like { "error": { "code": "…", "message": "…" } } with a matching HTTP status.

Endpoints

MethodPathWhat it does
GET/api/v1/meYour account, plan and documents used this month.
GET/api/v1/documentsList documents. Query: status (comma-separated), limit (1–100), before (ISO date cursor).
POST/api/v1/documentsUpload a PDF, add signers and fields, and send it (multipart).
GET/api/v1/documents/{id}Status, signers and the full audit trail.
GET/api/v1/documents/{id}/downloadThe signed PDF (?file=original for the unsigned one).
POST/api/v1/documents/{id}/voidWithdraw a document that's waiting for signatures. Body: { reason }.
DELETE/api/v1/documents/{id}Permanently delete a draft, voided, declined or completed document.
POST/api/v1/templates/{id}/sendSend a saved template. Body: { title?, signers: [{ name, email }] }, one per role in order.

Create and send a document

Coordinates are fractions of the page, measured from the top-left corner, so they work at any page size. kind is one of signature, initials, date, name, email, text or checkbox; add required: false or a label where it helps. Set "sequential": true to have signers go in order, or "send": false to keep it as a draft you finish in the editor.

curl https://esignsimple.com/api/v1/documents \
  -H "Authorization: Bearer $ESIGN_KEY" \
  -F [email protected] \
  -F 'data={
    "title": "Consulting agreement",
    "message": "Please sign by Friday",
    "signers": [{ "name": "Jane Doe", "email": "[email protected]" }],
    "fields": [
      { "signer": 0, "kind": "signature", "page": 0, "x": 0.1, "y": 0.8, "w": 0.3, "h": 0.06 },
      { "signer": 0, "kind": "date", "page": 0, "x": 0.5, "y": 0.8, "w": 0.2, "h": 0.03 }
    ]
  }'

The response is the document object with status sent. If your account has no email delivery configured, signing_links contains each signer's personal link so you can deliver it yourself.

Webhooks

Add one HTTPS endpoint in Settings. We send document.completed, document.declined, document.voided and signer.signed as JSON: { id, type, created_at, data }. Each request carries esign-signature, the hex HMAC-SHA256 of the raw body using your endpoint secret. Verify it before trusting the payload, and treat events as at-least-once: we retry a failed delivery once after a few seconds.

import crypto from "node:crypto";

// raw = the exact request body string; header = req.headers["esign-signature"]
const expected = crypto.createHmac("sha256", process.env.ESIGN_WEBHOOK_SECRET).update(raw).digest("hex");
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));

Limits and what's not here yet

API documents count toward your plan exactly like documents sent from the dashboard. PDFs are limited to 25 MB and 10 signers. There's no embedded signing iframe, SDK or sandbox yet; they're on the roadmap, and we'd rather tell you that than pretend. Our take: most integrations need three calls (create, poll or webhook, download), and we'd rather keep those three excellent than ship thirty mediocre ones.

Frequently asked questions

Is the eSignSimple API free?

Yes. The API is included on every plan and follows the same limits: 5 documents a month on Free, unlimited on Personal. There is no separate API price.

How do I authenticate?

Create a key in Settings → Developers and send it as `Authorization: Bearer es_live_…`. Keys are shown once and stored hashed; revoke one any time and requests using it fail immediately.

How do I know when a document is signed?

Add a webhook URL in Settings. We POST document.completed, document.declined, document.voided and signer.signed events, signed with HMAC-SHA256 in the esign-signature header. You can also poll GET /api/v1/documents/{id}.

Can signers sign inside my app?

Not yet. Embedded signing (an iframe you host) is on our roadmap. Today each signer gets a personal link by email, or you receive the links in the API response to deliver yourself.

Is there a sandbox?

Not yet. Create a separate free account for testing; documents you create there are real but cost nothing up to 5 a month.