ChickenSign Developer Platform·REST API v1

REST API & Integration Guide

Integrate UK e-signatures directly into your CRM, invoicing software, job management platform, or website.

Base URL

https://chickensign.com/api/v1

Authentication

Bearer ck_live_…

Rate Limit

60 requests / minute

How signers receive their documents

When you create an envelope through the API, ChickenSign emails each signer a secure signing invitation from ChickenSign's verified sending domain, with replies routed to your account email. For sequential envelopes, only the current signer is emailed; the next signer is invited automatically once the previous one signs. The response also includes each signer's private signUrl, so you can share links through your own channels too (SMS, WhatsApp, client portals, invoices). When everyone has signed, ChickenSign emails the signed PDF and proof of signing to you, every signer and any copies addresses.

  • The invitation includes your account name, the document title and your optional message.
  • If an invitation bounces or is marked as spam, you receive an envelope.bounced webhook so you can send the signUrl another way. Future emails to that address are suppressed.

API Reference

Authentication

All API requests must supply an API key in the standard Authorization header:

Authorization: Bearer ck_live_abcdefghijklmnopqrstuvwxyz012345
  • Keys are generated in your dashboard under Desk > API Keys.
  • ChickenSign stores only the SHA-256 hash of your key; keys cannot be recovered if lost.
  • You can have up to 5 active keys concurrently. If a key is compromised, revoke it immediately.
  • Requests without a valid key return 401 Unauthorized.

Check key validity:

GET /api/v1/me
curl -X GET https://chickensign.com/api/v1/me \
  -H "Authorization: Bearer ck_live_YOUR_API_KEY"

Rate Limits & Idempotency

Rate Limiting

Each API key has a quota of 60 calls per minute (rolling 60-second window). Every response includes rate limit telemetry headers:

  • x-ratelimit-limit: 60
  • x-ratelimit-remaining: 58

Exceeding the quota returns HTTP 429 with Retry-After: 60.

Idempotency Keys

To guard against duplicate documents on network drops or automatic retries, send an Idempotency-Key header with POST calls.

Must be 8 to 80 characters: letters, numbers, or . _ : -.

If sent again, ChickenSign replays the existing envelope with status 200 without creating a duplicate or charging another credit.

Endpoints

GET/api/v1/me

Verify your API credentials and test connectivity.

Response (200 OK)

{
  "ok": true
}
POST/api/v1/envelopes

Creates and locks up to 10 PDFs for signing in one envelope. Generates unique signing URLs for each party. Send a small PDF inline as base64 (fileName + fileData, whole request up to 14 MB), or upload each PDF first with POST /api/v1/documents (up to 30 MB each) and pass the documentIds in documents. Single-file requests work exactly as before.

Request Body Parameters

FieldTypeRequiredDescription
titlestringYesDocument title (1–180 chars).
fileNamestringOr documentsFile name with .pdf extension (1–180 chars), for one inline PDF.
fileDatastringOr documentsBase64 encoded PDF. Data URI prefix stripped automatically. Must be a readable PDF with at least one page and no password. Whole request up to 14 MB.
documentsarrayOr fileData1 to 10 items, in the order signers see them. Each is { documentId } from an upload, or { fileName, fileData } inline. Send either this or fileName/fileData, not both.
signersarrayYes1 to 10 signers, each with name and unique email.
signingOrderstringNo"parallel" (default) or "sequential".
fieldsarrayNoUp to 200 field placement objects. Use document to choose the PDF. Omit to put one signature box per signer on page 1 of a single PDF, or on the last page of the last document.
messagestringNoInstructions shown to signers above the contract (up to 2,000 chars).
copiesstring[]NoUp to 5 email addresses that receive the signed PDF and proof of signing by email once all parties have signed.
allowTypedbooleanNoDefault true. Allow keyboard typed signatures. At least one signature method must remain enabled.
allowHandwrittenbooleanNoDefault true. Allow drawn handwritten signatures (touch / pen / mouse). Also accepts allowDrawn.

Code Example:

POST /api/v1/envelopes
curl -X POST https://chickensign.com/api/v1/envelopes \
  -H "Authorization: Bearer ck_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: job-2026-0814" \
  -d '{
    "title": "Boiler Installation Agreement",
    "fileName": "quote.pdf",
    "fileData": "JVBERi0xLjQKJcOkw7zDtsOf...",
    "signingOrder": "parallel",
    "signers": [
      { "name": "Priya Shah", "email": "[email protected]" }
    ],
    "message": "Please review and sign your quotation."
  }'

Several documents (large files):

POST /api/v1/documents → POST /api/v1/envelopes
# 1. Upload each PDF (raw bytes, up to 30 MB each)
QUOTE=$(curl -s -X POST https://chickensign.com/api/v1/documents \
  -H "Authorization: Bearer ck_live_YOUR_API_KEY" \
  -H "Content-Type: application/pdf" \
  -H "X-File-Name: Quote.pdf" \
  --data-binary @Quote.pdf | jq -r .documentId)

TERMS=$(curl -s -X POST https://chickensign.com/api/v1/documents \
  -H "Authorization: Bearer ck_live_YOUR_API_KEY" \
  -H "Content-Type: application/pdf" \
  -H "X-File-Name: Terms.pdf" \
  --data-binary @Terms.pdf | jq -r .documentId)

# 2. Create one envelope with both documents
curl -X POST https://chickensign.com/api/v1/envelopes \
  -H "Authorization: Bearer ck_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Boiler Installation Pack",
    "documents": [{ "documentId": "'$QUOTE'" }, { "documentId": "'$TERMS'" }],
    "signers": [{ "name": "Priya Shah", "email": "[email protected]" }],
    "fields": [
      { "id": "sig_quote", "document": 0, "page": 0, "x": 0.1, "y": 0.75, "w": 0.4, "h": 0.08, "kind": "signature", "signer": 0 },
      { "id": "init_terms", "document": 1, "page": 3, "x": 0.7, "y": 0.9, "w": 0.15, "h": 0.05, "kind": "initials", "signer": 0 }
    ]
  }'

Response (201 Created)

{
  "envelope": {
    "id": "e4f8d9c2a10b",
    "title": "Boiler Installation Agreement",
    "status": "out_for_signature",
    "fileName": "quote.pdf",
    "documents": [
      {
        "position": 0,
        "fileName": "quote.pdf",
        "pageCount": 2,
        "byteSize": 182044,
        "sha256": "9f2c1e...",
        "signedDocumentUrl": "https://chickensign.com/api/v1/envelopes/e4f8d9c2a10b/documents/0/signed"
      }
    ],
    "message": "Please review and sign your quotation.",
    "certificateCode": "CS-2026-F9A",
    "contentHash": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
    "completedHash": "",
    "createdAt": "2026-10-16T17:15:00.000Z",
    "sentAt": "2026-10-16T17:15:00.000Z",
    "completedAt": null,
    "allowTyped": true,
    "allowDrawn": true,
    "files": {
      "signedDocumentUrl": "https://chickensign.com/api/v1/envelopes/e4f8d9c2a10b/document",
      "proofOfSigningUrl": "https://chickensign.com/api/v1/envelopes/e4f8d9c2a10b/proof"
    },
    "signers": [
      {
        "name": "Priya Shah",
        "email": "[email protected]",
        "status": "sent",
        "signUrl": "https://chickensign.com/sign/v84bJ_8xk9...",
        "signedAt": null
      }
    ]
  }
}
POST/api/v1/documents

Uploads one PDF of up to 30 MB as raw bytes, with Content-Type: application/pdf and an X-File-Name header. Use the returned documentId in documents when you create an envelope. Each upload can be used in one envelope only, within 24 hours.

Response (201 Created)

{
  "documentId": "doc_5f0c2a9e41d7b3c86e1f0a24",
  "fileName": "Terms.pdf",
  "pageCount": 48,
  "byteSize": 23068672,
  "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c7...",
  "expiresAt": "2026-10-31T09:14:02.000Z"
}
  • 413 over 30 MB (counted as it arrives, whatever Content-Length says)
  • 422 not a PDF, no pages, unreadable, or password-protected. The message names the file.
  • 429 more than 60 uploads in an hour
GET/api/v1/envelopes

Lists the 50 most recent envelopes for your account. Filter by status using the optional query parameter:?status=out_for_signature|completed|declined|voided|draft.

Response (200 OK)

{
  "envelopes": [
    {
      "id": "e4f8d9c2a10b",
      "title": "Boiler Installation Agreement",
      "status": "out_for_signature",
      "fileName": "quote.pdf",
      "certificateCode": "CS-2026-F9A",
      "contentHash": "5e88489...",
      "completedHash": "",
      "createdAt": "2026-10-16T17:15:00.000Z",
      "sentAt": "2026-10-16T17:15:00.000Z",
      "completedAt": null
    }
  ]
}
GET/api/v1/envelopes/:id

Fetches full status, timestamp tracking, and signer URLs for a single envelope.

GET/api/v1/envelopes/:id/document

Downloads the stamped, executed PDF document (File 1 of 2) with all signatures, initials, dates, and completed fields. For several documents, this is all signed documents combined into one PDF (or the first signed document when the set is over 50 MB).

Content-Type: application/pdf · Returns binary PDF stream.
GET/api/v1/envelopes/:id/documents/:position/signed

Downloads one signed document. position is its 0-based place in documents; the URL is returned as documents[].signedDocumentUrl.

Content-Type: application/pdf · Supports Range requests (206).
GET/api/v1/envelopes/:id/proof

Downloads the standalone cryptographic Certificate & Proof of Signing (File 2 of 2), including the complete immutable audit trail, SHA-256 hashes, signer IP addresses, user agents, and tamper-evident seal.

Content-Type: application/pdf · Returns binary PDF stream.
POST/api/v1/envelopes/:id/void

Immediately voids an in-progress document. All signing links are disabled and return an error if accessed. Signers are not emailed about the void. Cannot void a document that has already reached completed.

Field Coordinates & Geometry

ChickenSign uses normalized 0-to-1 floating point coordinates for responsive, resolution-independent PDF rendering.

Coordinate System:

  • document: 0-indexed PDF in documents (default 0).
  • page: 0-indexed page number in that PDF (0 is first page). It must exist.
  • x: Left position from 0.0 (left edge) to 1.0 (right edge).
  • y: Top position from 0.0 (top edge) to 1.0 (bottom edge).
  • w: Width fraction (min 0.03, max 1.0).
  • h: Height fraction (min 0.02, max 0.5).

Available Field Kinds:

  • "signature" (Mandatory for each signer)
  • "initials"
  • "date"
  • "text"
  • "checkbox"
  • "name"

Example Field Definition

"fields": [
  {
    "id": "fld_sig_1",
    "page": 0,
    "x": 0.10,
    "y": 0.75,
    "w": 0.40,
    "h": 0.08,
    "kind": "signature",
    "signer": 0
  },
  {
    "id": "fld_date_1",
    "page": 0,
    "x": 0.55,
    "y": 0.75,
    "w": 0.25,
    "h": 0.04,
    "kind": "date",
    "signer": 0
  }
]

Webhooks & Event Delivery

Configure up to 3 webhook endpoints in Desk > API. ChickenSign sends a POST request whenever an envelope transitions state.

envelope.sent

Envelope created and locked.

envelope.viewed

A signer clicked their signing link.

envelope.signed

A signer submitted their signature.

envelope.completed

All parties signed; certificate minted.

envelope.declined

A signer declined to sign.

envelope.voided

Sender voided the document.

envelope.bounced

A signer's invitation email bounced or was marked as spam.

Every event shares the same envelope payload. An envelope.bounced event does not name the signer: call GET /api/v1/envelopes/:id and look for the signer whose status is bounced.

HMAC Signature Verification

Every webhook contains the header ChickenSign-Signature: t=<unix>,v1=<hex>. Compute the HMAC-SHA256 of <timestamp>.<raw_body> with your secret to verify authenticity.

Node.js Signature Verification
import crypto from "node:crypto";

// Express / Fastify / Node raw body handler
function verifyChickenSignWebhook(rawBody, signatureHeader, secret) {
  // signatureHeader format: "t=1710000000,v1=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
  const parts = Object.fromEntries(
    signatureHeader.split(",").map(p => p.split("="))
  );
  const stamp = parts["t"];
  const signature = parts["v1"];

  // 1. Verify timestamp is fresh (within 5 minutes to prevent replay attacks)
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(stamp, 10)) > 300) {
    throw new Error("Webhook timestamp expired or out of bounds.");
  }

  // 2. Compute HMAC-SHA256 of '<stamp>.<rawBody>'
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${stamp}.${rawBody}`)
    .digest("hex");

  // 3. Constant-time comparison
  const valid = crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex")
  );

  return valid;
}

HTTP Status & Error Codes

CodeStatusMeaning / Solution
200OKRequest succeeded, or replayed via Idempotency-Key.
201CreatedEnvelope created and signing tokens generated.
400Bad RequestInvalid JSON, missing signature box, or duplicate signer emails.
401UnauthorizedMissing or invalid API key, or key has been revoked.
404Not FoundEnvelope ID does not exist or belongs to another account.
409ConflictCannot void a document that is already completed or voided.
413Payload Too LargeInline JSON request over 14 MB, or an uploaded PDF over 30 MB.
429Too Many RequestsRate limit of 60 req/min exceeded. Wait for Retry-After.

UK Legal Standing

Signatures executed via ChickenSign are simple electronic signatures under section 7 of the Electronic Communications Act 2000 and UK eIDAS regulations. Audit trails, timestamps, and SHA-256 fingerprints are cryptographically bound to each completed document. For details, read our UK Legal Guidance.