API docs

Integrations

Issue and check documents from the tools you already use.

Basics

Every call sends Authorization: Bearer lt_live_… (create a key under API & Webhooks). Read-only keys (documents:read) can list, search and subscribe to events; issuing, revoking and emailing need documents:write.

  • GET /v1/me — organisation name and key scopes (use to test a connection).
  • GET /v1/document-types and GET /v1/document-types/{code}/fields
  • POST /v1/documents — issue (send Idempotency-Key so retries never issue twice; file_url or file_base64 for upload types)
  • GET /v1/documents?code=… or ?external_ref=… — find
  • POST /v1/documents/{id}/revoke, POST /v1/documents/{id}/email
  • POST /v1/webhooks { url, events: [...] } → returns id and a one-time secret; DELETE /v1/webhooks/{id}
  • Polling: GET /v1/events (status changes), GET /v1/email-deliveries?status=bounced

Events: document.issued, document.revoked, document.suspended, document.reinstated, document.expired, document.superseded, document.status_changed, document.badge_issued, email.bounced.

Make (Integromat)

Issue a document — HTTP module

  1. Add HTTP → Make a request. URL https://lavishotrust.com/api/public/v1/documents, Method POST.
  2. Headers: Authorization = Bearer lt_live_…; Idempotency-Key = a unique id from the trigger (e.g. the row or file id).
  3. Body type Raw, content type JSON (application/json), Request content:
{
  "type_code": "CERT",
  "recipient_name": "{{1.name}}",
  "recipient_email": "{{1.email}}",
  "external_ref": "{{1.id}}",
  "fields": { "course": "{{1.course}}", "date": "{{formatDate(now; "YYYY-MM-DD")}}" },
  "file_url": "{{1.pdf_link}}",
  "source_app": "make"
}

Tick Parse response. The result has id, short_code and verify_url. To email the recipient, add another HTTP module: POST https://lavishotrust.com/api/public/v1/documents/{{2.data.id}}/email.

React to events — Custom webhook

  1. Add Webhooks → Custom webhook, create a hook and copy its address.
  2. Subscribe it once (HTTP module, or curl):
curl -X POST https://lavishotrust.com/api/public/v1/webhooks \
  -H "Authorization: Bearer lt_live_…" -H "Content-Type: application/json" \
  -d '{"url":"https://hook.eu1.make.com/…","events":["document.issued","document.revoked"]}'

Make cannot compute HMAC on the raw body in a Custom Webhook reliably, so either (a) treat the webhook as a "ping" and re-read the document: HTTP → GET https://lavishotrust.com/api/public/v1/documents?code={{1.data.short_code}} (authoritative data, comes from our API with your key), or (b) route the webhook through n8n / your server that checks the signature.

n8n

Issue a document — HTTP Request node

  1. Credentials → New → Header Auth: Name Authorization, Value Bearer lt_live_….
  2. HTTP Request: Method POST, URL https://lavishotrust.com/api/public/v1/documents, Authentication Generic → Header Auth, header Idempotency-Key = {{ $json.id }}, Body JSON like the Make example.

React to events — Webhook node + signature check

  1. Add a Webhook node (POST, Raw Body on). Copy its Production URL and activate the workflow.
  2. Subscribe that URL with POST /v1/webhooks (as above) and keep the returned secret.
  3. Add a Code node after it:
// n8n Code node (mode: Run once for each item), placed right after a Webhook node.
// Webhook node: HTTP Method POST, Options → "Raw Body" ON, Respond "Immediately".
const crypto = require('crypto');
const SECRET = 'whsec_…'; // from POST /v1/webhooks (or API & Webhooks page) — better: store in an n8n credential
const h = $json.headers;
const raw = Buffer.from($binary.data.data, 'base64').toString('utf8'); // raw body, byte-exact
const ts = h['x-lavisho-timestamp'];
const got = (h['x-lavisho-signature'] || '').replace(/^sha256=/, '');
const want = crypto.createHmac('sha256', SECRET).update(`${ts}.${raw}`).digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
if (!fresh || got.length !== want.length || !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want))) {
  throw new Error('Invalid Lavisho Trust signature');
}
return { json: JSON.parse(raw) }; // { event, created_at, data: { id, short_code, ... } }

Ready-made workflow: Google Drive new PDF → Issue in Lavisho Trust → email recipient (.json). In n8n: Workflows → Import from file, then connect your Google Drive and Header Auth credentials, choose the folder, and set TYPE_CODE in the “Build request” node.

Zapier

The Lavisho Trust Zapier app is private for now. Ask your Lavisho Trust contact for an invite link; after accepting, search for “Lavisho Trust” in the Zap editor and connect with an API key. Triggers: Document Issued, Document Revoked, Document Status Changed, Badge Issued, Email Bounced. Actions: Issue Document, Revoke Document, Send/Resend Recipient Email. Search: Find Document.