REST API

API basics

API v115 August 2026·5 min read

Base URL, authentication, environments, dates, response codes, the error envelope, pagination, and GET /api/v1/user.

Base URL

Every endpoint in this documentation is relative to:

Code
https://app.doclift.io/api/v1

Send requests directly from your server, never from a user's browser. Your API key would otherwise be exposed to whoever inspects the page.


Authentication

Every request carries an X-Api-Key header. The key identifies an external application, which belongs to an organization. Every read and write in this API is scoped to that organization, not to a single user or a single key.

cURL
curl https://app.doclift.io/api/v1/templates \
  -H "X-Api-Key: <your-api-key>"

A key belonging to a disabled external application answers exactly like an unknown key: 403 Forbidden. See Response codes for the exact bodies.


HTTP verbs

VerbUsed for
GETRead a resource or list one.
POSTCreate a resource, or trigger an action (generation, publish).
PUT/PATCHUpdate a resource. Both are accepted wherever an endpoint documents an update.
DELETERemove a resource: a soft archive on some resources, a hard delete on others; each endpoint's page says which.

Send JSON bodies; every response is JSON.


Environments

Every external application (API key) is created in one of two environments. The two share the same templates and data; an environment is a property of the key, not of the resource it acts on.

SandboxProduction
Available from account creationyesonly if your organization is authorized for production mode
Watermarkingevery generated document is watermarkednot watermarked
Default generation priorityforced to low (see priority)whatever you send (default critical)
Quotas (document size limit, webhook retry count)same as production (set per organization, not per environment)same as sandbox

Creating a production key requires your organization to be authorized for production mode; that check runs only at key-creation time, so a production key already issued keeps working even if the authorization is later revoked. There is no equivalent restriction on sandbox keys.

There is no rate limiting anywhere in this API. No request-per-minute ceiling exists to hit, in either environment.


Date format

All timestamps (created_at, updated_at, generated_at, timestamp, and similar fields) are rendered as ISO-8601, e.g. 2024-01-15T10:30:00+01:00. The timestamp field sent in every webhook payload is computed at response time rather than read from a stored column, but uses the same ISO-8601 format as every other date field in this API.


Response codes

CodeMeaning
200 The request succeeded.
201 A resource was created.
204 The request succeeded; there is no response body.
400 The body is not valid JSON, or is missing its required root key (template, variable, document_request, …).
403 The X-Api-Key header is missing, unknown, or belongs to a disabled external application.
404 The resource does not exist, is not in your organization, is archived, or is not the category this endpoint operates on.
409 A workflow write is refused because the dashboard builder currently holds the edit lock on it (workflow-authoring endpoints only); templates, variables, and document requests never answer 409.
422 The request was well-formed but failed a validation or business rule.

Errors

There is no single error envelope shared by the whole API. The shape depends on what failed:

SituationStatusBody
Missing, invalid, or disabled API key403 {"error": "<message>"}
Malformed JSON body400 {"error": "Le body de la requête semble mal formé."}
Missing required root key400 {"error": "<names the missing param>"}
Model validation failure on create/update422 {"errors": ["<message>", ...]}
Business-rule failure (e.g. creating a document request)422 {"error": "<message>"}, plus invalid_variables for a fillable-form allowed-values violation
Resource not found404 {"error": "Template not found"} / {"error": "Variable not found"} / {"error": "Record not found"}

The key name (error vs. errors) and the not-found wording both vary by endpoint. Match on the status code, not on a fixed body shape, if you branch on failures programmatically.


Pagination

Two list endpoints are paginated: GET /api/v1/templates and GET /api/v1/document_requests. Page size is fixed at 30 and cannot be changed; add ?page= to move through the results. A page past the last one still answers 200 with an empty array, never a 404.

Every paginated response carries these headers:

HeaderMeaning
resultsTotal number of records, across every page.
results_per_pageRecords per page (30).
current_pageThe page this response returned.
pages_countTotal number of pages.

The one exception: GET /api/v1/document_requests skips pagination entirely when your organization has zero document requests at all, answering 200 [] with none of these headers set. There is nothing to page through. GET /api/v1/templates always sets them, even for an empty result.

GET /api/v1/templates/:template_id/variables is not paginated. It always returns every variable of the template in one array.


User info

GET/api/v1/user

Returns the profile of the user your key resolves to (the external application's creator, or the organization's owner if that creator has been deactivated), plus your organization's account-level limits and the calling key's own public info. No parameters.

cURL
curl https://app.doclift.io/api/v1/user \
  -H "X-Api-Key: <your-api-key>"
200 OK · application/json
{
  "id": 100001,
  "firstname": "John",
  "lastname": "Doe",
  "email": "[email protected]",
  "created_at": "2021-02-15T10:30:00+01:00",
  "updated_at": "2021-06-20T14:00:00+01:00",
  "document_max_length_allowed": 800000,
  "webhooks_replays_count": 3,
  "allowed_to_use_production_mode": false,
  "current_external_application": {
    "name": "My App",
    "environment": "sandbox",
    "active": true,
    "webhook_url": "https://myapp.com/webhooks/doclift",
    "revealable_secret_key": "•••...abc12345"
  }
}

document_max_length_allowed, webhooks_replays_count, and allowed_to_use_production_mode are your organization's settings, not personal ones. Every key in the same organization reports the same values. current_external_application never includes the raw secret_key, only the masked revealable_secret_key.

Status codes: 200 on success, 403 per the authentication rules above. There is no other failure mode for this endpoint.