eSignature API you can integrate in an afternoon.

OpenAPI first, versioned by date, idempotent on every write, and documented down to the error bodies. The same API powers the Signclad app, the embedded builders, and the MCP server — there is no private tier.

Send a document

One POST creates a document from a file you host, places the fields, and sends it. Pass an Idempotency-Key and a retry after a lost response is free.

Base URL: https://api.signclad.com/api/v1

POST /documents
X-Api-Key: sk_live_…
Idempotency-Key: 7c1e-4a90-…

{
  "name": "Loan agreement",
  "subject": "Please sign your loan agreement",
  "test_mode": false,
  "draft": false,
  "reminders": true,
  "expires_in": 30,
  "metadata": { "loan_id": "48213" },
  "files": [
    { "name": "loan-agreement.pdf",
      "file_url": "https://files.example.com/msa.pdf?X-Amz-…" }
  ],
  "recipients": [
    { "id": "signer-1", "name": "Jane Doe", "email": "[email protected]" }
  ],
  "fields": [[
    { "api_id": "borrower_signature", "type": "signature",
      "recipient_id": "signer-1", "page": 1,
      "x": 375, "y": 206, "width": 180, "height": 44, "required": true },
    { "api_id": "borrower_date", "type": "date",
      "recipient_id": "signer-1", "page": 1,
      "x": 375, "y": 262, "width": 120, "height": 24,
      "lock_sign_date": true, "date_format": "MM/DD/YYYY" }
  ]]
}

And what comes back

A 201 with the signing URLs already valid. Note two honest quirks, both documented rather than discovered: the status on a create is the transient Created whatever draft was, and pages_number is 0 until ingest finishes. The settled status arrives on the next GET.

warnings[] is where Signclad tells you it accepted something the compatibility target would have rejected outright.

201 Created
x-ratelimit-limit: 10
x-ratelimit-remaining: 9
x-ratelimit-reset: 2026-09-09T20:56:00+00:00

{
  "id": "8f14e45f-ea8f-4b2c-9f0e-1b2c3d4e5f60",
  "status": "Created",
  "name": "Loan agreement",
  "test_mode": false,
  "embedded_signing": true,
  "metadata": { "loan_id": "48213" },
  "files": [
    { "name": "msa.pdf", "pages_number": 0, "status": "processing" }
  ],
  "recipients": [
    { "id": "signer-1", "name": "Jane Doe", "email": "[email protected]",
      "status": "created", "signing_order": 1,
      "embedded_signing_url": "https://app.signclad.com/sign/embedded/9c8f2b1a?token=…",
      "bounced": false }
  ],
  "warnings": [
    { "code": "lock_sign_date_value_ignored",
      "message": "borrower_date fills itself on signing.",
      "pointer": "/fields/0/1/value" }
  ]
}

Webhooks that tell you when they are broken

As many endpoints per workspace as you want, each with its own subscriptions, its own secret, and its own health.

Verification

The signature covers the raw body, not a header line: X-Signclad-Signature: t=<unix>,v1=<hex hmac-sha256(secret, "<t>.<raw body>")>, with a five-minute tolerance and a constant-time comparison. During a secret rotation the header carries one v1= value per valid secret, so rotation has no cutover.

Delivery and retry

At least once, 10-second timeout, any 2xx counts. Nine attempts over about three and a half days — the first, then retries at 1 m, 5 m, 15 m, 1 h, 3 h, 8 h, 24 h, 48 h with jitter. Retry-After is honoured and a 410 pauses the endpoint at once. Dedupe on X-Signclad-Event-Id, which is stable across retries and replays.

Delivery log and replay

Every delivery with its full attempt timeline, request headers and body, response status and body excerpt, and latency. Replay one, replay a selection, replay a date range, or resend everything that failed since a moment you pick.

Health states

StateWhat it means
healthy Deliveries are landing.
degraded Fifteen minutes of failures without a success, or over 25% failures in an hour while still failing. Admins are emailed and a banner appears in the app.
failing 25 consecutive failures, or 100% failures over 24 hours. A circuit breaker stops hammering you and probes hourly.
disabled Five days of continuous failure. Re-enabling offers to replay everything you missed in one click.

Event catalog — what each one means

  • document_created
  • document_sent
  • document_viewed
  • document_in_progress
  • document_recipients_updated
  • document_signed
  • document_completed
  • document_expired
  • document_canceled
  • document_declined
  • document_bounced
  • document_error
  • template_created
  • template_updated
  • template_error
  • template_deleted
  • bulk_send_completed
  • template_link_used
  • ping

Embedding

Put the signing view, the document builder, or the template builder inside your own product, branded as yours.

Embedded signing
Each recipient gets an embedded_signing_url you drop into an iframe. If it expires or you lose it, mint a fresh one with POST /documents/{id}/recipients/{rid}/signing_url instead of recreating the document.
Embedded builders
embedded_edit_url opens the document builder or the template builder in your page, with views for editing files, recipients, or fields. Renew it from the host side when a session runs long.
API applications
An API application carries your branding — logo, primary colour, button text colour, border radius — and the domains allowed to embed. Bind it to a key and every iframe your users see is yours.

Tools for reliable API integrations

Sandbox keys
sk_test_ keys never bill. Recipients receive emails labeled as test documents, and the documents are watermarked. Test mode is unlimited. No environment variable gymnastics to work out which mode you are in — the key says so.
Idempotency
Idempotency-Key on any POST, PATCH, or PUT, scoped to key plus method plus path and kept 24 hours. A retry after a timeout returns the original response rather than creating a second document.
Rate limits
120 requests a minute general, 10 for creates and mutations, 50 unauthenticated. x-ratelimit-limit, -remaining and -reset on every response, with the standard RateLimit-* headers alongside. Note that x-ratelimit-reset is an ISO 8601 timestamp, not a seconds count, and that a failed create still charges the create bucket.
Errors you can branch on
Every error carries a request_id and a type URL that links to its documentation. Validation errors are per field and per field id, so you can fix one value rather than re-sending everything.
Versioning
Dated versions through the Api-Version header, v1 frozen, and a twelve-month deprecation policy. Anything that ships is written down on the changelog.
List and search
Cursor-paginated GET /documents and GET /document_templates with filters on status, label, recipient email, metadata, and free text. No more polling ids one at a time.

Libraries

The honest version: there are no published client libraries yet, and you do not need one.

HTTP and JSON
Every endpoint is plain HTTP with a JSON body and an X-Api-Key header. Whatever HTTP client your language already has is enough — fetch, requests, Guzzle, curl. Nothing requires a vendor package to work, and nothing is hidden behind one.
OpenAPI 3.1
The contract is a versioned OpenAPI 3.1 document, and it is the source the API reference, the webhook event catalog, and the MCP tool schemas are all generated from. Point your own generator at it and you have a client in the language you actually use.
Generated clients
Not published yet. We would rather ship none than ship four half-maintained SDKs that lag the spec, so until there is a release we can commit to keeping current, the OpenAPI document is the supported path. The changelog will say when that changes.
MCP server
Sixteen tools, hosted by us at api.signclad.com/mcp and reached with OAuth. Nothing to install and no package to keep current. See the MCP page for what it does and the guide for how to connect.

New here? Getting started takes you from a sandbox key to a signed document and its audit trail in six steps.

Get a sandbox key and try it.

API access starts with Light. Every paid plan includes unlimited test mode and the first 25 live API documents each month with a card on file.