Skip to content
Last updated

Platform API

Overview

The Platform API integrates the Docue.com platform into your system. Everything you do through the API happens inside your Docue workspace: documents you draft, send for signing, or upload are all available when you log in at https://app.docue.com.

With the Platform API you can:

  • Draft documents from your workspace's templates, prefill their values programmatically, and finalize them for signing.
  • Send an existing PDF out for electronic signing in a single request.
  • Manage the workspace archive: list, fetch, download, and delete documents, and organize them into folders.

Please note that this is a separate product from the Embed API. The Platform API works against your Docue.com workspace. If you instead want to embed Docue's document-building UI into your own branded product, without a Docue.com account, see the Embed API.

Prerequisites

To use this API you need an API key tied to a Docue.com workspace. If you do not have one yet, please contact us at support@docue.com.

All endpoints require Bearer authentication. Include the API key in the Authorization header of every request:

Authorization: Bearer <api_key>

The production base URL is https://api.docue.com/public/v2. A good first call is Get current workspace — it returns the workspace tied to your key and is the simplest way to verify that authentication is configured correctly.

See the API Reference for the full list of endpoints.

Guide

The Platform API is organized around a few core resources. Understanding how they relate makes the rest of the API straightforward.

Core concepts

  • Workspace — the account your API key belongs to. Everything you create lives inside it and shows up at app.docue.com.
  • Folder — a container in the archive. Every document lives in a folder, and folders can be nested. Your workspace has a root_folder_id you can build under.
  • Document — an item in the archive (a drafted contract, an uploaded PDF, a signed agreement). You can download a document's file content with Download document.
  • Contract — the signing- and drafting-related state behind a document: its stage, signing method, builder state, and signatures. A document points to its contract via contract_id.
  • Template — a reusable, lawyer-maintained starting point for a new document. Templates are managed for your workspace; you start documents from them.
  • Webhook — a subscription that pushes notifications to your own systems when something happens in the workspace (a document is created, a contract is completed, and so on). See Webhooks.

contract_id

start

Workspace

Folder

Document

Contract

Template

Signatures

Builder state

contract_id

start

Workspace

Folder

Document

Contract

Template

Signatures

Builder state

The contract id vs. the document id

The single most common integration gotcha: the builder endpoints are keyed by the contract id, not the document id.

When you start a document from a template, the response is a document. That document carries a contract_id field. The drafting endpoints — GET/PATCH /contracts/{id}/builder/state, /builder/value-schema, /builder/sections, and /builder/finalize — all expect that contract_id as their {id}, not the document's own id. Conversely, the document endpoints (/documents/{id}, download) use the document id.

When you send a PDF for signing it is the other way around: the response is a contract, and you use its document_id to work with the document later.

Contract lifecycle

A contract moves through a small set of stages. Most endpoints care about whether the contract is still editable (created) or already locked.

start from template

finalize (canvas / strong)

finalize (manual / no signees)

all parties sign

not signed before due date

created

finalized

completed

cancelled

start from template

finalize (canvas / strong)

finalize (manual / no signees)

all parties sign

not signed before due date

created

finalized

completed

cancelled

While a contract is in the created stage you can freely read and patch its builder state. Once it is finalized or completed, the content is locked. You can still read the builder state for 24 hours after finalization; after that, Get contract builder state returns 410 Gone.

Drafting a document from a template

This is the richest flow. You start a draft from a template, optionally prefill its fields, and then finalize it for signing — all without anyone opening the builder UI.

Platform APIIntegratorPlatform APIIntegratorGET /templates?filter[type]=tailoredList of templates (id, builder_version)POST /templates/{template_id}/start (folder_id, title)Document (note its contract_id)GET /contracts/{contract_id}/builder/stateCurrent values, sections, appearancePATCH /contracts/{contract_id}/builder/state (operations)Updated statePOST /contracts/{contract_id}/builder/finalizeFinalized contract (stage = finalized, document_id)
Platform APIIntegratorPlatform APIIntegratorGET /templates?filter[type]=tailoredList of templates (id, builder_version)POST /templates/{template_id}/start (folder_id, title)Document (note its contract_id)GET /contracts/{contract_id}/builder/stateCurrent values, sections, appearancePATCH /contracts/{contract_id}/builder/state (operations)Updated statePOST /contracts/{contract_id}/builder/finalizeFinalized contract (stage = finalized, document_id)

Step by step:

  1. List templates with List templates. The filter[type]=tailored parameter is required. Note each template's builder_version (see the callout below).
  2. Start a document with Create document from template, passing the target folder_id and a title. The response is a document in the created stage; grab its contract_id.
  3. Read the builder state with Get contract builder state to see the current value, sections, and appearance.
  4. Prefill values with Update contract builder state using JSON Patch operations (see Working with the builder state below).
  5. Finalize with Finalize contract to lock the document and start signing.

Hand off to the builder UI (optional). You do not have to finalize through the API. After creating the contract — and optionally prefilling some values — you can let the end-user complete the document in Docue's builder UI instead. Each contract exposes a builder_url for this: fetch it with GET /documents/{id}?include=contract (it is contract.builder_url) and redirect the user there. A common pattern is to prefill the values you already know via the API, then send the user to builder_url to review, fill in the rest, and finalize. Opening the link requires Docue credentials and access to the document.

Builder 2.0 is required for the builder endpoints. The /contracts/{id}/builder/* endpoints only work for contracts whose builder_version is "2". Starting from a template that uses an older builder produces a builder_version of "1", and the builder endpoints return 409 Conflict. Check builder_version on the template (and on the contract) before relying on these endpoints. You can include the contract on a document response with ?include=contract to read its builder_version and stage.

Working with the builder state

The builder state is the source of truth for a document's field values, its sections, and its visual appearance. You update it with JSON Patch (RFC 6902) operations via Update contract builder state.

Key behavior:

  • Batch updates — you can send multiple operations in a single request.
  • Sequential execution — operations are applied in the order they appear (top to bottom), so later operations can build on earlier ones.
  • Editable only — patching is only allowed while the contract is in the created stage and builder_version is "2". Otherwise the endpoint returns 409 Conflict.

Before sending values, familiarize yourself with the response shape of Get contract builder state. The value object holds all field values, and its schema is defined by the template.

The shape of value

The value object consists of fieldsets and fields. Each root-level key is a fieldset. A fieldset is a collection of fields and can be either non-repeatable (an object, like basic) or repeatable (an array of objects, like parties).

{
  "_type": "value",
  "_id": "0196ae5b-2e9d-729f-aba5-fca3d9d646a4",
  "basic": {
    "_type": "value",
    "_id": "0196ae5b-2e9d-729f-aba6-03235f09a720",
    "title": {
      "_type": "translatable",
      "en-GB": "Employment Agreement"
    }
  },
  "parties": [
    {
      "_type": "value",
      "_id": "0196ae5b-2e9d-729f-aba6-07fd964cae09",
      "type": "company",
      "company_name": "Docue",
      "first_name": "John",
      "last_name": "Doe"
    }
  ]
}

Notes when constructing values:

  • Translatable text — many fields are localized. Provide them as a translatable object whose keys are the document's language codes (for example { "_type": "translatable", "en-GB": "Employment Agreement" }). The document's languages are listed in the state's languages array.
  • Identifiers — every fieldset instance has an _id (a UUIDv7). When adding a new fieldset instance, generate a fresh UUIDv7 for its _id.
  • Schema — the exact set of fieldsets and fields depends on the template. Use the (experimental) Get contract builder value schema endpoint to discover the structure and validation rules of the value before writing to it.

Tip: To append a new item to the end of a repeatable fieldset, use the path /value/<fieldset>/-, for example /value/parties/-.

Examples

Update a field value
PATCH /contracts/{id}/builder/state

{
  "operations": [
    {
      "op": "replace",
      "path": "/value/basic/title",
      "value": {
        "_type": "translatable",
        "en-GB": "Employment Agreement (revised)"
      }
    }
  ]
}
Add and remove repeatable fieldset instances
PATCH /contracts/{id}/builder/state

{
  "operations": [
    {
      "op": "add",
      "path": "/value/parties/-",
      "value": {
        "_type": "value",
        "_id": "0196ae5b-2e9d-729f-aba6-07fd964cae10",
        "type": "person",
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "jane.doe@example.org"
      }
    },
    {
      "op": "remove",
      "path": "/value/parties/0"
    }
  ]
}
Update the document appearance

Typography, logo, and footer settings live under /appearance. Patch individual properties or replace the whole object.

PATCH /contracts/{id}/builder/state

{
  "operations": [
    {
      "op": "replace",
      "path": "/appearance/footer",
      "value": {
        "enabled": true,
        "content": "Acme Inc."
      }
    }
  ]
}

Finalizing and sending for signing

When the draft is ready, finalize it with Finalize contract. Finalizing locks the content and moves the contract out of the editable created stage.

The signees are parsed automatically from the builder state, including the contact details found for each of them. How each signee is invited depends on those contacts:

  • email only → invited by email,
  • phone only → invited by SMS,
  • both → invited by both.

Two parameters control finalization:

  • signature_methodcanvas for drawn signatures, strong for strong electronic identification, or manual to complete the document without electronic signing.
  • send_invitations — when true, invitations are dispatched immediately. When false, the contract is finalized but no invitations are sent (you can send them later from app.docue.com).

The resulting stage tells you what happened:

  • finalized — the contract is locked and awaiting signatures.
  • completed — the document was completed without signing. This happens when there were no signees in the builder state, or when signature_method is manual.

Sending an existing PDF for signing

If you already have a finished PDF and just want signatures, you do not need the builder flow at all. Send PDF for signing uploads a PDF, creates the signees, and finalizes the contract for signing — in a single request.

SigneePlatform APIIntegratorSigneePlatform APIIntegratoropt[send_invitations = true]POST /contracts (multipart: file + parties)Contract (stage = finalized, document_id)Signing invitation (email / SMS)Signs the documentGET /documents/{document_id}/downloadSigned PDF
SigneePlatform APIIntegratorSigneePlatform APIIntegratoropt[send_invitations = true]POST /contracts (multipart: file + parties)Contract (stage = finalized, document_id)Signing invitation (email / SMS)Signs the documentGET /documents/{document_id}/downloadSigned PDF

Key points:

  • The request must be multipart/form-data because it includes a file upload. Only PDF files are accepted, and the maximum size is 13 MB per file. Optional attachments (up to 10) are merged with the primary file into a single document before signing.
  • Provide at least one party in parties[]. A party with an email is invited by email, one with a phone by SMS, and one with both by both. Use send_invitations to control whether invitations go out immediately.
  • The response is a contract. Its id is the contract identifier; use the document_id field to work with the document elsewhere in the API (for example, to fetch or download it).
  • After sending, you usually do not poll for the result. Instead, set up a webhook that listens for the contract-completed event. Its payload is the contract but does not include a document id, so use the contract's id to find the document with List documents (GET /documents?filter[contract_id]={contract_id}), then fetch the finished file with Download document.

Managing the archive

All documents live in folders inside the workspace archive, and you can manage both through the API.

Folders — list, create, fetch, update, and delete folders with the Folders endpoints. Use the include parameter (parent, breadcrumb, has_children) to pull in related data. Deleting a folder also deletes every document and subfolder inside it.

Documentslist, fetch, download, and delete documents. When listing, narrow results with the filter parameters (by folder_id, by contract stage, or by contract_id) and order them with sort. Use include=contract to embed each document's contract details.

Webhooks

Instead of polling the API for changes, you can let Docue push notifications to your own systems as they happen. A webhook subscribes to a set of events; whenever a matching event occurs in your workspace, Docue sends an HTTP POST request to the URLs you configured.

A webhook has two parts:

  • Configuration — the webhook itself: a name, an enabled flag, an optional description, and the list of accepted_events it listens to.
  • Endpoints — one or more URLs that receive the deliveries. Each endpoint can carry optional authentication (basic with a username and password, or bearer with a token) that Docue includes on every request it sends to that endpoint.

Manage webhooks with the Webhooks endpoints: create, list, update, and delete them. Use include=endpoints when listing to load each webhook's endpoints.

Your endpointDocueYour endpointDocueAn event occurs(e.g. contract completed)Delivery succeededRetried with backoff (up to 8 attempts)alt[endpoint responds 2xx][non-2xx / no response]POST <your endpoint URL> (event envelope)200 OK5xx / timeout
Your endpointDocueYour endpointDocueAn event occurs(e.g. contract completed)Delivery succeededRetried with backoff (up to 8 attempts)alt[endpoint responds 2xx][non-2xx / no response]POST <your endpoint URL> (event envelope)200 OK5xx / timeout

Delivery format

Each delivery is an HTTP POST with a JSON body — the event envelope:

{
  "id": "01J9Z6E0Q2VHB8N6Q4N0YQK7AB",
  "occurred_at": "2026-06-01T13:26:29Z",
  "event_type": "contract-completed",
  "content": { }
}
  • id — a unique identifier for the event (a ULID). Use it to deduplicate deliveries; the same event may be delivered more than once.
  • occurred_at — when the event occurred.
  • event_type — one of the webhook events below.
  • content — the resource the event is about. Its shape depends on the event: document events carry the document, contract events carry the contract, and signature events carry the signature (the same objects you get from the corresponding API endpoints).

Each request also carries identifying headers:

HeaderDescription
docue-webhook-event-idThe event id, matching the envelope.
docue-webhook-event-typeThe event type.
docue-webhook-endpoint-idIdentifier of the endpoint that is receiving the delivery.
docue-workspace-idIdentifier of the workspace the event belongs to.

If an endpoint has authentication configured, Docue also sends the corresponding Authorization header (Basic or Bearer).

Responding and retries

Your endpoint should return a 2xx status code to acknowledge a delivery. Any other status (or a timeout / connection error) is treated as a failure, and Docue retries the delivery with an increasing backoff — up to 8 attempts in total. The wait before each retry grows: about 5 minutes before the first retry, 1 hour before the second, and 10 hours before every retry after that. Acknowledge quickly and do any heavy processing asynchronously on your side.

Webhook events

These are the events a webhook can subscribe to via accepted_events. More may be added over time.

EventWhen it firescontent
document-createdA new document is created in the workspace — for example when one is drafted from a template, uploaded, or created as part of sending a PDF for signing.The document
document-updatedAn existing document's attributes change — for example its title, folder, or notes are updated.The document
contract-completedA contract reaches the completed stage: every party has signed, or the contract was finalized with the manual signing method or with no signees.The contract
contract-cancelledA contract is cancelled — for example its signing process is cancelled, or it expires before all parties have signed.The contract
signature-updatedA single signature (one signee on a contract) changes — for example its state changes or its contact details are edited.The signature

Testing a webhook

To verify your endpoints are wired up correctly, use Test webhook. Given a document, it builds a document-updated event from it and dispatches it to the webhook's endpoints — regardless of the webhook's accepted_events, so the webhook does not need to listen to document-updated to be testable. Use it to confirm your endpoint receives deliveries, validates the headers, and responds with a 2xx.

Architectural notes

  • Everything is scoped to your workspace. The API key authenticates one workspace, and all resources you create or read belong to it. Anything you do is mirrored in the Docue.com web app.
  • Builder state retention. After a contract is finalized or completed, its builder state remains readable for 24 hours, then becomes unavailable (410 Gone).
  • Draft expiry. Drafts created from a template expire if left untouched; see draft_expires_at on the contract.
  • No long-term guarantees on experimental endpoints. Get contract builder value schema and Get contract builder sections are experimental and their response shapes may change without notice — avoid depending on their exact structure in production.

Common error responses

StatusMeaning
401The API key is missing or invalid.
403The workspace lacks write access to the target folder.
404The requested template, contract, document, or folder was not found in the workspace.
409The contract is not Builder 2.0, or is no longer in the created stage (for patch/finalize), or there were not enough signatures to send for signing.
410The builder state is no longer available (more than 24 hours after finalization).
422The request payload failed validation. The response includes a validationErrors map.

If you have any questions about the Platform API, please feel free to contact support@docue.com.