✦ REST API v1

ZeroDocs API Reference

Integrate e-signatures, PDF tools, and AI auto-fill directly into your product. All requests and responses are JSON unless noted.

Base URLhttps://api.zerodocs.xyz/v1

Authentication

Include your secret API key in the Authorization header on every request. Keys are prefixed zd_live_ in production or zd_test_ in sandbox.

Secret key
Never expose your API key in client-side code. Store it as an environment variable and rotate it immediately if compromised.

Rate limits

Per API key per minute. Exceeded requests receive 429 with a Retry-After header in seconds.

Endpoint groupLimit
General300 req/min
Document create/send60 req/min
Bulk send10 jobs/min
OCR submit30 req/min
AI endpoints20 req/min

Error codes

All errors return { "error": { "code": "...", "message": "..." } }.

CodeHTTPDescription
INVALID_API_KEY401Key missing, malformed, or revoked
QUOTA_EXCEEDED402Monthly doc or OCR quota reached
DOCUMENT_NOT_FOUND404Doc ID doesn't exist or belongs to another account
DOCUMENT_COMPLETED422Action not allowed on a completed document
VALIDATION_ERROR422Body failed validation — see error.fields
RATE_LIMITED429Too many requests — check Retry-After
INTERNAL_ERROR500Server error — safe to retry with backoff

Documents

GET/documentsList documents

Paginated list of documents, newest first.

Query paramTypeDescription
statusoptionalstringpending, completed, declined, voided, expired
limitoptionalinteger1–100, default 20
cursoroptionalstringPagination cursor from previous response
created_afteroptionalISO 8601Filter documents created after this datetime
200 OK401 Unauthorized
POST/documentsCreate & send document

Upload a PDF and send signing requests. Request must be multipart/form-data.

FieldTypeDescription
filerequiredfilePDF, max 25MB
titlerequiredstringDocument display name
signersrequiredarrayArray of signer objects: [{"name":"...","email":"...","order":1}]
messageoptionalstringCustom email message to signers
expires_atoptionalISO 8601Expiry date (default: 30 days from now)
reminder_daysoptionalintegerAuto-reminder interval in days (default: 3)
201 Created400 Bad Request422 Validation error
POST/documents/{id}/voidVoid document

Immediately invalidates all signer links. Cannot void completed documents.

BodyTypeDescription
reasonoptionalstringReason communicated to signers via email
200 OK422 Already completed
GET/documents/{id}/downloadDownload signed PDF

Returns signed PDF with embedded audit trail as application/pdf. Only available when status is completed.

200 OK (PDF)422 Not complete

Bulk Send

POST/bulk-jobsCreate bulk send job

Creates a job from a template. Each recipient gets a personalised document. Response includes a job_id — poll GET /bulk-jobs/{id} for progress, or use webhooks.

FieldTypeDescription
template_idrequiredstringTemplate to use for personalisation
recipientsrequiredarrayUp to 500 recipient objects with token values
subjectoptionalstringEmail subject — supports {"{"}"{"}"} token substitution
send_atoptionalISO 8601Schedule send time (default: immediate)
expires_atoptionalISO 8601Expiry for all documents in the job
201 Job created429 Rate limited
GET/bulk-jobs/{id}Get job status

Returns job progress including sent, failed, and total counts. Status is queued, running, completed, or failed.

200 OK

OCR

POST/ocr/jobsSubmit file for OCR

Async text extraction via AWS Textract. Deducts from your OCR page quota. Use webhook_url or poll GET /ocr/jobs/{id}.

FieldTypeDescription
filerequiredfilePDF file, max 25MB
webhook_urloptionalURLCalled with result when complete
201 Queued402 Quota exceeded

Webhooks

ZeroDocs POSTs JSON to your webhook_url when events occur. Verify the X-ZeroDocs-Signature header (HMAC-SHA256 of request body using your webhook secret).

Always verify signatures
Ignore events where signature verification fails — anyone can POST to your endpoint.
Event typeDescription
document.signedA signer completed their fields
document.completedAll signers signed — PDF ready
document.declinedA signer declined to sign
document.voidedDocument was voided
document.expiredDocument passed expiry date
bulk_job.completedBulk send job finished
ocr.completedOCR job finished
Examples
cURL
Node.js
Python
Create document
curl -X POST \
  https://api.zerodocs.xyz/v1/documents \
  -H "Authorization: Bearer $ZD_KEY" \
  -F "file=@agreement.pdf" \
  -F "title=Service Agreement" \
  -F 'signers=[{"name":"Rahul","email":"r@co.in"}]'
Verify webhook
import hmac, hashlib, os

def verify(body, sig):
  secret = os.environ['ZD_SECRET'].encode()
  expected = hmac.new(secret, body, hashlib.sha256).hexdigest()
  return hmac.compare_digest(expected, sig)
Document response
{
  "id": "doc_a1b2c3d4e5",
  "title": "Service Agreement",
  "status": "pending",
  "created_at": "2026-02-28T11:43:00Z",
  "expires_at": "2026-03-30T11:43:00Z",
  "signers": [{
    "id": "sgn_x1y2z3",
    "name": "Rahul Sharma",
    "email": "r@acme.co",
    "status": "pending",
    "signed_at": null
  }],
  "download_url": null
}