HTTP API
Upload and manage templates
HTTP API to upload, list, update, and delete your templates
Upload a template
Uploads a new template to the Carbone storage.
This endpoint supports optional metadata and advanced features like template versioning.
When versioning is enabled:
- A unique
template IDis created, and aversion IDrepresenting the unique identifier (sha256) of the file. Both IDs can be used to Generate documents. - Multiple versions of a template can be managed under the same
Template ID. - When a document is generated using a
Template ID, Carbone will use the latest deployed version (based on thedeployedAttimestamp parameter).
Example 1 - Add a template with the absolute file path
curl --location --request POST 'https://api.carbone.io/template' \
--header 'carbone-version: 5' \
--header 'Expect:' \
--header 'Content-Type: multipart/form-data' \
--header 'Authorization: Bearer API_TOKEN' \
--form 'template=@"ABSOLUTE_FILE_PATH"'
Example 2 - Add a template with the file as a base64 String
curl --location --request POST 'https://api.carbone.io/template' \
--header 'carbone-version: 5' \
--header 'Expect:' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer API_TOKEN' \
--data-raw '{ "template": "BASE64_STRING" }'
Request header
{
// REQUIRED - Your API token (string)
"authorization" : "Bearer API_TOKEN",
// REQUIRED - Content-type
"content-type" : "multipart/form-data", // or "application/json" (solution 2)
// REQUIRED - Carbone-Version (string)
"carbone-version" : "5"
}
Request body
The body request can be either:
- A FormData object that contains the template as a Buffer or as a Blob. The file should be assigned to the attribute
template. The request header must include{"content-type": "multipart/form-data"}. - A JSON object that contains the template as a base64 String
{ "template" : "pure base64 or a base64 data-URI"}. The request header must include{"content-type": "application/json" }.
| Parameter | Type | Required | Description |
|---|---|---|---|
template |
File | Yes | The template file to upload. This can be provided either as a base64-encoded string or as multipart/form-data. Ensure that the template field is the last element in the request body to avoid any issues with the request. |
versioning |
Boolean | No | Template versioning is enabled if: - versioning is true → a new Template ID is generated.- versioning is true and the id field is provided → the new template is added to the existing Template ID’s version history.Template versioning is disabled if: - versioning is false/undefined, and if the id field is undefined. |
id |
String | No | Template ID (64-bit format). If the id is provided, the new template is added to the existing Template ID’s version history. If the id field is left empty, a new Template ID is generated. Providing a Version ID (SHA256 format) is not allowed and will result in an API error. |
name |
String | No | Template name, 200 characters maximum. |
comment |
String | No | Template comment, 200 characters maximum. |
tags |
Array[String] | No | List of tags. Duplicates are removed and the list is returned sorted alphabetically. The whole list is limited to 100 characters, which is about 8 tags of 9 characters. |
category |
String | No | Group multiple templates into categories, similar to folders. 200 characters maximum. |
sample |
Array[Object] | No | Sample input data used in Carbone Studio for testing and development. A single object with the optional properties data, complement, translations and enum. Example: [{ "data": {}, "complement": {}, "translations": {}, "enum": {} }]. |
deployedAt |
Integer | No | When generating a document with a Template ID, Carbone uses the most recent deployedAt version. The deployedAt value must be a UTC Unix timestamp; values ≥ 42000000000 (year 3300) are interpreted as 'NOW'. Future values are not allowed. |
expireAt |
Integer | No | Schedule the template for deletion, as a UTC Unix timestamp in seconds. Nothing changes until that time. After it, the template is no longer listed, cannot be downloaded, and generating a document with it returns 404 Template not found. The file itself is deleted later, once the storage retention delay has passed.0 (default) means the template never expires. |
origin |
Integer | No | Where the template comes from, used to filter the template list. - 0: API (default)- 1: Studio- 2: Salesforce- 3: Odoo- 4: HubSpotThe origin is set at upload time only: it cannot be changed afterwards. |
Responses
On success (status code 200) , the response body returns a JSON containing identifiers (id and versionId), file type, size, and creation timestamp. For backward compatibility (versioning field disabled or undefined), it returns only the field templateId, SHA-256 hash of the template file.
{
"success": true,
"data": {
"id": "TEMPLATE_ID (64-bit String)",
"versionId": "VERSION_ID (Sha256 String)",
"type": "FILE_TYPE",
"size": FILE_SIZE_IN_BYTES,
"createdAt": UTC_UNIX_TIMESTAMP,
"deployedAt": UTC_UNIX_TIMESTAMP
}
}
On error, the following responses can be returned:
| Status Code | Body | |
|---|---|---|
| 400 | { "success" : false, "error" : "Invalid template metadata. Error: expireAt (-1) must be an integer between 0 and 9007199254740991." }Returned when a metadata field is rejected. The message after Invalid template metadata. names the offending field and the expected range or format. |
|
| 400 | { "success" : false, "error" : "Cannot store JSON sample with template file" }Also returned when the sample field does not match the expected format [{data, complement, enum, translations}]. |
|
| 400 | { "success" : false, "error" : "Cannot store template" } |
|
| 400 | { "success" : false, "error" : "Content-Type header should be multipart/form-data or application/json" } |
|
| 400 | { "success" : false, "error" : "The 'X' field must be sent before the 'template' file field in the form data." } |
|
| 401 | { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"} |
|
| 413 | { "success" : false, "error" : "Template too large, the file size limit is X Bytes"} |
|
| 415 | { "success" : false, "error" : "Template format not supported" } |
|
| 422 | { "success" : false, "error" : ""template" field is empty" } |
|
| 500 | { "success" : false, "error" : "Database error." } |
|
| 500 | { "success" : false, "error" : "Server Error."} |
Download a template
Fetches a specific template or version of a template from the Carbone storage. It supports:
- Retrieving the latest deployed version of a template using the
templateId, as well as versions viaversionId. - Downloading JSON data samples associated with templates or specific versions, which are used in the Studio for testing and development purposes. The URL PATH must be specified as
/template/{templateId}_sample.jsonor/template/{versionId}_sample.jsonto download associated data samples.
curl --location --request GET 'https://api.carbone.io/template/{templateId-or-versionId}' \
--header 'carbone-version: 5' \
--header 'Authorization: Bearer API_TOKEN' \
--output 'FILENAME.docx'
Request header
{
// REQUIRED - Your API token (string)
"authorization" : "Bearer API_TOKEN",
// REQUIRED - Carbone-Version (string)
"carbone-version" : "5"
}
Response body
On success, the Stream of the template file is returned.
On error, a JSON is returned with details of the problem.
| Status Code | Body | |
|---|---|---|
| 200 | File stream | |
| 400 | { "success" : false, "error" : "Invalid templateId"} |
|
| 400 | { "success" : false, "error" : "Cannot retrieve template"} |
|
| 401 | { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"} |
|
| 404 | { "success" : false, "error" : "Template not found"} |
|
| 500 | { "success" : false, "error" : "Server Error."} |
Delete a template
Deletes either the template including all its versions, when using a template Id, or a specific version of a template when using a version Id.
The deletion process sets the expireAt timestamp to the current time: the template immediately stops being returned by the API, then the file is removed once the storage retention delay has passed (default: 24 hours). This is equivalent to calling PATCH /template/{id} with expireAt set to the current timestamp.
curl --location --request DELETE 'https://api.carbone.io/template/{templateId-or-versionId}' \
--header 'carbone-version: 5' \
--header 'Authorization: Bearer API_TOKEN'
Request header
{
// REQUIRED - Your API token (string)
"authorization" : "Bearer API_TOKEN",
// REQUIRED - Carbone-Version (string)
"carbone-version" : "5"
}
Response
A JSON is returned as body response.
On success, a status code 200 is returned.
| Status Code | Body | |
|---|---|---|
| 200 | { "success" : true } |
|
| 400 | { "success" : false, "error" : "Invalid templateId"} |
|
| 400 | { "success" : false, "error" : "Cannot delete template"} |
|
| 401 | { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"} |
|
| 404 | { "success" : false, "error" : "Template not found"} |
|
| 500 | { "success" : false, "error" : "Database error." } |
|
| 500 | { "success" : false, "error" : "Server Error."} |
Patch a Template
Updates specific metadata and attributes of an existing template identified by its template ID, or version ID. It allows:
- Metadata Management: Modify template metadata such as name, comment, and tags for improved organization and searchability.
- Version Deployment: Update the
deployedAtfield to control which version of a template is actively deployed, ensuring that the correct template version is used in document generation processes. - Lifecycle Control: Manage the template's lifecycle by updating the expiration timestamp, allowing for fine-grained control over template availability.
The identifier in the URL decides which version is patched:
- With a Template ID (64-bit format), Carbone patches the currently deployed version of that template.
- With a Version ID (SHA256 format), Carbone patches that exact version.
curl --location --request PATCH 'https://api.carbone.io/template/{templateId-or-versionId}' \
--header 'carbone-version: 5' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer API_TOKEN' \
--data-raw '{
"name": "Updated Template Name",
"comment": "Updated comment",
"category": "Folder1",
"tags": ["invoice", "contract", "v2"],
"expireAt": 0,
"deployedAt": 1625097600
}'
Request header
{
// REQUIRED - Your API token (string)
"authorization" : "Bearer API_TOKEN",
// REQUIRED - Content-type
"content-type" : "application/json",
// REQUIRED - Carbone-Version (string)
"carbone-version" : "5"
}
Request body
The request body should be a JSON object with the following optional properties:
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
String | No | Template ID (64-bit format) the patched version belongs to. Providing a Version ID (SHA256 format) is not allowed and will result in an API error. Changing this value moves the version to another Template ID. Target the version with its Version ID in the URL, otherwise you move the version that is currently deployed, and the original Template ID falls back to its next most recent version, or stops resolving if it has none left. An error is returned if the move creates a deployedAt conflict with the version already deployed under the destination Template ID. |
name |
String | No | Template name, 200 characters maximum. |
comment |
String | No | Template comment, 200 characters maximum. |
tags |
Array[String] | No | List of tags. Duplicates are removed and the list is returned sorted alphabetically. The whole list is limited to 100 characters, which is about 8 tags of 9 characters. |
category |
String | No | Group multiple templates into categories, similar to folders. 200 characters maximum. |
deployedAt |
Integer | No | When generating a document with a Template ID, Carbone uses the most recent deployedAt version. The deployedAt value must be a UTC Unix timestamp; values ≥ 42000000000 (year 3300) are interpreted as 'NOW'. Future values are not allowed. |
expireAt |
Integer | No | Schedule the template for deletion, as a UTC Unix timestamp in seconds. Nothing changes until that time. After it, the template is no longer listed, cannot be downloaded, and generating a document with it returns 404 Template not found. The file itself is deleted later, once the storage retention delay has passed.Send 0 to cancel a scheduled deletion and make the template permanent again. Omit the field to leave the current expiration untouched. |
Response
A JSON is returned as body response.
On success, a status code 200 is returned. The response always includes versionId, plus any fields provided in the request body are echoed back in the response.
| Status Code | Body | |
|---|---|---|
| 200 | { "success" : true, "data": { "versionId": "VERSION_ID", ...provided_fields } } |
|
| 400 | { "success" : false, "error" : "Invalid template metadata. Error: expireAt (-1) must be an integer between 0 and 9007199254740991." }Returned when a field value is rejected. The message after Invalid template metadata. names the offending field and the expected range or format. |
|
| 400 | { "success" : false, "error" : "Invalid template metadata. Error: "origin" is not allowed." }Returned when the body contains a field this endpoint does not accept. Only id, name, comment, tags, category, deployedAt and expireAt can be patched. |
|
| 400 | { "success" : false, "error" : "Invalid template metadata. Error: No valid attribute provided." }Returned when the body is empty: at least one field must be sent. |
|
| 400 | { "success" : false, "error" : "Invalid or undefined TemplateId or RenderId in the URL"} |
|
| 401 | { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"} |
|
| 404 | { "success" : false, "error" : "Template not found"} |
|
| 500 | { "success" : false, "error" : "Database error."} |
|
| 500 | { "success" : false, "error" : "Server Error."} |
List Templates
Retrieves a list of deployed templates from the Carbone storage. It supports filtering and pagination to manage large numbers of templates. The endpoint allows:
- Filtering: Filter templates by ID, version ID, and category to narrow down results based on specific criteria.
- Search: Utilize search for template names and exact matches for IDs and version IDs to quickly locate desired templates.
- Sorting: By default, the endpoint returns all deployed templates, sorted by creation date in descending order, excluding any that have expired. Changing the sorting order is not available for the moment.
- Pagination: This endpoint uses cursor-based pagination to manage large result sets. Each response includes two properties to control pagination:
hasMore(boolean): Indicates whether additional templates are available beyond the current set. Iffalse, the current response contains the last page of results.nextCursor(string): IfhasMoreistrue, this value specifies the cursor to use in the next request to fetch the subsequent batch of templates. Include it as a query parameter?cursor={value}in your follow-up request.
curl --location --request GET 'https://api.carbone.io/templates' \
--header 'carbone-version: 5' \
--header 'Authorization: Bearer API_TOKEN'
Request header
{
// REQUIRED - Your API token (string)
"authorization" : "Bearer API_TOKEN",
// REQUIRED - Carbone-Version (string)
"carbone-version" : "5"
}
Query Parameters
The endpoint supports filtering by various criteria such as: template Id, version ID, and category, offering flexibility to retrieve specific subsets of templates. Additionally, it supports fuzzy search in template names and exact matches on IDs and version IDs, enhancing discoverability.
| Parameter | Type | Description |
|---|---|---|
id |
String | Filter by Template ID (64-bit format). |
versionId |
String | Filter by Version ID (SHA256 format). |
category |
String | Filter by category. |
origin |
Integer | Filter templates by their upload origin. - 0: uploaded via the API.- 1: uploaded via the Studio.- 2: uploaded via the Salesforce integration.- 3: uploaded via the Odoo integration.- 4: uploaded via the HubSpot integration. |
includeVersions |
Boolean | Set true to list all versions for a specific template ID. By default equals to false. |
search |
String | Search in template name (fuzzy search), version ID (exact match), or template ID (exact match). |
limit |
Integer | Limit the number of items returned, from 1 to 100. By default equals to 100. |
cursor |
String | A cursor to use in pagination. The cursor defines your place in the list for fetching the next set of results. |
Response
On Success (status code 200), the response will include a list of templates with their metadata.
{
"success": true,
"data": [
{
"id": "",
"versionId": "",
"deployedAt": UTC_UNIX_TIMESTAMP,
"createdAt": UTC_UNIX_TIMESTAMP,
"expireAt": UTC_UNIX_TIMESTAMP,
"size": FILE_SIZE_IN_BYTES,
"type": "FILE_TYPE",
"name": "FILE_NAME",
"category": "",
"comment": "",
"tags": [],
"origin": 0
}
],
"hasMore": true,
"nextCursor": "CURSOR_HASH"
}
On Error
| Status Code | Body | |
|---|---|---|
| 400 | { "success" : false, "error" : "Invalid search filters. Error: limit (500) must be an integer between 1 and 101." }Returned when a query parameter is rejected. The message after Invalid search filters. names the offending parameter and the expected range or format. |
|
| 401 | { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"} |
|
| 500 | { "success" : false, "error" : "Database error."} |
|
| 500 | { "success" : false, "error" : "Server Error."} |
List Categories
Retrieve a list of all categories used in deployed templates, sorted by name. Categories function similarly to folders, allowing you to group and organize your templates effectively (e.g. "customer-x", "project-2026", "finances").
Practical Usage:
- Uploading a Template: When uploading a template, you can specify a category.
- Updating a Template: You can add or modify the category when updating template metadata.
- Listing Templates: You can filter templates by category to quickly find those that are relevant to a specific function or type.
curl --location --request GET 'https://api.carbone.io/templates/categories' \
--header 'carbone-version: 5' \
--header 'Authorization: Bearer API_TOKEN'
Request header
{
// REQUIRED - Your API token (string)
"authorization" : "Bearer API_TOKEN",
// REQUIRED - Carbone-Version (string)
"carbone-version" : "5"
}
Response
On Success (status code 200), the response will include a list of folders used in templates.
{
"success":true,
"data":[
{ "name":"folder1" },
{ "name":"customer2" }
]
}
On Error
| Status Code | Body | |
|---|---|---|
| 401 | { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"} |
|
| 500 | { "success" : false, "error" : "Database error."} |
|
| 500 | { "success" : false, "error" : "Server Error."} |
List Tags
List all tags currently used in deployed templates, sorted by name.
Tags are labels that you can attach to your templates for better organization. They help you categorize templates based on different criteria, such as the type of document (e.g., "invoice", "contract") or the version of the template (e.g., "v19.2.1").
Practical Usage:
- Uploading a Template: When uploading a template, you can specify tags to categorize it.
- Updating a Template: You can add or modify tags when updating template metadata.
- Listing Templates: This allows you to see which tags are assigned to each template, helping you to better organize templates. It is not possible to filter templates based on tags for the moment.
curl --location --request GET 'https://api.carbone.io/templates/tags' \
--header 'carbone-version: 5' \
--header 'Authorization: Bearer API_TOKEN'
Request header
{
// REQUIRED - Your API token (string)
"authorization" : "Bearer API_TOKEN",
// REQUIRED - Carbone-Version (string)
"carbone-version" : "5"
}
Response
On Success (status code 200), the response will include a list of tags used in templates.
{
"success":true,
"data":[
{ "name":"contract" },
{ "name":"invoice" },
{ "name":"tag3" },
{ "name":"v8.2.1" }
]
}
On Error
| Status Code | Body | |
|---|---|---|
| 401 | { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"} |
|
| 500 | { "success" : false, "error" : "Database error."} |
|
| 500 | { "success" : false, "error" : "Server Error."} |