Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.qflowhub.io/llms.txt

Use this file to discover all available pages before exploring further.

A template is the email content you send. It’s HTML + a subject line + sender details, scoped to a single event. You create a template once, then reference it by id when sending to attendees.

Create a template

curl -X POST 'https://api.qflowhub.io/comms/v1/api/comms/template' \
  -H 'Authorization: Bearer <token>' \
  -H 'Ocp-Apim-Subscription-Key: <subscription_key>' \
  -H 'Content-Type: application/json' \
  -d '{
    "id":          "<your guid (optional — for idempotent upserts)>",
    "eventId":     "4ef2891c-1e79-4c27-90b7-e2c20c8b13d9",
    "name":        "Ticket confirmation v1",
    "subject":     "Your ticket for {{event}} — {{firstname}}",
    "html":        "<html><body><h1>Hi {{firstname}}!</h1><p>Your ticket: {{barcode}}</p></body></html>",
    "fromAddress": "tickets@yourcompany.com",
    "fromName":    "Your Company Tickets",
    "replyTo":     "support@yourcompany.com",
    "attachPdf":   false
  }'
Response (200):
{
  "id": "7bc31757-5a82-4d7a-8767-bb508f6d3481",
  "eventId": "4ef2891c-1e79-4c27-90b7-e2c20c8b13d9",
  "name": "Ticket confirmation v1",
  "subject": "Your ticket for {{event}} — {{firstname}}",
  "html": "<html>...",
  "fromAddress": "tickets@yourcompany.com",
  "fromName": "Your Company Tickets",
  "replyTo": "support@yourcompany.com",
  "attachPdf": false,
  "created": "2026-04-30T10:00:00Z"
}
Capture the id — you’ll reference it when sending. If you supply your own id in the create request, the call is idempotent: posting the same id twice with different content is treated as an update.

Merge tokens

The following are replaced in subject and html per recipient:
TokenReplaced with
{{firstname}}Attendee’s first name
{{lastname}}Attendee’s last name
{{fullname}}First + last name
{{othernames}}Middle/other names
{{email}}Attendee’s email
{{barcode}}Attendee’s barcode (auto-generated if missing) — raw string, e.g. 4GA6965Q1G5EZ0FB
{{barcode_qr}}Fully-qualified QR-code image URL — drop into <img src="{{barcode_qr}}" />
{{plusones}}Number of plus-ones (or empty if 0)
{{guestnotes}}Attendee’s additionalInfo
{{tags}} / {{tickets}} / {{sessions}}Tag groups (one per line if multiple)
{{event}}Event title
{{date}}Event start date in event timezone (dd MMMM yyyy)
{{starttime}}, {{endtime}}Event times in event timezone (HH:mm)
{{companyname}}Sender’s company name
{{rsvplink_yes}}, {{rsvplink_no}}RSVP confirmation links
{{V_1}}, {{V_2}}, …Custom field values from the attendee’s CustomFields JSON
Tokens that don’t match (typo, no data) are left literal in the output.

PDF attachment

Setting attachPdf: true on the template makes every send from that template attach a PDF rendered from the same merge-resolved HTML the email body uses. Filename is {template-name}.pdf.
curl -X POST 'https://api.qflowhub.io/comms/v1/api/comms/template' \
  -H 'Authorization: Bearer <token>' -H 'Content-Type: application/json' \
  -d '{
    "id":         "<your guid>",
    "eventId":    "<event guid>",
    "name":       "Ticket Confirmation",
    "subject":    "Your ticket — {{firstname}}",
    "html":       "<h1>Hi {{firstname}}!</h1><p>Ticket: {{barcode}}</p><p><img src=\"{{barcode_qr}}\" /></p>",
    "attachPdf":  true
  }'
  • Same HTML for body + PDF — the PDF is what’s in the email, not a separate document.
  • Field is bool?. null (or omitted) leaves the existing flag alone on upserts — partial template updates won’t accidentally turn PDF off.
  • Toggle off any time by reposting the template with attachPdf: false.
  • PDF rendering is synchronous — adds ~1–2s per send. Pace bulk flushes accordingly.
If PDF generation fails (rendering server unreachable, malformed HTML), the entire send fails with comms.failed rather than shipping an email without the promised attachment.

Other template endpoints

MethodPathPurpose
GET/api/comms/template/{id}Fetch a single template
GET/api/comms/templates?eventId=<guid>List templates for an event
POST/api/comms/template/deleteDelete a template (body: {"id": "<guid>"})

URL safety scanning

Template HTML is automatically scanned by Google Web Risk on creation. Templates containing URLs flagged for malware, phishing, or unwanted software are rejected with 422:
{
  "error": "spam_check_failed",
  "message": "Template HTML contains URLs flagged as unsafe...",
  "flaggedUrls": [{"url": "https://...", "threatType": "MALWARE"}]
}
Remove the offending URLs and retry.