Documentation menu

API reference

Generated from the router. If an endpoint takes a field, it is in this table, because the table and the validator read the same declaration.

Base URL https://api.signsealer.com. Everything is JSON, everything takes Authorization: Bearer mk_live_…, and every response carries x-request-id.

Account

GET /v1/account

Scope signing:read

Show the account this key belongs to

The first call any integration makes: prove the credential works and show the operator the name of the account they just connected.

Templates

GET /v1/templates

Scope signing:read

List templates

Every version of every template, newest first, with whether each is published and how many documents were prepared from it.

POST /v1/templates

Scope signing:templates · takes an Idempotency-Key (templates.create)

Create a template

Creates version 1, as a draft. A template is not usable until it is published, and publishing is what freezes the text people will have signed.

FieldTypeConstraints
code string required matches ^[a-z][a-z0-9_-]*$
name string required 1–200 chars
kind "nda" | "waiver" | "contract" | "consent" | "policy" | "other" required
body string required 1–∞ chars
variables string[] optional
grants object optional
consent_text string | null optional

Documents

GET /v1/documents

Scope signing:read

List documents

Filter with status (a state, or open for draft and sent) and q (title, subject or signer).

GET /v1/documents/{id}

Scope signing:read

Show one document

The document, its signers, and the whole event trail with the text hash each event was made against.

POST /v1/documents

Scope signing:write · takes an Idempotency-Key (documents.prepare)

Prepare a document from a template

Renders the published template with the values given and stores the result on the document. Every declared variable needs a value: a contract that ships with a placeholder still in it is worse than one that failed to send.

FieldTypeConstraints
template_code string required
title string optional 0–200 chars
values object optional
expires_at string (date-time) | null optional
sequential boolean optional

POST /v1/documents/{id}/send

Scope signing:write · takes an Idempotency-Key (documents.send)

Send a document for signature

Returns one signing link per signer, once. The tokens are not stored, only their hashes, so a lost link is replaced by a reminder rather than looked up.

FieldTypeConstraints
signers object[] required 1–50 items

POST /v1/documents/{id}/void

Scope signing:write · takes an Idempotency-Key (documents.void)

Void a document

Needs a reason, which goes on the audit trail. An executed agreement cannot be voided: it is terminated by agreement, not by deletion.

FieldTypeConstraints
reason string required 1–500 chars

GET /v1/documents/{id}/certificate

Scope signing:read

Fetch the certificate of completion

Issued when the document completes, frozen at issue and hashed. still_matches_record re-derives it from the live record and reports any divergence rather than correcting it.

GET /v1/documents/{id}/pdf

Scope signing:read

Download the sealed PDF

The certificate as a PAdES-sealed PDF, with an RFC 3161 timestamp over the signature. Returns base64 bytes and the filename to save them under.

Workflows

GET /v1/workflows

Scope signing:read

List workflows

A workflow is a published template plus the rules for running it: who signs in what order, how long a link lives, and whether it has a public address.

POST /v1/workflows/{id}/start

Scope signing:workflows · takes an Idempotency-Key (workflows.start)

Start a workflow for one participant

Prepares the document, sends it to the participant and to every fixed role, and returns the tokens once.

FieldTypeConstraints
email string (email) required
full_name string required 1–200 chars
phone string optional 0–40 chars
fields object optional
values object optional
external_ref string optional 0–200 chars

Subjects

PUT /v1/subjects

Scope signing:subjects

Import a reservation or activity, and build its packet

Keyed on (provider, external_id), so importing the same reservation twice is one reservation, which is why this needs no idempotency key. Participants and the packet are built in the same call, because a caller who imported a reservation always wants to know what is now required.

FieldTypeConstraints
kind "reservation" | "activity" optional
provider string optional matches ^[a-z][a-z0-9_-]*$
external_id string required 1–200 chars
label string optional 0–200 chars
starts_on string required matches ^\d{4}-\d{2}-\d{2}$
ends_on string | null optional matches ^\d{4}-\d{2}-\d{2}$
facts object optional
participants object[] optional 0–60 items

Packets

GET /v1/packets/{id}

Scope signing:read

Show a packet

Who owes what, where each one has got to, and a readiness state a door lock can wait on.

POST /v1/packets/items/{id}/start

Scope signing:subjects · takes an Idempotency-Key (packets.start_item)

Start one packet item

Renders the item's workflow for the person who owes it. A minor's document is started for their guardian, because the guardian is who signs.

Webhooks

GET /v1/webhooks

Scope signing:webhooks

List webhook endpoints

POST /v1/webhooks

Scope signing:webhooks · takes an Idempotency-Key (webhooks.add)

Add a webhook endpoint

Returns the signing secret once and never again. It is sealed at rest; a caller who loses it replaces the endpoint.

FieldTypeConstraints
url string (uri) required matches ^https://
events string[] optional 1–30 items
label string optional 0–80 chars

PATCH /v1/webhooks/{id}

Scope signing:webhooks

Change a webhook endpoint

Turning an endpoint back on forgives its failure count.

FieldTypeConstraints
active boolean optional
events string[] optional 1–30 items
label string optional 0–80 chars

DELETE /v1/webhooks/{id}

Scope signing:webhooks

Remove a webhook endpoint

Needs ?reason=, which goes on the audit trail.

Sign

GET /v1/sign/{token}

Scope

Read a document from a signing link

Everything the signing page needs from one token: the text and its hash, who is being asked, who else is on it, whether it is this signer's turn, and — when it will not take a signature — why, in a sentence a person can read. Returns a body even for a token that matches nothing, so a bad link and an expired one fail identically.

POST /v1/sign/{token}/consent

Scope

Record consent to sign electronically

Must happen before the signature, and is its own event for that reason: ESIGN requires consent to precede the transaction, and a system that recorded both in the same instant could not show that it did.

FieldTypeConstraints
captured object optional

POST /v1/sign/{token}/fields

Scope

Supply a required field

Initials, a checkbox, a date. A signature is refused while anything required is unsupplied, and that refusal is in the database rather than in the form — so a second interface cannot go around it.

FieldTypeConstraints
key string required matches ^[a-z][a-z0-9_]{0,58}$
value string required 0–20000 chars
about string | null optional 0–200 chars

POST /v1/sign/{token}

Scope

Sign

Typed or drawn, both equally valid: what matters is intent. captured is for a signature taken where there was no network — the server records when it received it and keeps the device's claim beside it, with the clock skew computed rather than accepted.

FieldTypeConstraints
method "typed" | "drawn" | "clicked" | "uploaded" required
value string required 1–400000 chars
captured object optional

POST /v1/sign/{token}/decline

Scope

Decline to sign

With a reason. A decline is a person saying no, which is not the same as still waiting — a packet containing one is blocked rather than outstanding, so nobody chases somebody who already answered.

FieldTypeConstraints
reason string required 1–500 chars

Verify

GET /v1/verify/{code}

Scope

Check a certificate by its printed code

Anonymous, because the point is that a stranger holding a printed page can check it. Answers three separate questions: whether the certificate exists, whether a document you hold matches it, and whether it still matches the record behind it. The third is a finding, never a correction.

Ready to build? An API key takes a minute in the portal, and the free plan covers the first 25 agreements a month.

Get an API key