Developers

API reference

Send PDFs for signature from your own systems, follow progress with signed webhooks, and download the sealed document and its evidence package.

Authentication

Create a key in Settings → Developers (Business plan). Send it as a bearer token. Keys act with the permissions of the person who created them, limited to their scopes: read and/or write. Keys can never reach account, team, billing or admin routes. Limit: 600 requests per minute per key.

curl https://mydocument.online/api/v1/agreements \
  -H "Authorization: Bearer ps_live_xxxxxxxxxx_..."

Idempotency

Every write accepts an Idempotency-Key header. Retries with the same key within 24 hours return the original response (with Idempotent-Replayed: true) instead of sending a document twice. Reusing a key for a different request returns 422.

Errors

Errors are JSON with a message, and for validation errors an issues array. A plan limit returns 402 with code: "PLAN_LIMIT".

{ "message": "Validation failed", "issues": [{ "path": "recipients.0.email", "message": "Invalid email" }] }

Webhooks

Add endpoints in Settings → Developers. Each event is a JSON POST with PdfSign-Event, PdfSign-Delivery and PdfSign-Signature: t=<unix>,v1=<hex>, an HMAC-SHA256 of t.rawBody with your endpoint secret. Respond with any 2xx within 10 seconds. Failures retry with backoff for about a day; you can replay any delivery from the dashboard. Events are delivered at least once: de-duplicate on the event id.

Events: agreement.created, agreement.sent, recipient.viewed, recipient.authenticated, recipient.signed, recipient.declined, agreement.declined, agreement.completed, agreement.expired, agreement.voided, agreement.cancelled.

import crypto from 'node:crypto';

// Express: app.post('/webhooks/pdfsign', express.raw({ type: 'application/json' }), handler)
export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
  const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300; // reject replays older than 5 minutes
  return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Documents

Upload PDFs

post/documents

Upload a PDF

Multipart form upload, field name `file`. Returns the version id used to create agreements. Scope: write.

Agreements

Prepare, send and track agreements

get/agreements

List agreements

Parameters
  • status (query) — Comma-separated statuses, e.g. SENT,COMPLETED
  • q (query) — Search title, recipient name or email
  • page (query)
  • pageSize (query)
post/agreements

Create a draft agreement

Body
documentVersionId*string (uuid)
title*string
messagestring
signingOrder"SEQUENTIAL" | "PARALLEL"Default "SEQUENTIAL".
expiresAtany
reminderEveryDaysinteger | null
reminderMaxinteger
get/agreements/{id}

Get an agreement

Parameters
  • id (path)
patch/agreements/{id}

Update a draft

Parameters
  • id (path)
Body
titlestring
messagestring | null
signingOrder"SEQUENTIAL" | "PARALLEL"
expiresAtany | null
reminderEveryDaysinteger | null
reminderMaxinteger
put/agreements/{id}/recipients

Set recipients of a draft

Parameters
  • id (path)
Body
recipients*object[]
idstring (uuid)
name*string
email*string (email)
phonestring | null
role"SIGNER" | "APPROVER" | "WITNESS" | "CC"Default "SIGNER".
signingOrderintegerDefault 1.
authMethod"EMAIL_LINK" | "EMAIL_OTP" | "SMS_OTP"Default "EMAIL_OTP".
put/agreements/{id}/fields

Set fields of a draft

Coordinates are fractions (0–1) of the page as displayed, origin top-left.

Parameters
  • id (path)
Body
fields*object[]
idstring
recipientId*string (uuid)
type*"SIGNATURE" | "INITIALS" | "NAME" | "EMAIL" | "DATE_SIGNED" | "TEXT" | "CHECKBOX" | "COMPANY"
page*integer
x*number
y*number
width*number
height*number
requiredbooleanDefault true.
labelstring | null
post/agreements/{id}/send

Send for signature

Parameters
  • id (path)
post/agreements/{id}/cancel

Cancel or void

Parameters
  • id (path)
Body
reasonstring
post/agreements/{id}/recipients/{recipientId}/remind

Send a reminder

Parameters
  • id (path)
  • recipientId (path)
get/agreements/{id}/audit

Audit trail with chain verification

Parameters
  • id (path)
get/agreements/{id}/download

Download a PDF

Parameters
  • id (path)
  • file (query)
get/agreements/{id}/evidence

Evidence package (zip)

Parameters
  • id (path)

Templates

Reusable documents with roles and fields

get/templates

List templates

get/templates/{id}

Get a template with its roles

Parameters
  • id (path)
post/templates/{id}/agreements

Create (and optionally send) an agreement from a template

Provide one person per template role. Set `send: true` to send immediately.

Parameters
  • id (path)
Body
titlestring
messagestring
recipients*object[]
roleId*string (uuid)
name*string
email*string (email)
phonestring | null
sendbooleanDefault false.