Template Controllers¶
Overview¶
Template controllers manage renderable template resources and provide document generation and delivery endpoints. All template controllers inherit the full Resource Controller endpoint set plus the template-specific operations documented here.
The following controllers are covered by this page:
| Controller | Base Path | Resource Type |
|---|---|---|
| TemplateController | /api/templates |
TEMPLATE (HTML/document) |
| EmailTemplateController | /api/email-templates |
EMAIL_TEMPLATE |
| FopTemplateController | /api/fop-templates |
FOP_TEMPLATE (XSL-FO) |
| OfficeTemplateController | /api/office-templates |
OFFICE_TEMPLATE (DOCX/XLSX) |
| ModificationTemplateController | /api/modificationTemplates |
MODIFICATION_TEMPLATE |
Each controller also inherits all endpoints documented in Resource Controller.
Authentication¶
All endpoints require the X-API-KEY header for authentication.
Template-Specific Endpoints¶
These endpoints are available on all five template controllers listed above (substitute the appropriate base path).
Generate Document¶
POST /{base-path}/{id}/generate-document
Generates a document from the template using the supplied data, and returns it as raw bytes, base64-encoded JSON, or routes it to the archive output channel (depending on outputMode).
Parameters¶
| Name | Type | In | Required | Description |
|---|---|---|---|---|
id |
integer (long) | path | Yes | Template resource ID |
X-API-KEY |
string | header | Yes | API authentication key |
Request Body¶
multipart/form-data:
| Part | Type | Required | Description |
|---|---|---|---|
data |
file | No | Input data file to merge with the template |
params |
JSON | Yes | GenerationParams object (see schema below) |
GenerationParams schema (extends DataParams):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | No | — | Output file name |
outputFormat |
string (enum) | No | PDF |
Output format. See OutputFormat values |
outputMode |
string (enum) | No | RAW |
Output mode. See OutputMode values |
data |
object | No | — | Key-value map of template variables |
sampleUUID |
string (UUID) | No | — | UUID of sample data to use |
resourceType |
string (enum) | No | — | Resource type hint |
OutputFormat values:
| Value | Content-Type | Description |
|---|---|---|
PDF |
application/pdf |
Generate as PDF |
HTML |
text/html |
Generate as HTML |
RAW |
application/octet-stream |
Generate in native/raw format |
OutputMode values:
| Value | Description |
|---|---|
RAW |
Return document bytes directly in the HTTP response |
BASE64 |
Return document as base64-encoded string in JSON |
ARCHIVE |
Route to the archive output channel (no document returned in response) |
Example params JSON:
{
"name": "invoice-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {
"customerName": "Acme Corp",
"invoiceNumber": "INV-2024-001",
"amount": 1250.00
}
}
Response¶
| Status | Description |
|---|---|
200 OK |
Document bytes (when outputMode=RAW) or GenerationResult JSON (when outputMode=BASE64) |
200 OK |
Empty body (when outputMode=ARCHIVE) |
GenerationResult schema (BASE64 mode):
{
"document": "<base64-encoded document content>",
"data": null,
"metadata": {
"uid": "abc123",
"name": "invoice-2024.pdf",
"fileName": "invoice-2024.pdf",
"contentType": "application/pdf",
"outputMode": "BASE64"
}
}
Error response (400):
Code Examples¶
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"strings"
)
func main() {
apiKey := "your-api-key"
baseURL := "https://your-comfly-instance.com"
templateID := "42"
params := `{
"name": "invoice-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {"customerName": "Acme Corp", "invoiceNumber": "INV-2024-001"}
}`
var buf bytes.Buffer
w := multipart.NewWriter(&buf)
// Optional data file
if _, err := os.Stat("data.xml"); err == nil {
fw, _ := w.CreateFormFile("data", "data.xml")
f, _ := os.Open("data.xml")
defer f.Close()
io.Copy(fw, f)
}
pw, _ := w.CreateFormField("params")
io.Copy(pw, strings.NewReader(params))
w.Close()
url := fmt.Sprintf("%s/api/templates/%s/generate-document", baseURL, templateID)
req, _ := http.NewRequest("POST", url, &buf)
req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("X-API-KEY", apiKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
out, _ := os.Create("output.pdf")
defer out.Close()
io.Copy(out, resp.Body)
fmt.Println("Document saved to output.pdf")
} else {
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Error %d: %s\n", resp.StatusCode, string(body))
}
}
import java.io.*;
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
public class GenerateDocument {
public static void main(String[] args) throws Exception {
String boundary = "----Boundary" + System.currentTimeMillis();
String params = """
{
"name": "invoice-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {"customerName": "Acme Corp"}
}
""";
byte[] paramsHeader = ("--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"params\"\r\n"
+ "Content-Type: application/json\r\n\r\n").getBytes();
byte[] paramsBody = params.getBytes();
byte[] footer = ("\r\n--" + boundary + "--\r\n").getBytes();
int len = paramsHeader.length + paramsBody.length + footer.length;
byte[] body = new byte[len];
int pos = 0;
for (byte[] part : new byte[][]{paramsHeader, paramsBody, footer}) {
System.arraycopy(part, 0, body, pos, part.length);
pos += part.length;
}
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://your-comfly-instance.com/api/templates/42/generate-document"))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.header("X-API-KEY", "your-api-key")
.POST(HttpRequest.BodyPublishers.ofByteArray(body))
.build();
HttpResponse<byte[]> response = client.send(request,
HttpResponse.BodyHandlers.ofByteArray());
if (response.statusCode() == 200) {
Files.write(Path.of("output.pdf"), response.body());
System.out.println("Document saved to output.pdf");
} else {
System.err.println("Error " + response.statusCode());
}
}
}
import json
import requests
api_key = "your-api-key"
base_url = "https://your-comfly-instance.com"
template_id = 42
params = {
"name": "invoice-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {"customerName": "Acme Corp", "invoiceNumber": "INV-2024-001"}
}
url = f"{base_url}/api/templates/{template_id}/generate-document"
files = {
"params": (None, json.dumps(params), "application/json"),
# Optionally: "data": ("data.xml", open("data.xml", "rb"), "application/xml"),
}
try:
response = requests.post(url, files=files, headers={"X-API-KEY": api_key})
response.raise_for_status()
with open("output.pdf", "wb") as f:
f.write(response.content)
print("Document saved to output.pdf")
except requests.HTTPError as e:
print(f"Error {e.response.status_code}: {e.response.text}")
<?php
$apiKey = 'your-api-key';
$baseUrl = 'https://your-comfly-instance.com';
$templateId = 42;
$params = json_encode([
'name' => 'invoice-2024.pdf',
'outputFormat' => 'PDF',
'outputMode' => 'RAW',
'data' => ['customerName' => 'Acme Corp'],
]);
$boundary = '----Boundary' . uniqid();
$body = "--{$boundary}\r\n";
$body .= "Content-Disposition: form-data; name=\"params\"\r\n";
$body .= "Content-Type: application/json\r\n\r\n";
$body .= $params . "\r\n";
$body .= "--{$boundary}--\r\n";
$ch = curl_init("{$baseUrl}/api/templates/{$templateId}/generate-document");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data; boundary={$boundary}",
"X-API-KEY: {$apiKey}",
],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
file_put_contents('output.pdf', $response);
echo "Document saved to output.pdf\n";
} else {
echo "Error {$httpCode}: {$response}\n";
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var apiKey = "your-api-key";
var baseUrl = "https://your-comfly-instance.com";
var templateId = 42;
var paramsObj = new
{
name = "invoice-2024.pdf",
outputFormat = "PDF",
outputMode = "RAW",
data = new { customerName = "Acme Corp" }
};
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", apiKey);
var multipart = new MultipartFormDataContent();
multipart.Add(
new StringContent(JsonSerializer.Serialize(paramsObj),
Encoding.UTF8, "application/json"),
"params");
var response = await client.PostAsync(
$"{baseUrl}/api/templates/{templateId}/generate-document", multipart);
if (response.IsSuccessStatusCode)
{
var bytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("output.pdf", bytes);
Console.WriteLine("Document saved to output.pdf");
}
else
{
var body = await response.Content.ReadAsStringAsync();
Console.Error.WriteLine($"Error {(int)response.StatusCode}: {body}");
}
}
}
require 'net/http'
require 'json'
require 'uri'
api_key = 'your-api-key'
base_url = 'https://your-comfly-instance.com'
template_id = 42
params = JSON.generate(
name: 'invoice-2024.pdf',
outputFormat: 'PDF',
outputMode: 'RAW',
data: { customerName: 'Acme Corp' }
)
boundary = "----Boundary#{Time.now.to_i}"
body = "--#{boundary}\r\n"
body += "Content-Disposition: form-data; name=\"params\"\r\n"
body += "Content-Type: application/json\r\n\r\n"
body += "#{params}\r\n"
body += "--#{boundary}--\r\n"
uri = URI("#{base_url}/api/templates/#{template_id}/generate-document")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
request['X-API-KEY'] = api_key
request.body = body
response = http.request(request)
if response.code.to_i == 200
File.binwrite('output.pdf', response.body)
puts 'Document saved to output.pdf'
else
warn "Error #{response.code}: #{response.body}"
end
Generate Document Asynchronously¶
POST /{base-path}/{id}/generate-document-async
Starts asynchronous document generation. Returns a job ID immediately. The generated document is delivered via the callback URL when complete.
Parameters¶
| Name | Type | In | Required | Description |
|---|---|---|---|---|
id |
integer (long) | path | Yes | Template resource ID |
X-API-KEY |
string | header | Yes | API authentication key |
Request Body¶
multipart/form-data:
| Part | Type | Required | Description |
|---|---|---|---|
data |
file | No | Input data file |
params |
JSON | Yes | AsyncGenerationParams object |
AsyncGenerationParams schema (extends GenerationParams):
All fields from GenerationParams plus:
| Field | Type | Required | Description |
|---|---|---|---|
callback |
object | No | Callback configuration for async notification |
callback.callbackUrl |
string | Yes (if callback set) | URL to POST the result to |
callback.queryParams |
object | No | Additional query parameters to include in the callback request |
callback.headers |
object | No | Additional headers to include in the callback request |
Example params JSON:
{
"name": "report-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {"month": "January", "year": 2024},
"callback": {
"callbackUrl": "https://my-app.example.com/webhook/document-ready",
"queryParams": {"jobRef": "JOB-001"},
"headers": {"Authorization": "Bearer my-webhook-token"}
}
}
Response¶
| Status | Description |
|---|---|
202 Accepted |
Job accepted; returns job ID (long) |
400 Bad Request |
Invalid parameters |
Example response:
Code Examples¶
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"strings"
)
func main() {
apiKey := "your-api-key"
baseURL := "https://your-comfly-instance.com"
templateID := "42"
params := `{
"name": "report-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {"month": "January"},
"callback": {
"callbackUrl": "https://my-app.example.com/webhook/document-ready"
}
}`
var buf bytes.Buffer
w := multipart.NewWriter(&buf)
pw, _ := w.CreateFormField("params")
io.Copy(pw, strings.NewReader(params))
w.Close()
url := fmt.Sprintf("%s/api/templates/%s/generate-document-async", baseURL, templateID)
req, _ := http.NewRequest("POST", url, &buf)
req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("X-API-KEY", apiKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusAccepted {
jobID, _ := io.ReadAll(resp.Body)
fmt.Printf("Job accepted, ID: %s\n", string(jobID))
} else {
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Error %d: %s\n", resp.StatusCode, string(body))
}
}
import java.net.URI;
import java.net.http.*;
public class GenerateDocumentAsync {
public static void main(String[] args) throws Exception {
String boundary = "----Boundary" + System.currentTimeMillis();
String params = """
{
"name": "report-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {"month": "January"},
"callback": {
"callbackUrl": "https://my-app.example.com/webhook/ready"
}
}
""";
byte[] bodyBytes = ("--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"params\"\r\n"
+ "Content-Type: application/json\r\n\r\n"
+ params + "\r\n--" + boundary + "--\r\n").getBytes();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://your-comfly-instance.com/api/templates/42/generate-document-async"))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.header("X-API-KEY", "your-api-key")
.POST(HttpRequest.BodyPublishers.ofByteArray(bodyBytes))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 202) {
System.out.println("Job ID: " + response.body());
} else {
System.err.println("Error " + response.statusCode() + ": " + response.body());
}
}
}
import json
import requests
api_key = "your-api-key"
template_id = 42
params = {
"name": "report-2024.pdf",
"outputFormat": "PDF",
"outputMode": "RAW",
"data": {"month": "January"},
"callback": {
"callbackUrl": "https://my-app.example.com/webhook/document-ready"
}
}
response = requests.post(
f"https://your-comfly-instance.com/api/templates/{template_id}/generate-document-async",
files={"params": (None, json.dumps(params), "application/json")},
headers={"X-API-KEY": api_key}
)
if response.status_code == 202:
print(f"Job ID: {response.text}")
else:
print(f"Error {response.status_code}: {response.text}")
<?php
$params = json_encode([
'name' => 'report-2024.pdf',
'outputFormat' => 'PDF',
'outputMode' => 'RAW',
'data' => ['month' => 'January'],
'callback' => ['callbackUrl' => 'https://my-app.example.com/webhook/ready'],
]);
$boundary = '----Boundary' . uniqid();
$body = "--{$boundary}\r\nContent-Disposition: form-data; name=\"params\"\r\n";
$body .= "Content-Type: application/json\r\n\r\n{$params}\r\n--{$boundary}--\r\n";
$ch = curl_init('https://your-comfly-instance.com/api/templates/42/generate-document-async');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data; boundary={$boundary}",
'X-API-KEY: your-api-key',
],
]);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $code == 202 ? "Job ID: {$response}\n" : "Error {$code}: {$response}\n";
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program {
static async Task Main() {
var paramsObj = new {
name = "report-2024.pdf", outputFormat = "PDF", outputMode = "RAW",
data = new { month = "January" },
callback = new { callbackUrl = "https://my-app.example.com/webhook/ready" }
};
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", "your-api-key");
var multipart = new MultipartFormDataContent();
multipart.Add(
new StringContent(JsonSerializer.Serialize(paramsObj),
Encoding.UTF8, "application/json"), "params");
var response = await client.PostAsync(
"https://your-comfly-instance.com/api/templates/42/generate-document-async",
multipart);
if (response.StatusCode == System.Net.HttpStatusCode.Accepted)
Console.WriteLine("Job ID: " + await response.Content.ReadAsStringAsync());
else
Console.Error.WriteLine($"Error {(int)response.StatusCode}");
}
}
require 'net/http'
require 'json'
params = JSON.generate(
name: 'report-2024.pdf', outputFormat: 'PDF', outputMode: 'RAW',
data: { month: 'January' },
callback: { callbackUrl: 'https://my-app.example.com/webhook/ready' }
)
boundary = "----Boundary#{Time.now.to_i}"
body = "--#{boundary}\r\nContent-Disposition: form-data; name=\"params\"\r\n" \
"Content-Type: application/json\r\n\r\n#{params}\r\n--#{boundary}--\r\n"
uri = URI('https://your-comfly-instance.com/api/templates/42/generate-document-async')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
req['X-API-KEY'] = 'your-api-key'
req.body = body
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
res.code.to_i == 202 ? puts("Job ID: #{res.body}") : warn("Error #{res.code}: #{res.body}")
Deliver Document¶
POST /{base-path}/{id}/deliver-document
Generates a document and immediately delivers it to a configured output channel (file, printer, SMTP, etc.).
Parameters¶
| Name | Type | In | Required | Description |
|---|---|---|---|---|
id |
integer (long) | path | Yes | Template resource ID |
X-API-KEY |
string | header | Yes | API authentication key |
Request Body¶
multipart/form-data:
| Part | Type | Required | Description |
|---|---|---|---|
data |
file | No | Input data file |
params |
JSON | Yes | DeliveryParams object |
DeliveryParams schema (extends DataParams):
| Field | Type | Required | Description |
|---|---|---|---|
outputChannelType |
string (enum) | Yes | Target output channel. See OutputChannelType |
data |
object | No | Key-value map of template variables |
sampleUUID |
string (UUID) | No | UUID of sample data to use |
resourceType |
string (enum) | No | Resource type hint |
Response¶
| Status | Description |
|---|---|
200 OK |
Document delivered successfully |
400 Bad Request |
Delivery failed; returns error JSON |
Error response (400):
Code Examples¶
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"strings"
)
func main() {
apiKey := "your-api-key"
baseURL := "https://your-comfly-instance.com"
templateID := "42"
params := `{
"outputChannelType": "SMTP",
"data": {"recipient": "john@example.com", "subject": "Your Invoice"}
}`
var buf bytes.Buffer
w := multipart.NewWriter(&buf)
pw, _ := w.CreateFormField("params")
io.Copy(pw, strings.NewReader(params))
w.Close()
url := fmt.Sprintf("%s/api/templates/%s/deliver-document", baseURL, templateID)
req, _ := http.NewRequest("POST", url, &buf)
req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("X-API-KEY", apiKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
fmt.Println("Document delivered")
} else {
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Error %d: %s\n", resp.StatusCode, string(body))
}
}
import java.net.URI;
import java.net.http.*;
public class DeliverDocument {
public static void main(String[] args) throws Exception {
String boundary = "----Boundary" + System.currentTimeMillis();
String params = "{\"outputChannelType\":\"SMTP\","
+ "\"data\":{\"recipient\":\"john@example.com\"}}";
byte[] bodyBytes = ("--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"params\"\r\n"
+ "Content-Type: application/json\r\n\r\n"
+ params + "\r\n--" + boundary + "--\r\n").getBytes();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://your-comfly-instance.com/api/templates/42/deliver-document"))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.header("X-API-KEY", "your-api-key")
.POST(HttpRequest.BodyPublishers.ofByteArray(bodyBytes))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() == 200
? "Delivered" : "Error: " + response.body());
}
}
import json
import requests
params = {
"outputChannelType": "SMTP",
"data": {"recipient": "john@example.com", "subject": "Your Invoice"}
}
response = requests.post(
"https://your-comfly-instance.com/api/templates/42/deliver-document",
files={"params": (None, json.dumps(params), "application/json")},
headers={"X-API-KEY": "your-api-key"}
)
print("Delivered" if response.ok else f"Error {response.status_code}: {response.text}")
<?php
$params = json_encode(['outputChannelType' => 'SMTP',
'data' => ['recipient' => 'john@example.com']]);
$boundary = '----Boundary' . uniqid();
$body = "--{$boundary}\r\nContent-Disposition: form-data; name=\"params\"\r\n"
. "Content-Type: application/json\r\n\r\n{$params}\r\n--{$boundary}--\r\n";
$ch = curl_init('https://your-comfly-instance.com/api/templates/42/deliver-document');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data; boundary={$boundary}",
'X-API-KEY: your-api-key',
],
]);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $code === 200 ? "Delivered\n" : "Error {$code}: {$response}\n";
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program {
static async Task Main() {
var paramsObj = new {
outputChannelType = "SMTP",
data = new { recipient = "john@example.com" }
};
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", "your-api-key");
var mp = new MultipartFormDataContent();
mp.Add(new StringContent(JsonSerializer.Serialize(paramsObj),
Encoding.UTF8, "application/json"), "params");
var response = await client.PostAsync(
"https://your-comfly-instance.com/api/templates/42/deliver-document", mp);
Console.WriteLine(response.IsSuccessStatusCode
? "Delivered" : $"Error {(int)response.StatusCode}");
}
}
require 'net/http'
require 'json'
params = JSON.generate(outputChannelType: 'SMTP',
data: { recipient: 'john@example.com' })
boundary = "----Boundary#{Time.now.to_i}"
body = "--#{boundary}\r\nContent-Disposition: form-data; name=\"params\"\r\n" \
"Content-Type: application/json\r\n\r\n#{params}\r\n--#{boundary}--\r\n"
uri = URI('https://your-comfly-instance.com/api/templates/42/deliver-document')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
req['X-API-KEY'] = 'your-api-key'
req.body = body
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.code.to_i == 200 ? 'Delivered' : "Error #{res.code}: #{res.body}"
Get PDF Preview¶
GET /{base-path}/{id}/preview/{dummyFileName}
Generates a PDF preview of the template. Optionally stores the first page as a thumbnail.
Note
This endpoint is considered legacy. Prefer POST /{id}/generate-document with outputFormat=PDF.
Parameters¶
| Name | Type | In | Required | Description |
|---|---|---|---|---|
id |
integer (long) | path | Yes | Template resource ID |
dummyFileName |
string | path | Yes | Filename hint included in the Content-Disposition header |
dataId |
integer (long) | query | No | ID of sample data to use for preview |
inputChannelConfigId |
integer (long) | query | No | ID of input channel configuration to use |
setThumbnail |
boolean | query | No | If true, stores the first page as thumbnail on the resource |
X-API-KEY |
string | header | Yes | API authentication key |
Response¶
| Status | Description |
|---|---|
200 OK |
PDF bytes with Content-Type: application/pdf |
204 No Content |
Template produced no output |
Code Examples¶
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET",
"https://your-comfly-instance.com/api/templates/42/preview/preview.pdf?setThumbnail=false",
nil)
req.Header.Set("X-API-KEY", "your-api-key")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
f, _ := os.Create("preview.pdf")
defer f.Close()
io.Copy(f, resp.Body)
fmt.Println("Preview saved")
} else {
fmt.Printf("Status: %d\n", resp.StatusCode)
}
}
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
public class GetPreview {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://your-comfly-instance.com/api/templates/42/preview/preview.pdf"))
.header("X-API-KEY", "your-api-key")
.GET()
.build();
HttpResponse<byte[]> response = client.send(request,
HttpResponse.BodyHandlers.ofByteArray());
if (response.statusCode() == 200)
Files.write(Path.of("preview.pdf"), response.body());
}
}
<?php
$ch = curl_init(
'https://your-comfly-instance.com/api/templates/42/preview/preview.pdf');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-KEY: your-api-key'],
]);
$pdf = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code === 200) file_put_contents('preview.pdf', $pdf);
using System.IO;
using System.Net.Http;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", "your-api-key");
var bytes = await client.GetByteArrayAsync(
"https://your-comfly-instance.com/api/templates/42/preview/preview.pdf");
await File.WriteAllBytesAsync("preview.pdf", bytes);
require 'net/http'
uri = URI('https://your-comfly-instance.com/api/templates/42/preview/preview.pdf')
req = Net::HTTP::Get.new(uri)
req['X-API-KEY'] = 'your-api-key'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
File.binwrite('preview.pdf', res.body) if res.code.to_i == 200