REST API

Document requests API

API v115 August 2026·6 min read

Full reference for Doclift's Document Requests API: asynchronous generation, the payload, statuses, validation errors and limits.

The document request object

  • id: unique identifier
  • tag: free-form string you send, echoed back
  • type: asynchrone (spelled as shown, not the English "asynchronous"); the value you send at creation
  • sandbox_mode: set once at creation from the calling key's environment
  • status: in_progress, success, or error (the request's overall outcome)
  • documents_generations: present on the list endpoint and the show endpoint; absent from the create response, since nothing has rendered yet when it answers; each entry has id, tag, generated_at, created_at, generation_status (created, in_progress, success, or error), and file (filename, url, size)

template_id accepts a custom, fillable_form, or workflow template, as long as it is published. The payload shape is identical for all three. Workflow templates carry one additional contract on top of everything below. See Workflow templates.


Asynchronous generation

type: "asynchrone" accepts one or more entries in document_generations and answers immediately with id, tag, type, sandbox_mode, and status: "in_progress": no documents_generations key at all, since nothing has rendered yet. The finished documents arrive later as a webhook. See Webhooks. Generation requires a webhook URL configured on the calling external application; without one, the request is refused before anything is created:

422 Unprocessable Content · application/json
{
  "error": "Please add a webhook URL to this external application to use asynchronous generation. You can add one from your Doclift.io account."
}

Sandbox forces priority to low

priority (critical, default, or low, default critical) sets how this request ranks against others waiting to generate. In sandbox mode it is always forced to low, whatever value you send.


Create a document request

POST/api/v1/document_requests
cURL
curl https://app.doclift.io/api/v1/document_requests \
  --request POST \
  --header "X-Api-Key: <your-api-key>" \
  --header "Content-Type: application/json" \
  --data '{
    "document_request": {
      "type": "asynchrone",
      "document_generations": [
        {
          "template_id": 100013,
          "tag": "Invoice#42",
          "variables": {
            "client_name": "John Doe"
          }
        }
      ],
      "tag": "Batch#1"
    }
  }'
200 OK · application/json
{
  "id": 100004,
  "tag": "Batch#1",
  "type": "asynchrone",
  "sandbox_mode": false,
  "status": "in_progress"
}
FieldTypeRequiredNotes
typestringyessend asynchrone
prioritystringnocritical, default, or low; forced to low in sandbox
tagstringnodefault ""
document_generationsarrayyesone or more entries
document_generations[].template_idintegeryesmust be published
document_generations[].tagstringnodefault ""
document_generations[].variablesobject or nullnoflat key/value map (see Templates)

There is no idempotency key: submitting the same body twice creates two independent document requests, each reporting its own status.


Validation errors

Each of the following is checked in order; the first failure short-circuits the rest and answers before any document is generated.

FailureStatusNotes
type422 "The requested generation type is invalid. Accepted values: synchrone / asynchrone"
priority422 {"error": "..."}, names the accepted values
webhook_url422 see Asynchronous generation
document_generations422 "The following required parameters are missing: document_generations"
template_id422 "The following required parameters are missing: template_id"
template_id422 names the id; a wrong id and someone else's id answer identically
content422
Rendered content exceeds the organization's size limit422 see Limits
variables422
document_request400 {"error": "..."}, names the missing parameter when applicable

Missing/invalid/disabled API key answers 403 on every variant, as elsewhere in the API. See Response codes.

Variable validation errors

On a fillable_form template only, each provided value is checked against the auto-detected allowed_values of its variable (see Fillable forms). A value outside the allowed list answers 422 naming every offending field:

422 Unprocessable Content · application/json
{
  "error": "Les valeurs fournies pour certaines variables ne sont pas valides (status: 'bad_value' (valeurs autorisées : approved, rejected)).",
  "invalid_variables": [
    { "field": "status", "value": "bad_value", "allowed_values": ["approved", "rejected"] }
  ]
}

custom and workflow templates are not checked against allowed_values at generation time by this step.

If generation fails for any other reason once the payload is otherwise valid, you observe it through GET /api/v1/document_requests/:id's generation_status/ generation_error, or through the webhook payload's generation_status: "error".


Workflow templates

Workflow templates are generated through this same endpoint. There is no separate workflow generation route. Workflows are a private beta, available on request by writing to [email protected]; see Workflows for the full picture.

On top of everything above, a workflow's variables payload carries a required-variable contract that no other category enforces:

Workflow document_generations entry
{
  "template_id": 100050,
  "variables": {
    "investor_type": "natural",
    "country": "FR",
    "investments": [{ "product": "SCPI", "amount": "10 000 €" }]
  },
  "tag": ""
}
FailureTrigger
Missing required variablea variable declared required has no key at all in the payload
Malformed collectiona collection-type variable's value is not an array of flat objects
Non-scalar valuea non-collection variable received an array or object
Oversized collectiona collection carries more than 200 rows
Missing required row fielda required field of a collection row has no key in that row
Excludes every sectionthe payload's conditions leave nothing to render
Prints nothingsections survive the conditions but assemble to blank content

A key present with an empty string or null counts as answered. Only the absence of the key triggers the missing-variable check. All applicable failures across the whole batch are reported together in one 422 {"error": "..."}, naming every affected template and variable at once (useful when a batch mixes several workflow generations). allowed_values is not checked for workflow variables at generation time.


List document requests

GET/api/v1/document_requests
cURL
curl https://app.doclift.io/api/v1/document_requests \
  --header "X-Api-Key: <your-api-key>"
200 OK · application/json
[
  {
    "id": 100004,
    "tag": "Batch#1",
    "type": "asynchrone",
    "external_application": {
      "id": 100000,
      "name": "Production key",
      "environment": "sandbox",
      "active": true
    },
    "documents_generations": [
      {
        "id": 100230,
        "tag": "Invoice#42",
        "generated_at": "2024-01-15T10:35:02+01:00",
        "created_at": "2024-01-15T10:35:00+01:00",
        "generation_status": "success",
        "file": {
          "filename": "Invoice-1615737313.pdf",
          "url": "https://doclift.s3.eu-west-1.amazonaws.com/d207f8fe.pdf?[...]",
          "size": 40290
        }
      }
    ]
  }
]

Lists your organization's document requests, newest first. This follows from the organization-wide association, so requests created through other external applications under the same organization appear too, not only the calling key's. Paginated at 30 per page; see Pagination.

StatusBodyWhen
200 arrayalways, including an empty account
403 {"error": "..."}missing, unknown, or disabled API key

View a document request

GET/api/v1/document_requests/:id
cURL
curl https://app.doclift.io/api/v1/document_requests/100004 \
  --header "X-Api-Key: <your-api-key>"
200 OK · application/json
{
  "id": 100004,
  "tag": "Batch#1",
  "type": "asynchrone",
  "external_application": {
    "id": 100000,
    "name": "Production key",
    "environment": "sandbox",
    "active": true
  },
  "documents_generations": [
    {
      "id": 100230,
      "tag": "Invoice#42",
      "generated_at": "2024-01-15T10:35:02+01:00",
      "created_at": "2024-01-15T10:35:00+01:00",
      "generation_status": "success",
      "generation_duration": 1721,
      "generation_error": null,
      "sent_payload": { "client_name": "John Doe" },
      "file": {
        "filename": "Invoice-1615737313.pdf",
        "url": "https://doclift.s3.eu-west-1.amazonaws.com/d207f8fe.pdf?[...]",
        "size": 40290
      },
      "template": {
        "id": 100013,
        "title": "Invoice",
        "description": "A template for invoices"
      }
    }
  ]
}

This is the richer view: sent_payload (exactly what you sent), generation_duration, generation_error, and the source template are only present here, never in the list or in the create response. File URLs are valid for 20 hours in this view, against 2 hours everywhere else.

StatusBodyWhen
200 document request, show viewbelongs to your organization
404 {"error": "Record not found"}unknown id or another organization's
403 {"error": "..."}missing, unknown, or disabled API key

Limits

LimitValueScope
Rendered content size800 ,000 characters by default, configurable per organizationcustom and workflow templates; fillable_form is never measured
Collection rows (workflow)200 per collection variable, per generation
Webhook delivery retriesconfigurable per organizationsee Webhooks

There is no request-rate limiting on this API. See Environments.