TrustInk API

Send documents for legally-binding e-signature, route them to multiple signers, track status, download the completed PDF with its audit trail, and get real-time webhooks — all over a simple REST API.

Authentication

The API authenticates with an API key. Create one in the TrustInk app under Settings → API keys. Keys look like tk_live_… and are shown once — store it securely.

Send it on every request as a Bearer token (or the X-Api-Key header):

curl https://api.trustink.cloud/v1/envelopes \
  -H "Authorization: Bearer tk_live_your_key_here"
Keep API keys server-side. Anyone with your key can send documents on your account. Rotate a key by deleting it in the app and creating a new one.

Base URL & versioning

All endpoints are under the versioned base:

https://api.trustink.cloud/v1

Requests and responses are JSON (documents travel as base64). We version by URL prefix; breaking changes ship under a new prefix.

Create & send an envelope

POST/v1/envelopes

Creates an envelope from a PDF, places fields for each signer, and (by default) sends it. Set "send": false to create a draft.

Body parameters

FieldTypeDescription
docName requiredstringFile name shown to signers, e.g. "NDA.pdf".
docB64 requiredstringThe PDF, base64-encoded.
signers requiredarrayOne or more recipients — see Signers.
fieldsarrayField placements bound to a signer — see Fields.
subjectstringEmail subject for the signing request.
messagestringMessage included in the signing email.
signingModestringsequential (default) or parallel.
reminderDaysintegerReminder cadence in days. 0 disables reminders.
expiresAtstringISO-8601 expiry timestamp (optional).
sendbooleanSend immediately (default true).

Example

curl -X POST https://api.trustink.cloud/v1/envelopes \
  -H "Authorization: Bearer tk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "docName": "NDA.pdf",
    "docB64": "JVBERi0xLjc…",
    "subject": "Please sign: Mutual NDA",
    "signingMode": "sequential",
    "reminderDays": 3,
    "signers": [
      { "email": "alice@acme.com", "name": "Alice", "roleLabel": "Discloser" },
      { "email": "bob@example.com", "name": "Bob", "roleLabel": "Recipient" }
    ],
    "fields": [
      { "signerIndex": 0, "page": 1, "x": 0.12, "y": 0.82, "w": 0.25, "h": 0.05, "type": "signature" },
      { "signerIndex": 1, "page": 1, "x": 0.55, "y": 0.82, "w": 0.25, "h": 0.05, "type": "signature" }
    ]
  }'
201 Created
{
  "envelope": {
    "id": "env_…", "status": "sent", "doc_name": "NDA.pdf",
    "signing_mode": "sequential",
    "signers": [
      { "email": "alice@acme.com", "status": "sent", "sign_url": "https://app.trustink.cloud/sign/…" },
      { "email": "bob@example.com", "status": "pending" }
    ]
  }
}

List envelopes

GET/v1/envelopes

Returns your envelopes, newest first. Filter with ?status= (draft, sent, signed, declined, voided, expired).

curl "https://api.trustink.cloud/v1/envelopes?status=sent" \
  -H "Authorization: Bearer tk_live_your_key_here"

Get an envelope

GET/v1/envelopes/:id

Full status including every signer and field.

curl https://api.trustink.cloud/v1/envelopes/env_123 \
  -H "Authorization: Bearer tk_live_your_key_here"

Download the document

GET/v1/envelopes/:id/document

Returns the PDF bytes (application/pdf). Once complete this is the signed document, with the certificate-of-completion page and a tamper-evident SHA-256; before completion it's the original.

curl https://api.trustink.cloud/v1/envelopes/env_123/document \
  -H "Authorization: Bearer tk_live_your_key_here" \
  -o signed.pdf

Void an envelope

POST/v1/envelopes/:id/void

Cancels an in-flight envelope. Signers can no longer act on it.

curl -X POST https://api.trustink.cloud/v1/envelopes/env_123/void \
  -H "Authorization: Bearer tk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Superseded by a new version" }'

Fields & signers

Signer object

FieldTypeDescription
email requiredstringRecipient email.
namestringRecipient name.
roleLabelstringRole shown in the UI/certificate, e.g. "Buyer".
signOrderintegerOrder for sequential signing (1-based).
authMethodstringnone (default) or code (access-code required).
accessCodestringRequired when authMethod is code.

Field object

Coordinates are normalized 0–1 from the top-left of the page, so they're resolution-independent.

FieldTypeDescription
signerIndex requiredintegerIndex into signers[] this field belongs to.
page requiredinteger1-based page number.
x, y, w, h requirednumberPosition and size, each 0–1.
type requiredstringsignature, initials, date, text, checkbox, dropdown.
labelstringField label / placeholder.
requiredbooleanWhether the signer must complete it.
optionsarrayChoices for a dropdown.

Webhooks

Add an endpoint under Settings → Webhooks. TrustInk POSTs JSON when envelope state changes. Each request carries:

HeaderDescription
X-TrustInk-EventThe event name (below).
X-TrustInk-Signaturesha256=<hex> — HMAC-SHA256 of the raw body using your webhook secret.

Events

EventFires when
envelope.sentAn envelope is sent to its first signer(s).
envelope.signedA signer completes their part.
envelope.completedAll signers have signed; the final PDF is ready.
envelope.declinedA signer declines.
envelope.expiredAn envelope passes its expiry.

Verify the signature (Node)

const crypto = require('crypto');
function verify(rawBody, header, secret) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}
Compute the HMAC over the raw request body before any JSON parsing. Deliveries retry with backoff on non-2xx responses.

Errors

Standard HTTP status codes; the body is { "error": "message" }.

StatusMeaning
400Missing or invalid parameters.
401Missing or invalid API key.
403Not permitted (e.g. no verified sending domain, or plan quota reached).
404Envelope not found.
429Rate limited.

Rate limits & quotas

Sends are metered against your plan's monthly envelope quota (Free / Starter / Business / Enterprise). A 403 on create means the quota is reached — upgrade in the app. Before you can send, your account must have a verified sending domain (Settings → Domains).

TrustInk — by ThreatShield. Questions? Your account team, or the in-app help. This reference covers the public /v1 API; the portal has additional account-management endpoints.