Skip to content

Legally binding e-signature API Signing, as an
API call

Create documents from templates, add recipients, and receive HMAC-signed webhooks when signatures land. Every completed document comes back with its audit trail and, on Business and above, a hash anchored on Hedera.

Base URL https://developer.ledgersign.io/api/v1. API access is included from the Business plan.

create a document from a template
$ curl -X POST https://developer.ledgersign.io/api/v1/documents \
    -H "Authorization: Bearer $LEDGERSIGN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "template_id": "3f6c1e2a-…",
      "title": "Master Services Agreement",
      "recipients": [
        { "email": "counsel@client.com", "order": 1 },
        { "email": "cfo@client.com",     "order": 2 }
      ]
    }'

201 Created
{
  "status": "success",
  "message": "Document created",
  "data": {
    "id": "8c3df21a-…",
    "status": "sent",
    "recipients": 2
  },
  "meta": null
}

How do I authenticate?

Generate an API key in the dashboard under Settings, then send it as a Bearer token on every request. Keys belong to one organization and inherit that organization's plan, so a Business key gets Business limits.

  • Header: Authorization: Bearer <your key>
  • One organization per key; documents are scoped to it
  • Keys can be revoked from the dashboard at any time
  • Keep keys server-side; never ship one in a browser or mobile app
check usage against your plan
$ curl https://developer.ledgersign.io/api/v1/account/usage \
    -H "Authorization: Bearer $LEDGERSIGN_API_KEY"

200 OK
{
  "status": "success",
  "message": "Usage retrieved",
  "data": {
    "plan": "business",
    "documents_used": 212,
    "documents_limit": 500,
    "api_calls_used": 1840,
    "api_calls_limit": 10000
  },
  "meta": null
}
Responses

What does every response look like?

One envelope for every endpoint, so client code handles success and failure the same way everywhere.

error envelope (400)
{
  "status": "error",
  "message": "Validation failed",
  "errors": {
    "recipients": ["At least one recipient is required"]
  }
}

Success responses carry status, message, data, and meta. Error responses drop data and meta and add errors.

StatusMeaning
200 / 201Success. The envelope carries data and, for lists, meta.
400Validation failed. errors lists each field and what was wrong.
401No API key, or the key is invalid or revoked.
403The key is valid but the plan or the key permissions do not allow this call.
404The document, template, or webhook does not exist in your organization.
429Rate limit exceeded for the current one-minute window. Back off and retry.
Rate limits

What are the rate limits?

Limits apply per organization over a one-minute window. Exceed them and the API answers 429 until the window resets.

Business

Requests per minute
300
API calls per month
10,000
Webhook endpoints
5 endpoints

Pro

Requests per minute
1,000
API calls per month
200,000
Webhook endpoints
Unlimited

Enterprise

Requests per minute
Unlimited
API calls per month
Unlimited
Webhook endpoints
Unlimited

How does pagination work?

List endpoints take limit (1 to 100, default 20) and offset (default 0), ordered newest first. The meta object echoes both so a client can page without keeping state of its own.

  • Filter documents by status (draft, sent, completed, and so on)
  • archived=false hides archived documents; archived=true shows only those
  • Templates list the same way, with the same limit and offset
page through completed documents
$ curl "https://developer.ledgersign.io/api/v1/documents?status=completed&limit=20&offset=40" \
    -H "Authorization: Bearer $LEDGERSIGN_API_KEY"

200 OK
{
  "status": "success",
  "message": "Documents retrieved",
  "data": [ { "id": "…", "status": "completed", "sha256": "7f3a92c1…" }, … ],
  "meta": { "limit": 20, "offset": 40 }
}

How do webhooks work?

Register an endpoint and LedgerSign delivers signing events as they happen. Every payload is signed with HMAC-SHA256 using your endpoint's secret, so you can confirm it came from us before you act on it. The signature covers the raw request body.

Headers on every delivery

  • X-Webhook-Signature: hex HMAC-SHA256 of the body
  • X-Webhook-Timestamp: when the delivery was sent
  • X-Webhook-Event: the event name

Events

  • document.created
  • document.sent
  • document.viewed
  • document.signed
  • document.completed
  • document.expired
  • recipient.viewed
  • recipient.signed
  • recipient.declined

A voided document does not fire a webhook; poll GET /documents/{id} or read the audit trail for that state.

incoming webhook (HMAC-signed)
POST /webhooks/ledgersign HTTP/1.1
Content-Type: application/json
X-Webhook-Event: document.completed
X-Webhook-Timestamp: 2026-09-13T14:02:11Z
X-Webhook-Signature: 9f2c41ab…

{
  "event": "document.completed",
  "created_at": "2026-09-13T14:02:11Z",
  "data": {
    "document_id": "8c3df21a-…",
    "status": "completed",
    "sha256": "7f3a92c1…de10e04d",
    "blockchain_transaction_id": "0.0.481…@1757…"
  }
}
Reference

Which endpoints exist?

Every route under /api/v1. Request and response schemas are in the OpenAPI reference.

Documents

MethodPathPurpose
POST/documentsCreate and send a document from a template
POST/documents/multi-templateMerge several templates into one envelope, in order
POST/documents/from-fileUpload a PDF and place fields yourself
GET/documentsList documents with status, archived, limit, and offset filters
GET/documents/{id}Document detail, recipients, and signing status
POST/documents/{id}/voidVoid an in-progress document and notify every reached recipient
GET/documents/{id}/downloadThe signed PDF (and certificate when complete)
POST/documents/{id}/remindSend a reminder to recipients who have not signed
GET/documents/{id}/audit-trailEvery event with actor, timestamp, IP address, and user agent
POST/documents/{id}/archiveArchive or unarchive (see /unarchive)
PATCH/documents/{id}/signers/{signerId}Update a signer before they sign
POST/documents/{id}/signers/{signerId}/resendRe-issue a signing link

Templates

MethodPathPurpose
GET/templatesList templates
GET/templates/{id}Template detail, roles, and fields
POST/templates/{id}/archiveArchive or unarchive (see /unarchive)

Webhooks and account

MethodPathPurpose
GET / POST/webhooksList or register webhook endpoints
GET / PATCH / DELETE/webhooks/{id}Inspect, update, or remove an endpoint
GET/account/usageCurrent usage against plan limits
GET/statusAPI status for the authenticated organization

Full schemas: Swagger UI or ReDoc. Verifying an anchored document needs no API at all; see the verification guide.

Beyond the basics

Send at volume, test without a key

Pro and above

Bulk send via CSV

Upload a CSV and send one template to up to 1,000 recipients in a single batch. Each recipient gets their own document and audit trail, and each completion fires its own webhook.

See how HR teams use it
No account needed

Live API playground

Explore every endpoint, see real request and response shapes, and copy working curl commands before you generate a key.

Open the playground

Ship signing
this sprint

Start on the free plan to model your templates, then move to Business for API keys, webhooks, and anchoring.

API access from $149/month · 300 requests per minute on Business · HMAC-signed webhooks

Page updated September 29, 2026