Skip to main content

Zapier

The Formfeed app for Zapier has six actions and one trigger. It is listed in Zapier's app directory: search for Formfeed when you add a step to a Zap. In the Formfeed app, Integrations shows the Formfeed Zap templates and your Zaps without leaving the app, once you choose Show Zapier; that loads Zapier's own page into the app and hands Zapier your name and email address, so it can create a Zapier account for you in one step.

Zap templates for Google Forms, Typeform, Google Sheets, Google Drive, Stripe and Slack are published in the directory as well. Starting from one puts the trigger and the Formfeed step in place; you connect the two accounts and pick your own template, and the Zap is done.

Connect​

Add a Formfeed connection and paste an API key from the app (API keys). The default scopes of a new key (render:create, render:read, template:read, account:read) cover the connection test, the template list and every render action; tick file:write and webhook:manage as well when you use Upload File or the trigger. What each step needs:

ScopeNeeded for
account:readthe connection test, which reads GET /account (a default scope)
template:readthe template list and the fields of a template (a default scope)
render:createthe three Create Document actions, Create E-Invoice and Convert Document to PDF (a default scope)
file:writeUpload File
webhook:managethe Render Completed trigger, which registers a webhook

A ff_test_ key renders for free (with a watermark on the Free plan), which is what you want while building a Zap; switch the connection to a ff_live_ key before the Zap goes on. The connection shows as organisation / workspace, so several workspaces stay apart. Leave Region on Europe (every workspace is in the EU today) and Custom API URL empty.

Actions​

ActionWhat it does
Create DocumentRenders a published template. Picking the template loads its fields, so you map invoice.number instead of writing JSON, and a Version choice when the template has release channels. Word and PowerPoint templates render DOCX, PPTX or PDF.
Create Document From HTMLRenders HTML built earlier in the Zap, with the template language of your choice.
Create Document From URLRenders a public page to PDF or an image.
Upload FileAdds an image or PDF from an earlier step to the file library, where templates use it with asset(). The same name replaces the file.
Convert Document to PDFTurns a Word, Excel, PowerPoint, OpenDocument or RTF file from an earlier step (up to 20 MB, not kept), or the render of a Word or PowerPoint template by its ID, into a PDF. Starter plan and above.
Create E-InvoiceRenders a ZUGFeRD / Factur-X e-invoice from fields for the invoice itself, validated before it is delivered. See below. Starter plan and above.

The fields of each action:

ActionFields
Create DocumentTemplate (required), then the template's own fields and Version; Output (empty: the template's format, PDF for a PDF template, its image format for an image template, its default for a Word or PowerPoint template), File name, Locale (for example de-DE, overrides the template's), Data (JSON)
Create Document From HTMLHTML (required), Template language (Jinja2, the default, Liquid or Handlebars), Output (PDF, the default, PNG, JPG or WebP), File name, Data (JSON), Settings (JSON) (paper, margins, header and footer, as in Override settings per request)
Create Document From URLURL (required, a public page), Output (PDF, the default, PNG, JPG or WebP), File name, Settings (JSON)
Upload FileFile (required: PNG, JPEG, WebP, GIF, SVG, AVIF or PDF, up to 10 MB), Name in library (the name templates use with asset(), for example brand/logo.png; the file's own name when empty)
Convert Document to PDFFile (DOCX, XLSX, PPTX, ODT, ODS, ODP, DOC, XLS, PPT or RTF) or Render ID (rnd_… of a render with output DOCX or PPTX), exactly one of the two; Page ranges (for example 1-3,5, all when empty), Landscape and One page per sheet (for spreadsheets and documents without their own page setup), File name (the file's own name with .pdf when empty)

The Template list shows the workspace's templates by name and kind, up to 100 of them, unpublished ones included; only published templates render, and an unpublished one fails with template_not_found. Its fields come from the template's data schema, or, when it has none, from its sample data. Nested objects become dotted names (invoice.number); lists are left out of the fields and go into Data (JSON).

Every Create Document action returns the render: id, status, download_url, page_count and units. Map Download Url into the next step: file fields in Zapier (Gmail's Attachments, Google Drive's File) accept a URL and fetch the document. Copy the file rather than storing the link: a download link is valid for at most seven days, and the file itself only for the workspace's retention period (one day on the Free plan, at most 24 hours for a test key). A render that takes longer than a minute continues in the background, and the action then returns it with status: queued and no download URL; the trigger receives it when it finishes.

Lists (invoice line items, table rows) go into the Data (JSON) field, which is merged over the mapped fields value by value: an object in the JSON adds to the mapped fields at the same place, a value replaces the mapped one, and a list replaces the whole list. A Looping by Zapier step or a Code step usually builds that array.

E-invoices​

Create E-Invoice makes a ZUGFeRD / Factur-X e-invoice: a PDF/A-3 that carries the invoice as XML, checked by the validator before the Zap receives it. Instead of a template's fields, the action asks for the invoice itself, in groups: the invoice (number, issue date, currency, document type, references), seller and buyer, the lines and the VAT breakdown, the five totals and the payment. Lines and the VAT breakdown are line items, so a trigger that brings line items (an invoice of your shop or accounting app) maps them line by line. The action sends everything as the _invoice block, and the template prints the same block, so every value is mapped once. The E-invoice example of the gallery in the app is such a template.

Nothing is computed: the totals and the VAT breakdown are the ones your system states, and an invoice whose totals do not add up to the cent is refused. The Zap's error then names every field with the rule it breaks, such as _invoice.totals.due: … (BR-CO-16). What the fields do not offer (the invoice a credit note refers to, allowances and charges, the delivery, a direct debit mandate, the notes French invoices need) goes into Invoice (JSON) with the names of the field reference, merged over the fields. The options choose the profile (EN 16931 or Basic), the name of the specification (Factur-X or ZUGFeRD; the file is the same), whether the XML is also stored as a file of its own, and whether a value the PDF does not show fails the render instead of being reported.

The action returns the render with the validator's report as einvoice; E-invoice valid, Rules checked, PDF/A level, XML URL and the two SHA-256 fields can be mapped into the next step. Live e-invoices need the Starter plan or higher; a test key makes a limited number a day, each with the test mark (see Plans and units).

Trigger​

Render Completed subscribes to the workspace's webhooks. Choose the events you care about: render.completed (the default), render.failed, job.completed, job.failed, quota.warning, quota.exceeded. Zapier registers the endpoint when the Zap is turned on and removes it when the Zap is turned off, so nothing is left behind; while it exists, it is listed in the app under Webhooks as Zapier.

The trigger fires for every render of the workspace, of live and test keys alike, not only for renders started by a Zap: batches from the app, API calls from your backend and renders that outlasted the synchronous limit (the action then returns them with status: queued) all arrive here. Its fields are Render ID, Event Type, Status, Output Format, Download URL, Page Count, Template, Error Code, Error Title, Error Detail and, for a batch, Batch ZIP URL.

A Zap needs at least one real action after the trigger; Formatter, Filter and Delay steps alone do not count. Do not add a Formfeed Create Document action to a Zap that triggers on render.completed: every render would start the Zap again.

Example Zaps​

Zapier's free plan runs Zaps of two steps; an example with a third step needs a paid Zapier plan. Build the template in the Formfeed app first and publish it: Create Document lists unpublished templates too, but renders only published ones.

Most of these exist as a published Zap template: open it from the app directory or from Integrations in the Formfeed app, and the steps are already in place. The fields are written out here anyway, because a template cannot know what your own template expects.

Send a certificate for every form response​

A participant submits a form and receives their certificate by email.

  1. Trigger: Google Forms → New Form Response (Typeform → New Entry works the same way).

  2. Action: Formfeed → Create Document

    FieldValue
    Templateyour certificate template, for example Certificate (pdf)
    nameFull name from step 1
    courseCourse from step 1
    dateTimestamp from step 1
    File namecertificate- followed by Full name from step 1
  3. Action: Gmail → Send Email: To is the Email answer from step 1, Attachments is Download Url from step 2.

The template reads the fields as {{ name }}, {{ course }} and {{ date | date('dd.MM.yyyy') }}. Google Forms sends the timestamp as text such as 9/16/2026 10:15:00; put a Formatter by Zapier → Date / Time → Format step before the Formfeed step, with the output format YYYY-MM-DD, and map its output to date.

Turn a spreadsheet row into an invoice in Google Drive​

Every new row in the sheet becomes a PDF in a Drive folder.

  1. Trigger: Google Sheets → New Spreadsheet Row, with columns number, customer, street, city, amount.

  2. Action: Formfeed → Create Document, template Invoice, and map the columns onto the template's fields (invoice.number, customer.name, …). The line items go into Data (JSON) in the shape your template loops over, for example:

    {
    "items": [
    { "description": "Consulting", "quantity": 1, "unit_price": 450 }
    ]
    }
  3. Action: Google Drive → Upload File: File is Download Url from step 2, File Name is Invoice followed by number from step 1.

Render HTML without a stored template​

When an earlier step already produces the text, render it directly.

  1. Trigger: any app, for example Schedule by Zapier → Every Week.

  2. Action: Formfeed → Create Document From HTML

    FieldValue
    HTML<h1>Weekly report for {{ team }}</h1><p>{{ summary }}</p>
    Template languageJinja2
    OutputPDF
    Data (JSON){"team": "Fennlor Studio", "summary": "All systems normal."}
    Settings (JSON){"paper": {"format": "A4"}, "margin": {"top": "20mm", "bottom": "20mm"}}

    Map values from earlier steps into the JSON instead of the fixed text.

  3. Action: Email by Zapier → Send Outbound Email with Download Url in the body.

Zapier does not touch {{ }} inside a field, so the template syntax reaches Formfeed unchanged.

Keep the logo in the file library up to date​

  1. Trigger: Google Drive → New File in Folder, the folder your designers use for brand assets.
  2. Action: Formfeed → Upload File: File is the file from step 1, Name in library brand/logo.png.

Every template that shows <img src="{{ asset('brand/logo.png') }}" alt=""> uses the new logo from the next render on.

Get a Slack message when a render fails​

  1. Trigger: Formfeed → Render Completed, Events set to Render failed and Batch failed.
  2. Action: Slack → Send Channel Message, with the text Render failed: followed by Render ID and Error Detail picked from step 1. error is the render's problem, so its Error Title and Error Code fields are there as well.

This covers renders from the app and the API as well, which makes it a cheap alert for a backend integration.