# DocLift API — Complete Reference > DocLift is a PDF document generation API. You design templates with an online editor, define dynamic variables, then generate PDFs via REST API calls. Documents are generated asynchronously and delivered via webhooks. ## Quick Reference — All Endpoints | Method | Endpoint | Description | Response | |--------|----------|-------------|----------| | GET | /api/v1/user | Current user & app info | 200 | | GET | /api/v1/templates | List published templates | 200 (paginated) | | GET | /api/v1/templates/:id | View a template | 200 / 404 | | POST | /api/v1/templates | Create a custom template | 201 / 422 | | PATCH | /api/v1/templates/:id | Update a custom template | 200 / 404 / 422 | | DELETE | /api/v1/templates/:id | Archive a custom template | 204 / 404 | | PUT | /api/v1/templates/:id/publish | Publish a template | 200 / 404 | | PUT | /api/v1/templates/:id/unpublish | Unpublish a template | 200 / 404 | | GET | /api/v1/templates/:template_id/variables | List variables | 200 | | POST | /api/v1/templates/:template_id/variables | Create a variable | 201 / 422 | | PATCH | /api/v1/templates/:template_id/variables/:id | Update a variable | 200 / 422 | | DELETE | /api/v1/templates/:template_id/variables/:id | Delete a variable | 204 | | GET | /api/v1/document_requests | List document requests | 200 (paginated) | | GET | /api/v1/document_requests/:id | View a document request | 200 / 404 | | POST | /api/v1/document_requests | Create a document request | 201 / 422 | Base URL: https://app.doclift.io/api/v1 --- ## Authentication Every request must include the `X-Api-Key` header with your API key value. ``` X-Api-Key: your_secret_key_here ``` Invalid or missing keys return 403 Forbidden. --- ## Response Codes - 200 OK — success - 201 Created — resource created (POST) - 204 No Content — resource deleted (DELETE) - 400 Bad Request — malformed body or missing params - 403 Forbidden — invalid, missing, or disabled API key - 404 Not Found — resource does not exist - 422 Unprocessable Entity — validation errors - 500 Internal Server Error --- ## Pagination List endpoints return paginated results. Response headers: - `results` — count on current page - `results_per_page` — items per page - `current_page` — current page number - `pages_count` — total pages Use `?page=N` query parameter to navigate. --- ## Environments - **Sandbox**: free, watermarked documents, priority forced to "low" - **Production**: requires premium plan, no watermark, full priority control Both share the same templates and data. --- ## Dates All dates use ISO-8601 format in GMT+1 (Paris): `2021-02-23 16:39:00 +0100` --- ## User Info ### GET /api/v1/user Returns the authenticated user and current external application. Response: ```json { "id": 100001, "firstname": "John", "lastname": "Doe", "email": "john@example.com", "created_at": "2021-02-15 10:30:00 +0100", "updated_at": "2021-06-20 14:00:00 +0100", "document_max_length_allowed": 800000, "webhooks_replays_count": 3, "allowed_to_use_production_mode": false, "current_external_application": { "id": 100000, "name": "My App", "environment": "sandbox", "active": true, "webhook_url": "https://myapp.com/webhooks/doclift", "revealable_secret_key": "•••...abc12345" } } ``` --- ## Templates ### Template Object Fields - `id` — unique identifier - `title` — name (required) - `description` — description (required) - `category` — `custom` or `fillable_form` - `orientation` — `portrait` or `landscape` - `published` — boolean - `content` — HTML content (custom templates only) - `margin_top`, `margin_bottom`, `margin_left`, `margin_right` — margins in mm (min 5) - `variables` — list of Variable objects - `created_at`, `updated_at` — ISO-8601 timestamps Only `custom` templates can be managed via API. `fillable_form` templates return 404. ### Response Views The API returns different levels of detail depending on the endpoint: **Short view** (GET /templates list): `id`, `title`, `description` **Show view** (GET /templates/:id): `id`, `title`, `description`, `created_at`, `updated_at`, `variables` (with `title`, `description`, `field_type`, `allowed_values` — no `id`, no `seed_value`) **Detail view** (POST, PATCH, PUT publish/unpublish): all fields including `content`, `category`, `orientation`, `published`, margins, and variables with `id`, `title`, `description`, `seed_value`, `field_type`, `allowed_values` ### GET /api/v1/templates List published templates (short view). Response: ```json [ {"id": 100011, "title": "Template 1", "description": "Description 1"}, {"id": 100012, "title": "Template 2", "description": "Description 2"} ] ``` ### GET /api/v1/templates/:id View a published template (show view). Response: ```json { "id": 100011, "title": "Template 1", "description": "Template 1 description", "variables": [ {"title": "firstname", "description": "First name", "field_type": "text", "allowed_values": []}, {"title": "status", "description": "Status", "field_type": "select", "allowed_values": ["active", "inactive"]} ], "created_at": "2021-02-28 21:48:03 +0100", "updated_at": "2021-02-28 21:48:58 +0100" } ``` ### POST /api/v1/templates Create a custom template. Returns 201 with detail view. Request: ```json { "template": { "title": "Invoice template", "description": "For monthly invoices", "orientation": "portrait", "content": "
{{client_name}}
", "margin_top": 10, "margin_bottom": 10, "margin_left": 15, "margin_right": 15, "variables_attributes": [ {"title": "client_name", "description": "Client name", "field_type": "text", "seed_value": "John Doe"} ] } } ``` Accepted fields: `title`, `description`, `content`, `orientation`, `margin_top`, `margin_bottom`, `margin_left`, `margin_right`, `variables_attributes` (array of `id`, `_destroy`, `title`, `description`, `seed_value`, `field_type`, `allowed_values`). ### PATCH /api/v1/templates/:id Update a custom template. Returns 200 with detail view. Only send fields you want to change. Inline variable management via `variables_attributes`: - Update: include `id` + changed fields - Create: omit `id` - Delete: include `id` + `"_destroy": true` ### DELETE /api/v1/templates/:id Soft-delete (archive) a custom template. Returns 204. ### PUT /api/v1/templates/:id/publish Publish a template. Returns 200 with detail view. ### PUT /api/v1/templates/:id/unpublish Unpublish a template. Returns 200 with detail view. --- ## Variables ### Variable Object Fields - `id` — unique identifier - `title` — name (alphanumeric + underscores, auto-lowercased, unique per template) - `description` — expected content and format - `field_type` — `text`, `checkbox`, `radio`, or `select` - `seed_value` — preview value (accepted on write, only returned in template detail view) - `allowed_values` — array of accepted values (for radio/select only) ### GET /api/v1/templates/:template_id/variables List all variables of a template. Response: ```json [ {"id": 200001, "title": "client_name", "description": "Full name", "field_type": "text", "allowed_values": []}, {"id": 200002, "title": "status", "description": "Client status", "field_type": "select", "allowed_values": ["active", "inactive"]} ] ``` Note: `seed_value` is NOT included in variable API responses. ### POST /api/v1/templates/:template_id/variables Create a variable. Returns 201. Request: ```json {"variable": {"title": "city", "description": "City name", "field_type": "text", "seed_value": "Paris"}} ``` Response: ```json {"id": 200003, "title": "city", "description": "City name", "field_type": "text", "allowed_values": []} ``` ### PATCH /api/v1/templates/:template_id/variables/:id Update a variable. Returns 200. ### DELETE /api/v1/templates/:template_id/variables/:id Delete a variable. Returns 204. --- ## Document Requests Document generation is asynchronous. You create a request, and results are delivered via webhook. ### Document Request Object Fields - `id` — unique identifier - `tag` — custom identifier (optional) - `type` — `asynchrone` - `priority` — `critical` (default), `default`, or `low`. Sandbox forces `low`. - `sandbox_mode` — boolean - `external_application` — `{id, name, environment, active}` - `documents_generations` — array of Document Generation objects ### Document Generation Object Fields Short view (list, webhook): - `id`, `tag`, `generated_at`, `created_at`, `generation_status`, `file` Detail view (GET show): - All of the above plus: `generation_duration` (ms), `generation_error`, `sent_payload`, `template` File object: `{filename, url, size}` S3 URL expiration: **2 hours** (webhook) / **20 hours** (GET show) Generation statuses: `created` → `in_progress` → `success` | `error` ### POST /api/v1/document_requests Create a document request (up to 100 documents). Returns 201. Webhook URL must be configured on the external application. Request: ```json { "document_request": { "type": "asynchrone", "priority": "critical", "tag": "Batch#12", "document_generations": [ { "template_id": "100017", "tag": "Subscription#102", "variables": {"firstname": "John", "lastname": "Doe", "city": "Paris"} }, { "template_id": "100014", "tag": "Subscription#103", "variables": {"firstname": "Lea", "lastname": "Maquize", "city": "London"} } ] } } ``` Response: ```json { "id": 100004, "tag": "Batch#12", "type": "asynchrone", "sandbox_mode": true, "status": "in_progress" } ``` Results are delivered via webhook when generation completes. ### GET /api/v1/document_requests List document requests (paginated). Returns index view with `id`, `tag`, `type`, `external_application`, `documents_generations` (short view). ### GET /api/v1/document_requests/:id View a document request with full detail including `sent_payload`, `generation_duration`, `generation_error`, and `template` per generation. ### Variable Validation Errors When a radio/select variable receives a value not in `allowed_values`, returns 422: ```json { "error": "Invalid variables", "invalid_variables": [ {"field": "status", "value": "unknown", "allowed_values": ["active", "inactive", "pending"]} ] } ``` --- ## Webhooks ### Configuration Set a `webhook_url` (HTTPS) on your external application from the DocLift dashboard. Required for document requests. ### Payload POST to your webhook URL when generation completes: ```json { "id": 100004, "tag": "Batch#12", "type": "asynchrone", "timestamp": "2024-01-15T10:35:00+01:00", "documents_generations": [ { "id": 100230, "tag": "Subscription#102", "generated_at": "2024-01-15 10:35:00 +0100", "created_at": "2024-01-15 10:34:58 +0100", "generation_status": "success", "file": {"filename": "Contract.pdf", "url": "https://doclift.s3...?...", "size": 40290} } ] } ``` S3 URLs expire after **2 hours**. ### Signature Verification Header: `X-Doclift-Signature: sha256={hmac_hex_digest}` The signature is HMAC-SHA256 of the raw request body, signed with your API secret key, prefixed with `sha256=`. Verification example (Ruby): ```ruby computed = "sha256=" + OpenSSL::HMAC.hexdigest("SHA256", api_secret_key, request.raw_post) valid = computed == request.headers["X-Doclift-Signature"] ``` ### Response Your endpoint must return HTTP 2xx within **3 seconds**. ### Retry Policy On failure: exponential backoff — `delay = min(30 * 2^(n-1), 1800)` seconds. - Retry 1: 30s - Retry 2: 60s - Retry 3: 120s - Max delay: 30 minutes Default max retries: 3 (configurable via `webhooks_replays_count`). Failed webhooks can be recovered via GET /api/v1/document_requests/:id.