# Turn every Tally form response into a PDF

Tally form to PDF, automatically. Turn each submission into a branded PDF quote, receipt, certificate or summary with a webhook, n8n, Make or Zapier.

**Quick answer.** In Tally, open **Integrations → Webhooks** and point it at n8n, Make or your own endpoint. Build HTML from `data.fields`, send it to `POST https://html-pdf.com/v1/pdf`, and email or store the PDF.

## What you'll build

Tally is free for unlimited forms, which makes it a favorite for client intake, quote requests, event sign-ups and course feedback. What it doesn't do is hand anyone a designed PDF afterwards.

This setup adds that step. Each submission becomes a document with your name and layout, sent to the respondent, your team or a Drive folder.

## What you need

- **A Tally form.** Webhooks work on the free plan.
- **n8n, Make or Zapier**, or a small server endpoint.
- **A design.** Start from the [quote template](https://html-pdf.com/templates/quote), [receipt template](https://html-pdf.com/templates/receipt) or [certificate template](https://html-pdf.com/templates/certificate).
- **An API key** from [html-pdf.com](https://html-pdf.com/login). You get 100 free pages once, without a card.

## What Tally sends

This is the shape of the webhook body, trimmed. Every answer is in `data.fields`, with the question as `label`.

```json
{
  "eventType": "FORM_RESPONSE",
  "data": {
    "formName": "Quote request",
    "fields": [
      { "key": "question_1", "label": "Company", "type": "INPUT_TEXT", "value": "Acme Ltd" },
      { "key": "question_2", "label": "Email", "type": "INPUT_EMAIL", "value": "jo@acme.example" },
      { "key": "question_3", "label": "Budget", "type": "MULTIPLE_CHOICE", "value": ["opt_2"],
        "options": [{ "id": "opt_1", "text": "Under 5k" }, { "id": "opt_2", "text": "5k to 10k" }] }
    ]
  }
}
```

Choice questions send option ids, so look the text up in `options`.

## Step by step with n8n

Want it ready-made? [Download tally-form-to-pdf.json](https://html-pdf.com/static/n8n/tally-form-to-pdf.json) and import it into n8n. The steps below explain what it does.

1. Add a **Webhook** node, method `POST`. Copy the production URL into Tally under **Integrations → Webhooks**.
2. Add a **Code** node that turns the fields into HTML.

```js
const { formName, fields } = $json.body.data;
const esc = s => String(s ?? "").replace(/[&<>"]/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);
const text = f => Array.isArray(f.value)
  ? f.value.map(id => (f.options || []).find(o => o.id === id)?.text ?? id).join(", ")
  : f.value;

const rows = fields.map(f => `<tr><th>${esc(f.label)}</th><td>${esc(text(f))}</td></tr>`).join("");
const html = `<!doctype html><html><head><meta charset="utf-8"><style>
  body { font-family: system-ui, sans-serif; color: #111; }
  th { text-align: left; color: #666; width: 35%; padding: 8px 0; vertical-align: top; }
  td { padding: 8px 0; } tr { border-bottom: 1px solid #eee; break-inside: avoid; }
  table { width: 100%; border-collapse: collapse; }
</style></head><body><h1>${esc(formName)}</h1><table>${rows}</table></body></html>`;

return [{ json: { html, email: fields.find(f => f.type === "INPUT_EMAIL")?.value } }];
```

3. Add an **HTTP Request** node: `POST https://html-pdf.com/v1/pdf`, header `Authorization: Bearer hp_live_...`, JSON body `{"html": "{{ $json.html }}", "format": "A4", "margin": "18mm"}`, and Response Format **File**.
4. Add **Gmail** or **Send Email**, attach the `data` binary, and send it to `{{ $('Code').item.json.email }}`.

Full node settings are in the [n8n guide](https://html-pdf.com/guides/n8n).

## With Make or Zapier

Both have a Tally app with a new response trigger, so you don't need the webhook setup.

1. **Trigger.** Tally, new response, pick your form.
2. **Make the PDF.** Make's **HTTP → Make a request** or **Webhooks by Zapier → Custom Request**: `POST https://html-pdf.com/v1/pdf` with the JSON below, mapping each answer into the HTML.
3. **Deliver.** Map the returned `url` into a Gmail attachment or a Google Drive upload.

```json
{
  "html": "<h1>Quote request</h1><p><b>Company:</b> Acme Ltd</p><p><b>Budget:</b> 5k to 10k</p>",
  "format": "A4",
  "filename": "quote-request.pdf",
  "response": "url"
}
```

The link in `url` works for 24 hours. Step-by-step: [Make guide](https://html-pdf.com/guides/make) · [Zapier guide](https://html-pdf.com/guides/zapier).

## Code path for developers

This Express endpoint checks the signature, renders the PDF, then replies. In production, reply to Tally right away and render in a background job.

```js
import crypto from "node:crypto";
import express from "express";

const app = express();
app.post("/tally", express.raw({ type: "application/json" }), async (req, res) => {
  const sig = crypto.createHmac("sha256", process.env.TALLY_SECRET).update(req.body).digest("base64");
  if (sig !== req.get("tally-signature")) return res.sendStatus(401);

  const { data } = JSON.parse(req.body);
  const html = renderQuote(data.fields); // your template, with escaped values
  const r = await fetch("https://html-pdf.com/v1/pdf", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.HTML_PDF_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({ html, response: "url" }),
  });
  const { url } = await r.json();
  // Email the link or download and store the file.
  res.sendStatus(200);
});
```

Set a signing secret in the Tally webhook settings so you can check the `Tally-Signature` header.

## Ask your AI agent

With the [html-pdf.com MCP server](https://html-pdf.com/pdf-mcp-server) connected to [Claude](https://html-pdf.com/guides/claude) or [ChatGPT](https://html-pdf.com/guides/chatgpt), paste one sample submission and ask for a design.

> Here is a Tally quote request. Use html-pdf to make a one page A4 quote for "Brightside Studio" with the client's details at the top, three line items based on their budget, and a 30 day validity date.

When you like it, ask for the HTML and drop it into the Code node.

## FAQ

### Can Tally create a PDF of each response on its own?

Tally shows and exports responses, but it doesn't create a designed PDF per submission. A webhook plus an HTML to PDF API adds that.

### Do Tally webhooks work on the free plan?

Yes. Webhooks are available on Tally's free plan, so the whole setup can run on n8n's self-hosted edition and the 100 free html-pdf.com pages.

### How do I show the text of a multiple choice answer?

Choice fields send option ids in `value`. Match each id against the `options` array of the same field to get the text.

### Is the response data stored by html-pdf.com?

No. HTML is not stored, and download links expire after 24 hours.
