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.
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.
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_idyou 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.
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.
A contract moves through a small set of stages. Most endpoints care about whether the contract is still editable (created) or already locked.
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.
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.
Step by step:
- List templates with List templates. The
filter[type]=tailoredparameter is required. Note each template'sbuilder_version(see the callout below). - Start a document with Create document from template, passing the target
folder_idand atitle. The response is a document in thecreatedstage; grab itscontract_id. - Read the builder state with Get contract builder state to see the current
value,sections, andappearance. - Prefill values with Update contract builder state using JSON Patch operations (see Working with the builder state below).
- 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 whosebuilder_versionis"2". Starting from a template that uses an older builder produces abuilder_versionof"1", and the builder endpoints return409 Conflict. Checkbuilder_versionon the template (and on the contract) before relying on these endpoints. You can include the contract on a document response with?include=contractto read itsbuilder_versionandstage.
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
createdstage andbuilder_versionis"2". Otherwise the endpoint returns409 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 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
translatableobject 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'slanguagesarray. - 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
valuebefore 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/-.
PATCH /contracts/{id}/builder/state
{
"operations": [
{
"op": "replace",
"path": "/value/basic/title",
"value": {
"_type": "translatable",
"en-GB": "Employment Agreement (revised)"
}
}
]
}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"
}
]
}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."
}
}
]
}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_method—canvasfor drawn signatures,strongfor strong electronic identification, ormanualto complete the document without electronic signing.send_invitations— whentrue, invitations are dispatched immediately. Whenfalse, 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 whensignature_methodismanual.
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.
Key points:
- The request must be
multipart/form-databecause it includes a file upload. Only PDF files are accepted, and the maximum size is 13 MB per file. Optionalattachments(up to 10) are merged with the primaryfileinto a single document before signing. - Provide at least one party in
parties[]. A party with anemailis invited by email, one with aphoneby SMS, and one with both by both. Usesend_invitationsto control whether invitations go out immediately. - The response is a contract. Its
idis the contract identifier; use thedocument_idfield 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-completedevent. Its payload is the contract but does not include a document id, so use the contract'sidto find the document with List documents (GET /documents?filter[contract_id]={contract_id}), then fetch the finished file with Download document.
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.
Documents — list, 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.
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, anenabledflag, an optionaldescription, and the list ofaccepted_eventsit listens to. - Endpoints — one or more URLs that receive the deliveries. Each endpoint can carry optional authentication (
basicwith a username and password, orbearerwith 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.
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:
| Header | Description |
|---|---|
docue-webhook-event-id | The event id, matching the envelope. |
docue-webhook-event-type | The event type. |
docue-webhook-endpoint-id | Identifier of the endpoint that is receiving the delivery. |
docue-workspace-id | Identifier of the workspace the event belongs to. |
If an endpoint has authentication configured, Docue also sends the corresponding Authorization header (Basic or Bearer).
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.
These are the events a webhook can subscribe to via accepted_events. More may be added over time.
| Event | When it fires | content |
|---|---|---|
document-created | A 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-updated | An existing document's attributes change — for example its title, folder, or notes are updated. | The document |
contract-completed | A 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-cancelled | A contract is cancelled — for example its signing process is cancelled, or it expires before all parties have signed. | The contract |
signature-updated | A single signature (one signee on a contract) changes — for example its state changes or its contact details are edited. | The signature |
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.
- 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_aton 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.
| Status | Meaning |
|---|---|
401 | The API key is missing or invalid. |
403 | The workspace lacks write access to the target folder. |
404 | The requested template, contract, document, or folder was not found in the workspace. |
409 | The 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. |
410 | The builder state is no longer available (more than 24 hours after finalization). |
422 | The 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.