Overview

Termitude API

The Termitude API lets you publish policies and legal documents, fetch the current published version, and record user consent — all backed by a tamper-evident ledger. Every request is versioned, every accept is hashed, and every change is auditable.

Base URL
https://api.termitude.com
Version
v1
Format
JSON
5 minutes

Quickstart

  1. 1

    Create a document

    In the dashboard, open Documents → New, give it a slug like terms, and publish your first version.
  2. 2

    Generate an API key

    Go to Settings → API Keys and create a key. Store the secret — it's only shown once.
  3. 3

    Fetch the current version

    bash
    curl https://api.termitude.com/api/public/v1/documents/terms \
      -H "Authorization: Bearer sk_live_..."
  4. 4

    Record consent

    bash
    curl -X POST https://api.termitude.com/api/public/v1/consent \
      -H "Authorization: Bearer sk_live_..." \
      -H "Content-Type: application/json" \
      -d '{
        "document_slug": "terms",
        "subject_id": "user_123",
        "subject_email": "alex@acme.com"
      }'
Auth

Authentication

All API requests use bearer tokens. Keys are scoped to a single organisation. The secret is hashed at rest — you'll only see it once at creation. Treat keys like passwords; rotate them when a teammate leaves.

http
Authorization: Bearer sk_live_a1b2c3d4...
Test keys
sk_test_…

Sandbox traffic. Free, rate-limited.

Live keys
sk_live_…

Production traffic. Counts toward plan limits.

Reference

Documents API

GET/api/public/v1/documents/:slug

Fetch the current published version of a document.

bash
curl https://api.termitude.com/api/public/v1/documents/terms \
  -H "Authorization: Bearer sk_live_..."
GET/api/public/v1/documents/:slug/log

List published versions with summaries and effective dates.

Drop-in

Embeds

Drop a single tag into your site to render the current version of a document, with optional auto re-consent prompts.

html
<div data-termitude="terms" data-org="acme"></div>
<script src="https://cdn.termitude.com/embed.js" async></script>
Events

Webhooks

Subscribe to events to sync versions or consent records into your own systems. Payloads are signed with HMAC-SHA256 — verify theX-Termitude-Signature header.

EventDescription
version.publishedA new document version went live.
version.scheduledA version was queued for a future effective date.
consent.recordedA user accepted a document.
consent.outstandingRe-consent window opened for existing users.
document.archivedA document was retired.
Libraries

Official SDKs

@termitude/node
Node.js / TypeScript
npm i @termitude/node
@termitude/react
React component + hooks
npm i @termitude/react
termitude-python
Python 3.9+
pip install termitude
termitude-go
Go 1.21+
go get github.com/termitude/go
Bring your own domain

Custom Domains

Customers can point their own domain (e.g. app.acme.com) at Termitude. Behind the scenes we issue and renew TLS certificates automatically via Let's Encrypt — the customer just sets DNS records once and never touches them again.

DNS records the customer adds

Two records: one CNAME to route traffic, and one_acme-challenge CNAME so we can answer ACME challenges on their behalf for every issuance and renewal.

dns
CNAME  app                  app.<your-domain>.
CNAME  _acme-challenge.app  app.<your-domain>.<dcv-target>.dcv.cloudflare.com.

Replace app with whatever subdomain the customer is using. For an apex domain, the challenge record is just_acme-challenge. The exact<dcv-target> value is shown in your Termitude dashboard when you add the hostname.

Why the second record (DCV Delegation)

Without the _acme-challenge CNAME, the customer would have to add a fresh TXT record every time a certificate is issued or renewed (every ~60–90 days). With it, we answer all ACME challenges ourselves — first issuance and every future renewal — and the customer never has to touch DNS again.

When you need it

  • ✅ Customer domains hosted outside Cloudflare (most common).
  • ✅ Cloudflare-hosted domains running DNS-only / unproxied (grey cloud).
  • ✅ Wildcard custom hostnames such as *.customer.com — effectively required.
  • Not required when the customer's domain is on Cloudflare and proxied (orange cloud) — those validate automatically.

Troubleshooting

  • Certificate stuck pending → confirm both CNAMEs resolve with dig; DNS can take up to an hour to propagate.
  • Renewals failing months later → the _acme-challenge record was removed. Re-add it.
  • CAA records present on the apex → make sure they allow letsencrypt.org.
Reference

Errors

StatusCodeMeaning
400invalid_requestMalformed JSON or missing required fields.
401unauthenticatedMissing or invalid API key.
403forbiddenKey lacks permission for this resource.
404not_foundDocument or version does not exist.
409version_conflictA newer version exists; refetch and retry.
429rate_limitedSlow down — retry after the Retry-After header.
500internal_errorSomething went wrong on our side.

Ready to ship?

Explore features or check pricing to get started.