Generate concert ticket PDFs with QR codes using PDF Generator API
Automate the creation and distribution of concert tickets with unique QR codes. This workflow uses a FormTrigger to collect attendee data, generates a PDF ticket with PDF Generator API, sends it via Gmail, logs the sale in Google Sheets, and notifies Slack. Event organizers and promoters can efficiently manage ticket sales, reduce manual effort, and ensure secure ticket delivery. This saves significant time and improves the attendee experience.
Workflow JSON
{"id":"xJYtz0FU0LQCj4uN","meta":{"instanceId":"82c5bea520362e516241165c0caf720c8d29d2f0ba5e3cae2ba36d2c25d3b3b3","templateCredsSetupCompleted":true},"name":"Concert Ticket Generator with QR Code (PDF Generator API)","tags":[],"nodes":[{"id":"sticky-001","name":"π Setup Instructions","type":"n8n-nodes-base.stickyNote","position":[-192,-448],"parameters":{"width":892,"height":776,"content":"## π΅ Concert Ticket Generator\n### Powered by PDF Generator API\n\nThis workflow accepts ticket requests via a web form, generates a personalized **PDF ticket with a built-in QR code** using **PDF Generator API**, emails it to the attendee, logs the sale to **Google Sheets**, and notifies the event organizer via **Slack**.\n\n---\n\n### βοΈ Setup (4 steps)\n\n**1. Create a PDF ticket template in PDF Generator API**\nSign up at [pdfgeneratorapi.com](https://pdfgeneratorapi.com) β Templates β New Template.\nDesign your concert ticket and use these data variables:\n- `ticket_id` β unique ticket identifier *(also the QR code data β see note β)*\n- `attendee_name` Β· `event_name` Β· `venue` Β· `event_date` Β· `seat_number`\n- `ticket_tier` β tier badge (GENERAL / VIP / BACKSTAGE)\n- `issued_date` β ticket issue date\n\n**2. Set your Template ID**\nIn the **Generate Concert Ticket PDF** node, replace `123456` with your actual template ID (found in the PDF Generator API dashboard).\n\n**3. Add credentials**\n- **Generate Concert Ticket PDF** node β add your PDF Generator API credentials\n- **Send Ticket to Attendee** node β connect your Gmail account\n- **Log Ticket Sale** node β connect your Google Sheets account\n- **Notify Event Organizer** node β connect your Slack account\n\n**4. Configure Google Sheets & Slack**\nSee the sticky notes on the right for details."},"typeVersion":1},{"id":"sticky-002","name":"π² QR Code & PDF Output","type":"n8n-nodes-base.stickyNote","position":[768,-80],"parameters":{"color":4,"width":420,"height":412,"content":"### π² QR Code β Built into the Template\n\nThe QR code is **not generated by this workflow**. Instead, it is a native **QR Code component** inside your PDF Generator API template.\n\n**How to set it up in the template editor:**\n1. Open your template in PDF Generator API\n2. Add a **QR Code** component to the ticket design\n3. Set the QR code data field to: `{{ ticket_id }}`\n4. The QR will automatically encode the unique ticket ID for each generated PDF\n\nThis approach is simpler, more reliable, and gives you full design control over QR code size and position.\n\n---\n**Output format:** `URL` β the node returns a hosted PDF link valid for 30 days. Change to `File` to attach the PDF directly to the email (update the Gmail node accordingly)."},"typeVersion":1},{"id":"sticky-003","name":"π Google Sheets Setup","type":"n8n-nodes-base.stickyNote","position":[1264,16],"parameters":{"color":3,"width":380,"height":304,"content":"### π Google Sheets Tracker\n\nLogs every issued ticket for event management.\n\n**Setup:**\n1. Create a Google Sheet with a tab named **Tickets**\n2. Add these column headers in row 1:\n `Ticket ID` Β· `Attendee` Β· `Email` Β· `Event` Β· `Venue` Β· `Date` Β· `Seat` Β· `Tier` Β· `PDF URL` Β· `Issued At`\n3. In the **Log Ticket Sale** node, set your Spreadsheet ID and connect your Google account\n\nπ‘ Use this sheet to track attendance, validate tickets at the door, or export attendee lists."},"typeVersion":1},{"id":"sticky-004","name":"π Slack Setup","type":"n8n-nodes-base.stickyNote","position":[1744,32],"parameters":{"color":7,"width":340,"height":294,"content":"### π Slack Notification\n\nSends a real-time alert to the event organizer whenever a new ticket is issued.\n\n**Setup:**\n1. Connect your Slack workspace in the **Notify Event Organizer** node\n2. Set the channel name (e.g. `#tickets` or `#events`)\n3. Optional: remove this node if you don't use Slack"},"typeVersion":1},{"id":"node-form","name":"Concert Ticket Form","type":"n8n-nodes-base.formTrigger","position":[288,384],"webhookId":"cc000001-0000-0000-0000-000000000001","parameters":{"path":"cc+1234567890-+1234567890","options":{},"formTitle":"π΅ Concert Ticket Request","formFields":{"values":[{"fieldLabel":"Full Name","placeholder":"Jane Smith","requiredField":true},{"fieldType":"email","fieldLabel":"Email Address","placeholder":"user@example.com","requiredField":true},{"fieldLabel":"Event Name","placeholder":"Summer Rock Festival 2025","requiredField":true},{"fieldLabel":"Venue","placeholder":"Madison Square Garden, New York","requiredField":true},{"fieldLabel":"Event Date","placeholder":"Saturday, July 5, 2025","requiredField":true},{"fieldLabel":"Seat Number","placeholder":"Section A, Row 3, Seat 12","requiredField":true},{"fieldType":"dropdown","fieldLabel":"Ticket Tier","fieldOptions":{"values":[{"option":"General Admission"},{"option":"VIP"},{"option":"Backstage Pass"}]},"requiredField":true}]},"formDescription":"Fill in your details to receive your personalized concert ticket via email. Your PDF ticket includes a unique QR code for venue entry."},"typeVersion":2.1},{"id":"node-prepare","name":"Prepare Ticket Data","type":"n8n-nodes-base.code","position":[688,384],"parameters":{"jsCode":"const item = $input.item.json;\n\n// Generate unique ticket ID (URL-safe, 8 chars)\nconst chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\nlet suffix = '';\nfor (let i = 0; i < 8; i++) {\n suffix += chars[Math.floor(Math.random() * chars.length)];\n}\nconst ticketId = 'TKT-' + suffix;\n\nconst issuedDate = new Date().toLocaleDateString('en-US', {\n year: 'numeric', month: 'long', day: 'numeric'\n});\n\nconst ticketTier = item['Ticket Tier'] || 'General Admission';\n\n// Tier badge for the PDF template and email\nconst tierBadge = ticketTier === 'VIP' ? 'VIP'\n : ticketTier === 'Backstage Pass' ? 'BACKSTAGE'\n : 'GENERAL';\n\n// Tier accent colour used in the confirmation email\nconst tierColor = ticketTier === 'VIP' ? '#7B2FBE'\n : ticketTier === 'Backstage Pass' ? '#C0392B'\n : '#0f3460';\n\n// β οΈ Replace 123456 with your PDF Generator API template ID.\n// The template should include a QR Code component whose data is set to {{ ticket_id }}.\nconst TEMPLATE_ID = 1615251;\n\nreturn [{\n json: {\n ticketId,\n attendeeName: item['Full Name'],\n attendeeEmail: item['Email Address'],\n eventName: item['Event Name'],\n venue: item['Venue'],\n eventDate: item['Event Date'],\n seatNumber: item['Seat Number'],\n ticketTier,\n tierBadge,\n tierColor,\n issuedDate,\n emailSubject: `π« Your ${ticketTier} Ticket: ${item['Event Name']} β ${ticketId}`,\n templateId: TEMPLATE_ID,\n outputName: `concert-ticket-${ticketId}`,\n // Variables passed to the PDF Generator API template.\n // Map each one to the corresponding component in your template editor.\n templateData: {\n ticket_id: ticketId,\n attendee_name: item['Full Name'],\n event_name: item['Event Name'],\n venue: item['Venue'],\n event_date: item['Event Date'],\n seat_number: item['Seat Number'],\n ticket_tier: tierBadge,\n issued_date: issuedDate\n }\n }\n}];\n"},"typeVersion":2},{"id":"node-pdfgen","name":"Generate Concert Ticket PDF","type":"@pdfgeneratorapi/n8n-nodes-pdf-generator-api.pdfGeneratorApi","position":[1088,384],"parameters":{"data":"={{ JSON.stringify($json.templateData) }}","templateId":{"__rl":true,"mode":"id","value":"={{ $json.templateId }}"},"documentOutput":"url","additionalFields":{"outputName":"={{ $json.outputName }}"}},"credentials":{"pdfGeneratorApi":{"id":"credential-id","name":"PDF Generator account 2"}},"typeVersion":1},{"id":"node-buildemail","name":"Build Confirmation Email","type":"n8n-nodes-base.code","position":[1488,384],"parameters":{"jsCode":"const pdfData = $input.item.json;\nconst t = $('Prepare Ticket Data').item.json;\n\n// URL returned by PDF Generator API (documentOutput: url)\nconst pdfUrl = pdfData.response || '';\n\n// Tier-specific header colour\nconst headerColor = t.tierColor || '#0f3460';\n\nconst emailHtml = ''\n + '<!DOCTYPE html><html><body style=\"margin:0;padding:0;background:#f4f4f8;font-family:Arial,sans-serif\">'\n + '<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"padding:24px 0\"><tr><td align=\"center\">'\n + '<table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.12)\">'\n\n // Header\n + '<tr><td style=\"background:' + headerColor + ';padding:36px 30px;text-align:center\">'\n + '<div style=\"font-size:44px;line-height:1\">π΅</div>'\n + '<h1 style=\"color:#fff;margin:10px 0 4px;font-size:24px;font-weight:700\">Your Concert Ticket</h1>'\n + '<span style=\"display:inline-block;background:rgba(255,255,255,0.2);color:#fff;padding:4px 18px;border-radius:20px;font-size:11px;letter-spacing:2px;font-weight:700;margin-top:6px\">'\n + t.tierBadge\n + '</span>'\n + '</td></tr>'\n\n // Body\n + '<tr><td style=\"padding:32px 40px\">'\n + '<p style=\"font-size:16px;color:#333;margin:0 0 10px\">Hi <strong>' + t.attendeeName + '</strong>,</p>'\n + '<p style=\"color:#555;line-height:1.7;margin:0 0 24px\">Your <strong>' + t.ticketTier + '</strong> ticket is confirmed! Your personalized PDF β complete with a unique entry QR code β is ready to download.</p>'\n\n // Event card\n + '<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"border:2px dashed ' + headerColor + ';border-radius:10px;margin-bottom:24px\"><tr><td style=\"padding:22px\">'\n + '<h2 style=\"color:' + headerColor + ';margin:0 0 14px;font-size:19px\">πΈ ' + t.eventName + '</h2>'\n + '<p style=\"margin:6px 0;color:#555;font-size:14px\">π <strong>Venue:</strong> ' + t.venue + '</p>'\n + '<p style=\"margin:6px 0;color:#555;font-size:14px\">π
<strong>Date:</strong> ' + t.eventDate + '</p>'\n + '<p style=\"margin:6px 0;color:#555;font-size:14px\">πΊ <strong>Seat:</strong> ' + t.seatNumber + '</p>'\n + '<p style=\"margin:6px 0;color:#555;font-size:14px\">π« <strong>Ticket ID:</strong> <code style=\"background:#f0f0f0;padding:2px 7px;border-radius:4px;font-size:13px\">' + t.ticketId + '</code></p>'\n + '</td></tr></table>'\n\n // Download button\n + '<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr><td align=\"center\" style=\"padding-bottom:24px\">'\n + '<a href=\"' + pdfUrl + '\" style=\"background:' + headerColor + ';color:#fff;padding:14px 44px;border-radius:8px;text-decoration:none;font-size:15px;font-weight:700;display:inline-block\">π Download PDF Ticket</a>'\n + '</td></tr></table>'\n\n + '<p style=\"color:#999;font-size:12px;text-align:center;margin:0 0 4px\">Your PDF contains a unique QR code for venue entry.</p>'\n + '<p style=\"color:#bbb;font-size:11px;text-align:center;margin:0\">Please have it ready β printed or on your phone.</p>'\n + '</td></tr>'\n\n // Footer\n + '<tr><td style=\"background:#f8f8f8;padding:16px 30px;text-align:center;border-top:1px solid #eee\">'\n + '<p style=\"color:#bbb;font-size:11px;margin:0\">PDF ticket generated with <a href=\"https://pdfgeneratorapi.com\" style=\"color:' + headerColor + ';text-decoration:none\">PDF Generator API</a> • Automated by <a href=\"https://n8n.io\" style=\"color:' + headerColor + ';text-decoration:none\">n8n</a></p>'\n + '</td></tr>'\n + '</table></td></tr></table></body></html>';\n\nreturn [{\n json: {\n attendeeEmail: t.attendeeEmail,\n emailSubject: t.emailSubject,\n emailHtml,\n pdfUrl,\n ticketId: t.ticketId,\n eventName: t.eventName,\n tierBadge: t.tierBadge\n }\n}];\n"},"typeVersion":2},{"id":"node-gmail","name":"Send Ticket to Attendee","type":"n8n-nodes-base.gmail","position":[1760,384],"webhookId":"a4e0dd25-c113-4f97-97c8-d38d323dd8dd","parameters":{"sendTo":"={{ $json.attendeeEmail }}","message":"={{ $json.emailHtml }}","options":{},"subject":"={{ $json.emailSubject }}"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.1},{"id":"node-sheets","name":"Log Ticket Sale","type":"n8n-nodes-base.googleSheets","position":[2016,384],"parameters":{"columns":{"value":{},"schema":[],"mappingMode":"autoMapInputData","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1hlzNCuQQH_1qq7fQiwRcxq84rKeR9bOVnf8o8hb4wug/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1hlzNCuQQH_1qq7fQiwRcxq84rKeR9bOVnf8o8hb4wug","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1hlzNCuQQH_1qq7fQiwRcxq84rKeR9bOVnf8o8hb4wug/edit?usp=drivesdk","cachedResultName":"Concert Tickets"}},"credentials":{"googleSheetsOAuth2Api":{"id":"credential-id","name":"Google Sheets account 2"}},"typeVersion":4.5},{"id":"node-slack","name":"Notify Event Organizer","type":"n8n-nodes-base.slack","position":[2288,384],"webhookId":"a7801711-2ba0-41b9-9dec-af02009f594e","parameters":{"text":"={{ 'π« New ticket issued!\\n*' + $('Prepare Ticket Data').item.json.tierBadge + '* β ' + $('Prepare Ticket Data').item.json.eventName + '\\n\\nπ€ *Attendee:* ' + $('Prepare Ticket Data').item.json.attendeeName + '\\nπ§ ' + $('Prepare Ticket Data').item.json.attendeeEmail + '\\nπΊ *Seat:* ' + $('Prepare Ticket Data').item.json.seatNumber + '\\nπ *Ticket ID:* ' + $('Prepare Ticket Data').item.json.ticketId + '\\n\\nπ PDF: ' + $('Generate Concert Ticket PDF').item.json.response }}","user":{"__rl":true,"mode":"id","value":"U02P412345"},"select":"user","otherOptions":{}},"credentials":{"slackApi":{"id":"credential-id","name":"Slack account 2"}},"typeVersion":2.3}],"active":false,"pinData":{},"settings":{"callerPolicy":"workflowsFromSameOwner","availableInMCP":false,"executionOrder":"v1"},"versionId":"59716666-a031-4373-981d-99e95d12a1f9","connections":{"Log Ticket Sale":{"main":[[{"node":"Notify Event Organizer","type":"main","index":0}]]},"Concert Ticket Form":{"main":[[{"node":"Prepare Ticket Data","type":"main","index":0}]]},"Prepare Ticket Data":{"main":[[{"node":"Generate Concert Ticket PDF","type":"main","index":0}]]},"Send Ticket to Attendee":{"main":[[{"node":"Log Ticket Sale","type":"main","index":0}]]},"Build Confirmation Email":{"main":[[{"node":"Send Ticket to Attendee","type":"main","index":0}]]},"Generate Concert Ticket PDF":{"main":[[{"node":"Build Confirmation Email","type":"main","index":0}]]}}}How to Import This Workflow
- 1Copy the workflow JSON above using the Copy Workflow JSON button.
- 2Open your n8n instance and go to Workflows.
- 3Click Import from JSON and paste the copied workflow.
Don't have an n8n instance? Start your free trial at n8nautomation.cloud
Related Templates
Auto-create TikTok videos with VEED.io AI avatars, ElevenLabs & GPT-4
Automate the creation and distribution of trending TikTok videos using AI avatars. This workflow connects Telegram, Perplexity, OpenAI, ElevenLabs, VEED.io, and BLOTATO to generate scripts, synthesize voice, create video, and publish across multiple social platforms. Content creators and marketers can rapidly produce engaging short-form video content without manual editing.
Summarize Google Sheets form feedback via OpenAI's GPT-4
Efficiently summarize Google Sheets form feedback using OpenAI's GPT-4. This productivity workflow connects Google Sheets to retrieve form submissions, aggregates the responses into arrays, and then leverages OpenAI's advanced GPT-4 model to generate concise summaries. The generated summaries, initially in Markdown, are then converted to HTML for easy readability before being sent directly to your inbox via Gmail. This automation is ideal for product managers, marketing teams, or customer support departments who regularly collect feedback through Google Forms and need a quick, intelligent overview of responses without manually sifting through every entry. It dramatically reduces the time and effort spent analyzing feedback, allowing for faster insights and more informed decision-making.
Use skills In n8n agent node
This template gives you a framework to use skills in any n8n agent. You can use this as a starting point and add any other tools or patterns needed for your use case. What are βskillsβ? Skills are a context management standard created by Anthropic for use in Claude code. Basically, instead of having a HUGE system prompt, skills split that into lots of small, structured instruction files that tell an agent how to do a specific kind of task. Instead of stuffing a massive prompt full of rules, the agent: finds the relevant skill file reads it and follows the steps inside Itβs a simple pattern that makes managing system prompts for general purpose agents much more straightforward. See an example of a skills repo here. What this workflow does Responds to messages in n8n Chat (or Chat Hub) Builds an βavailable skillsβ index from one or more GitHub repos Lets the agent browse folders + fetch skill files (Markdown) as needed Uses the skill content to guide how it completes tasks How it (roughly) works A chat message comes in. The workflow lists directories in the configured skills repos (root + if present), filters out noise, and merges everything into one directory map. That directory map gets injected into the agentβs system prompt so it knows what skill files exist. When it needs instructions, it uses tools: List Files by Path Name to explore folders * Get a File From GitHub to pull the skill file as raw text (no base64) Same βskillsβ pattern as the CLI tools The flow is: find a skill β open it β follow the steps, the same way it works in the CLI tools, but running inside n8n, so you donβt need to download or install anything locally. How to set it up (Required) Add your GitHub credentials to each node that needs it (Required) Add your OpenRouter credentials to the chat node or replace with the provider of your choosing (Optional) Add more repos to (any skills GitHub repo works as long as your credentials have access to it, such as any public repo) (Optional) Add more tools and turn it into whatever agent you actually need