Templify API Documentation

🚀 Introduction

Templify is an API-first SaaS that allows developers to create and manage templates, generate PDFs dynamically, and integrate powerful asynchronous workflows using webhooks. This documentation provides everything you need to start using the Templify API.

🔐 Authentication

Templify API requires authentication using both a Client ID and a Client Secret. These must be included in every API request via headers.

client_id: CLIENT_ID_HERE
client_secret: CLIENT_SECRET_HERE

You can generate & manage your API keys from the API Keys section of your dashboard.

🔗 API Endpoints

📄Generate PDF

Endpoint:

POST /convert/TEMPLATE_ID_HERE

Headers:

client_id: CLIENT_ID_HERE
client_secret: CLIENT_SECRET_HERE

Request Body:

{
  "templateData": {
    "name": "John Doe",
    "invoice_number": "INV-1001",
    "items": [
      { "description": "Item 1", "price": 20 },
      { "description": "Item 2", "price": 30 }
    ]
  }
}

Response:

{
  data: PDF_DOC_IN_BYTE_ARRAY
}

📬 Request & Response Examples

cURL Example:

1curl --location 'https://api.templify.cloud/convert/YOUR_TEMPLATE_ID_HERE' \
2--header 'client_id: USER_ID_HERE' \
3--header 'client_secret: CLIENT_SECRET_HERE' \
4--header 'Content-Type: application/json' \
5--header 'Cookie: NEXT_LOCALE=en' \
6--data '{
7  "templateData": {
8    "name": "John Doe",
9    "invoice_number": "INV-1001",
10    "items": [
11      { "description": "Item 1", "price": 20 },
12      { "description": "Item 2", "price": 30 }
13    ]
14  }
15}'

⚡ Asynchronous PDF Generation

Templify supports asynchronous PDF generation, allowing long-running documents to be processed in the background.

How to trigger async mode

You can request async processing using either:

  • Header: Prefer: respond-async
  • Query param: ?runMode=async

Example (async mode)

1curl --location 'https://api.templify.cloud/convert/TEMPLATE_ID?runMode=async' \
2--header 'Prefer: respond-async' \
3--header 'client_id: USER_ID' \
4--header 'client_secret: SECRET' \
5--header 'Content-Type: application/json' \
6--data '{ "templateData": { "name": "John" } }'

Async Response

{
  "template_id": "tmpl_123",
  "status": "STARTED",
  "job_id": "01HF4S8JAC9P7Z92K2N7Q3Y3G7"
}

📡 Webhooks for Async PDFs

When async mode is used, Templify sends webhook notifications at different stages of PDF generation.

Supported Events

  • pdf.started
  • pdf.generated
  • pdf.failed

Webhook Example Payloads

📤 pdf.started

{
  "id": "evt_84h1N3P2",
  "type": "pdf.started",
  "created_at": "2025-11-02T10:12:00Z",
  "attempt": 1,
  "meta": {
    "input_data": { "company_name": "ABC Corp" }
  }
}

📤 pdf.generated

{
  "id": "evt_84h1N3P2",
  "type": "pdf.generated",
  "created_at": "2025-11-02T10:12:00Z",
  "data": {
    "download_url": "https://cdn.templify.cloud/renders/xyz.pdf",
    "render_ms": 12450,
    "expires_at": "2025-11-03T10:12:00Z"
  }
}

📤 pdf.failed

{
  "id": "evt_84h1N3P3",
  "type": "pdf.failed",
  "data": {
    "error": {
      "code": "PDF_GENERATION_FAILED",
      "message": "Error generating PDF: HTML validation failed",
      "details": null
    },
    "render_ms": 350
  },
  "meta": {
    "template_id": "tmpl_999",
    "job_id": "job_8r9sm1a3",
    "input_data": { "company_name": "ABC Corp" }
  }
}

🔏 Webhook Signature Verification

🔑 Getting Your Webhook Secret

Each webhook endpoint in Templify is secured using a unique webhook secret.

This secret is automatically generated by Templify when you add a webhook URL from the dashboard.

  • Go to Settings → Webhooks
  • Add a new webhook endpoint URL
  • Copy the generated Webhook Secret

You must store this secret securely on your server and use it to validate incoming webhook requests.

Example:

TEMPLIFY_WEBHOOK_SECRET=whsec_4f8d2c9e9a0e6d

👉 You can manage your webhook endpoints and secrets from here:

Open Webhook Settings

Every webhook request includes the header:

x-templify-signature: sha256=<signature>

You should validate the signature on your server:

1const crypto = require("crypto");
2
3app.post("/webhooks/templify", (req, res) => {
4  const signature = req.headers["x-templify-signature"];
5  const payload = JSON.stringify(req.body);
6  const secret = process.env.TEMPLIFY_WEBHOOK_SECRET;
7
8  const expectedSignature =
9    "sha256=" +
10    crypto.createHmac("sha256", secret).update(payload).digest("hex");
11
12  if (
13    crypto.timingSafeEqual(
14      Buffer.from(signature),
15      Buffer.from(expectedSignature)
16    )
17  ) {
18    return res.status(200).send("OK");
19  }
20
21  res.status(401).send("Invalid signature");
22});

🧪 Testing Webhooks Locally (ngrok)

You can test webhooks locally using ngrok:

ngrok http 3000

# Example forwarding URL:
https://d7a3-10-1-2-55.ngrok-free.app

Use this URL as your Webhook URL in Templify dashboard:

https://YOUR_NGROK_URL/webhooks/templify

📦 Template Versioning

Templify supports template versioning, enabling you to safely develop, test, and deploy updates to your templates without affecting the live (production) version.

🚀 Default Behavior

  • When you create a new template, it is automatically published to production.
  • The template becomes immediately available to your generate PDF API calls (unless in dev mode).

🛠 Updating Templates

When editing a template, you have two options:

  1. Update (Save Only)
    • Saves the changes in the unpublished (dev) version.
    • Ideal for testing changes in lower environments (e.g., staging).
    • These changes do not affect the live template used in production.
  2. Update and Publish
    • Saves and publishes the new version to production.
    • All future PDF generations (including from generate API) will use this updated version.

🧪 Previewing Unpublished Versions (Dev Mode)

  • Add ?devMode=true to your preview or generation API calls.
  • This will render the latest saved (unpublished) version of the template.

Example curl to preview dev version:

1curl --location 'https://api.templify.cloud/convert/YOUR_TEMPLATE_ID_HERE?devMode=true' \
2--header 'client_id: USER_ID_HERE' \
3--header 'client_secret: CLIENT_SECRET_HERE' \
4--header 'Content-Type: application/json' \
5--data '{
6  "templateData": {
7    "name": "John Doe",
8    "invoice_number": "INV-1001",
9    "items": [
10      { "description": "Item 1", "price": 20 },
11      { "description": "Item 2", "price": 30 }
12    ]
13  }
14}'

✅ Production PDF Generation (Default Behavior)

When you call the /convert API without devMode=true, Templify will always use the latest published version of the template.

❌ Error Handling

Status CodeMeaningDescription
200OKSuccess
400Bad RequestMissing parameters
401UnauthorizedInvalid credentials
402Insufficient creditsCredit balance too low
404Not FoundTemplate not found
500Server ErrorUnexpected error

Example error response:

{
  "error": "Template ID not found"
}

🔒 Security & Best Practices

  • Store API keys securely.
  • Never expose secrets to frontend code.
  • Use HTTPS for all requests.
  • Use signature verification for all webhook requests.

📞 Contact & Support

Need help? We're here for you.

Happy coding! 🚀