Last updated: April 28, 2026

Chaindoc REST API reference

Full endpoint reference for the Chaindoc REST API. Covers authentication, documents, signatures, media uploads, embedded sessions, and blockchain verification.

Overview

The API gives you programmatic access to everything in Chaindoc: documents, signatures, blockchain verification, and team management. It's designed for server-to-server use and supports both public and secret API keys. Learn more in the RFC 9110 — HTTP Semantics.

  • Documents: create, update, and verify documents on the blockchain
  • Signatures: send signature requests and track completion
  • Media: upload PDFs, images, and videos (max 10 per request)
  • Contracts: draft, send, cancel, and terminate contracts with optional payment terms
  • Invoices & Transactions: bill contragents, charge saved payment methods, track settlements
  • Templates: render documents, signature requests, and contracts from published templates
  • Embedded sessions: create signing sessions for your frontend (uses the Embed SDK)

Authentication

Every request needs an API key in the Authorization header. There are two types:. Learn more in the RFC 6749 — OAuth 2.0.

Key types

  • Public key (`pk_`). read-only, safe for frontend code
  • Secret key (`sk_`). full read/write, backend only. Never expose in client-side code.

Getting your keys

1Subscribe to Business planOnly Business plan users can create API keys

2Navigate to API AccessGo to Settings → API Access in your dashboard

3Create API keyClick Create API Key button

4Store securelyStore the secret key securely (shown only once)

Using API keys

Include your API key in the Authorization header with Bearer authentication:

terminal
curl -X GET https://api.chaindoc.io/api/v1/me \
  -H "Authorization: Bearer sk_xxxxxxxxxxxxx"

Rate limiting

All public API endpoints are limited to 10 requests per 60 seconds per API key. When the limit is exceeded, you'll receive a 429 Too Many Requests response. back off and retry after a short delay.

Error handling

HTTP status codes

  • 200 - Success
  • 201 - Resource created successfully
  • 400 - Bad request (validation error)
  • 401 - Unauthorized (invalid or missing API key)
  • 403 - Forbidden (insufficient permissions)
  • 404 - Resource not found
  • 429 - Too many requests (rate limit exceeded)
  • 500 - Internal server error

Error response format

terminal
{
  "statusCode": 400,
  "message": [
    "name must be a string",
    "recipients should not be empty"
  ],
  "error": "Bad Request"
}

Validation errors return `message` as an array of human-readable strings, one per failed constraint. For non-validation errors (401, 403, 404, 500), `message` is a single string.

General API

Get API key info

Get information about the current API key.

GET /me

Authorization: Bearer sk_xxxxx

Health check

Verify API connectivity and key validity.

GET /health

Authorization: Bearer sk_xxxxx

Documents API

Create document

Create a new document with blockchain verification. When status is set to 'published', the document is automatically verified on blockchain.

POST /documents

Headers:
Authorization: Bearer sk_xxxxx
Content-Type: application/json

Update document

Update a document by creating a new version. Previous versions are preserved for audit trail.

PUT /documents/:documentId

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Update document access rights

Update document access control settings.

PUT /documents/:documentId/rights

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Verify document

Verify document authenticity using blockchain. Returns verification status with transaction hash and chain ID.

POST /documents/verify

Authorization: Bearer pk_xxxxx
Content-Type: application/json

{
  "versionHash": "0x123abc...",
  "certificateHash": "0x456def..."
}

Get verification status

Get blockchain verification status for a document version.

GET /documents/versions/:versionId/verification

Authorization: Bearer sk_xxxxx

Signatures API

Create signature request

Create a signature request for one or more recipients. Enable embedded flow for frontend integration.

curl -X POST https://api.chaindoc.io/api/v1/signatures/requests \
  -H "Authorization: Bearer sk_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "versionId": "f0b7721f-0399-4035-9b69-7b95d3a367f0",
    "recipients": [
      { "email": "signer@example.com", "signingMethod": "embedded" }
    ],
    "deadline": "2026-12-31T23:59:59Z",
    "embeddedFlow": true,
    "isKycRequired": false
  }'

Pre-placed fields (advanced). If you upload your own PDF and want exact control over where signature, initials, date, text, or checkbox fields appear, pass an optional `fields` array alongside `versionId`. When you render a document from a template (see Templates API below), placed fields come from the template definition automatically. skip this option.

terminal
{
  "fields": [
    {
      "signerEmail": "signer@example.com",
      "fieldType": "signature",
      "pageIndex": 0,
      "xPct": 0.15,
      "yPct": 0.78,
      "wPct": 0.25,
      "hPct": 0.05,
      "required": true,
      "label": "Client signature"
    },
    {
      "signerEmail": "signer@example.com",
      "fieldType": "date_signed",
      "pageIndex": 0,
      "xPct": 0.45,
      "yPct": 0.78,
      "wPct": 0.15,
      "hPct": 0.03
    }
  ]
}

Get signature request status

Check the status of a signature request and see which signers have completed signing.

GET /signatures/requests/:requestId/status

Authorization: Bearer sk_xxxxx

Sign document

Sign a document (if API key owner is a signatory).

POST /signatures/sign

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Get user signatures

Get all signatures for the authenticated user.

GET /signatures?pageNumber=1&pageSize=10

Authorization: Bearer sk_xxxxx

Get signature requests

Get all signature requests for the authenticated user with pagination support.

GET /signatures/requests?pageNumber=1&pageSize=10

Authorization: Bearer sk_xxxxx

Media upload API

Upload files for use in document creation. Supports PDF, images, and videos. Maximum 10 files per request.

curl -X POST https://api.chaindoc.io/api/v1/media/upload \
  -H "Authorization: Bearer sk_xxxxx" \
  -F "media=@contract.pdf"

Contracts API

Create and manage contract lifecycles from draft through signing, active, and termination. Each contract wraps a document, contragent info, optional payment terms, and a signing policy. Payment-enabled contracts require a Stripe Connect account. see the security guide for setup.

Create contract

Create a contract in `draft` status from an existing document. Payment terms are optional. you can add them later via payment setup.

POST /contracts

Authorization: Bearer sk_xxxxx
Content-Type: application/json

List contracts

List contracts created via the API, with pagination and optional status/search filters.

GET /contracts?page=1&limit=10&status=active&search=acme

Authorization: Bearer sk_xxxxx

Get contract

Fetch full contract details including payment terms, signing status, and contragent info.

GET /contracts/:contractId

Authorization: Bearer sk_xxxxx

Get contract status

Lightweight endpoint for monitoring contract lifecycle without fetching the full payload. Returns current status, signing progress, and a payment summary.

GET /contracts/:contractId/status

Authorization: Bearer sk_xxxxx

Get contract activities

Paginated activity log (created, sent, signed, amended, terminated, etc.) for audit and webhook reconciliation.

GET /contracts/:contractId/activities?page=1&limit=20

Authorization: Bearer sk_xxxxx

Set up payment terms

Attach or replace payment terms on a `draft` contract. Useful when you create the contract shell first and configure billing separately.

POST /contracts/:contractId/payment-setup

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Send contract for signing

Transition a `draft` contract to `pending_signature` and notify both parties. All body fields are optional.

POST /contracts/:contractId/send

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Cancel contract

Cancel a `draft` contract (never sent) or a `pending_signature` contract before anyone signs. Irreversible.

POST /contracts/:contractId/cancel

Authorization: Bearer sk_xxxxx

Terminate contract

Terminate an `active` contract. For `mutual_approval` contracts this initiates a `termination_pending` flow where the other party must confirm; for `one_side` contracts it terminates immediately.

POST /contracts/:contractId/terminate

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Contract Invoices API

Bill contragents on an `active` contract. Invoices can be auto-generated from recurring payment terms or created manually for ad-hoc billing. Charging saved payment methods is supported for Stripe-enabled contracts.

Create invoice

Create a manual invoice on an `active` contract. Set `sendImmediately: true` to dispatch to the contragent right away, and `autoCharge: true` to charge their saved payment method when sent.

POST /contracts/:contractId/invoices

Authorization: Bearer sk_xxxxx
Content-Type: application/json

List contract invoices

List all invoices for a contract with pagination and optional status filter.

GET /contracts/:contractId/invoices?page=1&limit=10&status=unpaid

Authorization: Bearer sk_xxxxx

Get invoice

Fetch full invoice details including line items, transactions, and Stripe checkout URL if applicable.

GET /contracts/:contractId/invoices/:invoiceUuid

Authorization: Bearer sk_xxxxx

Send invoice

Send a `draft` invoice to the contragent. Set `autoCharge: true` to attempt immediate charge of a saved payment method.

POST /contracts/:contractId/invoices/:invoiceUuid/send

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Charge invoice

Charge an already-sent invoice using the contragent's saved payment method. Used to retry failed payments or charge on demand.

POST /contracts/:contractId/invoices/:invoiceUuid/charge

Authorization: Bearer sk_xxxxx

Mark invoice as paid

Record an offline/external settlement. wire transfer, cash, or payment through another rail. A manual transaction is recorded for audit.

POST /contracts/:contractId/invoices/:invoiceUuid/mark-paid

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Transactions API

Read payment transactions linked to contract invoices. Transactions capture every charge attempt (successful, failed, or pending) along with Stripe fee breakdown, net amount, and retry history.

List contract transactions

List all transactions for a contract across its invoices.

GET /contracts/:contractId/transactions

Authorization: Bearer sk_xxxxx

Get transaction

Fetch a single transaction by UUID with full details: amounts, fees, receipt URL, and retry metadata.

GET /transactions/:transactionUuid

Authorization: Bearer sk_xxxxx

Templates API

Render a published template into a draft document, a signature request, or a contract. passing variable values and slot assignments. The template system supports per-signer variables and role-based slot assignment for contract templates.

Create document from template

Render a template with variables and create a new draft document. Slot assignments aren't needed here. this endpoint only produces the document shell.

POST /templates/:templateId/documents

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Create signature request from template

Render a template, create the document, and immediately send it for signing. Each `slotAssignment` binds a template signer key to a real recipient email.

POST /templates/:templateId/signature-requests

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Create contract from template

Render a contract template with variables and contragent info, creating a contract and sending it for signing in one call. Slot assignments bind template signer keys to roles (`business` | `contragent`). emails are taken from API key owner (for business) and `contragent.email`.

POST /templates/:templateId/contracts

Authorization: Bearer sk_xxxxx
Content-Type: application/json

Embedded sessions API

Create embedded sessions for document or contract signing in your frontend application. Sessions are valid for 10 minutes. For standalone document signing, pass both `documentId` and `signatureRequestId` in `metadata`. For contract signing, pass `contractId` and Chaindoc resolves the active signing request.

POST /embedded/sessions

Authorization: Bearer sk_xxxxx
Content-Type: application/json

What to do next

  • API integration. common patterns, best practices, and full workflow examples
  • SDKs. Server SDK and Embed SDK with framework-specific guides
  • Webhooks. set up real-time event notifications
  • Installation. npm setup for all supported frameworks
  • Security. API key management and compliance