Help center
API

How do I integrate via API?

REST API + webhooks for programmatic sending. Pro tier required. Available endpoints and authentication.

2 min read

The SahlSign API is REST + JSON. You can send documents, query status, list audit events, and (forthcoming) receive webhooks when documents change state — all programmatically.

Getting started

  1. Open Settings → API Keys (Pro plan required)
  2. Click Create new key. Give it a label (e.g., "Production HRIS integration"). The full key is shown ONCE — copy it immediately
  3. Authenticate every request with Authorization: Bearer sahl_live_xxxxx

Key endpoints

POST   /api/v1/documents          Upload + create a document
POST   /api/v1/documents/:id/send Send for signature
GET    /api/v1/documents/:id      Document status + audit trail
POST   /api/v1/templates/:id/send Send using a saved template
POST   /api/v1/bulk-sends         Batch send via CSV
GET    /api/v1/bulk-sends/:id     Batch status
POST   /api/v1/webhooks           Register a webhook

Each request includes a tenant context derived from the API key — keys are tenant-scoped so a leaked key only affects its own organization.

Webhooks

When you register a webhook URL, we POST a JSON payload to it on these events:

  • document.sent
  • document.viewed
  • document.signed
  • document.completed
  • document.declined
  • document.voided
  • bulk_send.completed

Every payload is signed with HMAC-SHA256 using your webhook secret. Verify the X-SahlSign-Signature header to confirm the request is from us:

const expectedSignature = crypto
  .createHmac('sha256', webhookSecret)
  .update(rawBody)
  .digest('hex');
if (request.headers['x-sahlsign-signature'] !== expectedSignature) {
  return reply.status(401).send('Invalid signature');
}

We retry failed deliveries with exponential backoff (up to 24 hours). Webhook delivery history is visible under Settings → API Keys → Webhook deliveries.

Rate limits

  • 100 requests / minute / tenant on the standard Pro plan
  • Higher limits available on Enterprise (contact us)

Rate-limited requests return 429 Too Many Requests with a Retry-After header indicating when to retry.

SDKs

We don't yet ship official SDKs. The API is plain REST, so any HTTP client works. Community-maintained TypeScript / Python / Ruby helpers are linked from the developer docs.

Status

This feature is Pro tier only. The API Keys page on a free-tier account shows an upgrade gate.

(Note: webhooks routes are in active development. The schema and queue infrastructure are in place, the public POST endpoint and event dispatcher are not yet shipped at the time of writing. Check the status page or contact us for current availability.)