Skip to content

API Quickstart

This guide walks you through creating a container, adding a document with clauses, publishing it, and sending a signing request — all via the REST API.

  • A TheTerms account with an organisation
  • An API key (see Authentication)
  • curl or any HTTP client

Set your API key as an environment variable for the examples below:

Terminal window
export THETERMS_API_KEY="tt_your_api_key_here"
export THETERMS_URL="https://app.theterms.app/api/v1"
  1. Create a container

    Containers group related documents. Create one for your Terms of Service:

    Terminal window
    curl -X POST "$THETERMS_URL/containers" \
    -H "X-Api-Key: $THETERMS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name": "Website Agreements", "description": "All website legal documents"}'

    Response:

    {
    "data": {
    "id": "clx1abc...",
    "name": "Website Agreements",
    "description": "All website legal documents",
    "org_id": "clx0org...",
    "created_by": "clx0usr...",
    "created_at": "2026-02-21T10:00:00.000Z",
    "updated_at": "2026-02-21T10:00:00.000Z"
    }
    }

    Save the id — you will need it in the next step.

  2. Create a document

    Create a document inside the container. containerId goes in the body — documents are not nested under /containers/{id}/documents. It starts as a draft (version 1):

    Terminal window
    curl -X POST "$THETERMS_URL/documents" \
    -H "X-Api-Key: $THETERMS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"containerId": "clx1abc...", "name": "Terms of Service"}'

    Save the document id from the response.

  3. Update the draft with clauses

    Add clauses to the document’s current draft version. The endpoint resolves the draft internally — there’s no version ID in the path:

    Terminal window
    curl -X PUT "$THETERMS_URL/documents/{documentId}/draft" \
    -H "X-Api-Key: $THETERMS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "content": {
    "clauses": [
    {
    "id": "clause-1",
    "order": 0,
    "title": "Acceptable Use",
    "content": "You agree to use the service only for lawful purposes.",
    "is_mandatory": true,
    "default_checked": false,
    "slug": "acceptable-use"
    },
    {
    "id": "clause-2",
    "order": 1,
    "title": "Marketing Communications",
    "content": "We may send you promotional emails about new features.",
    "is_mandatory": false,
    "default_checked": false,
    "slug": "marketing-communications"
    }
    ]
    },
    "settings": {
    "expiry_days": 30,
    "redirect_url": null
    }
    }'
  4. Publish the version

    Publishing makes the document’s current draft active and available for signing:

    Terminal window
    curl -X POST "$THETERMS_URL/documents/{documentId}/publish" \
    -H "X-Api-Key: $THETERMS_API_KEY"
  5. Send a signing request

    Signing requests are a top-level resource, not nested under the document. versionId (the published version’s ID, from the previous step’s response) is required in the body:

    Terminal window
    curl -X POST "$THETERMS_URL/signing-requests" \
    -H "X-Api-Key: $THETERMS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "versionId": "clx2def...",
    "signerName": "Jane Doe",
    "signerEmail": "jane@example.com"
    }'

    Response:

    {
    "data": {
    "requestId": "clx3ghi...",
    "token": "a1b2c3...",
    "isNew": true,
    "emailSent": true
    }
    }

    The signer receives an email with a unique link to review and sign the document. No account creation is required.

  6. Check signing status

    List signing requests for a version:

    Terminal window
    curl "$THETERMS_URL/signing-requests?versionId=clx2def..." \
    -H "X-Api-Key: $THETERMS_API_KEY"

    Each request includes a status field — PENDING, ACCEPTED_FULL, ACCEPTED_PARTIAL, REJECTED, VOIDED, or EXPIRED — and clause-level responses once the signer decides. “Viewed” is tracked separately as an audit event, not as a request status.