Generate a QBR deck per account from Airtable with n8n
On the first day of each quarter, one Google Slides QBR deck per account, built from your Airtable base, delivered to Google Drive, with the link written back to the account record.
- Source
- Airtable
- Output
- Google Slides
- Delivered to
- Google Drive
n8n workflow
The importable workflow file for this recipe is being tested and will be added here. The steps below show exactly what it does, so you can build it now in a few minutes with the SourceToDocs n8n node.
How the workflow runs
- 01
Schedule Trigger: first day of each quarter
Trigger Interval is Custom (Cron) with the expression 0 8 1 1,4,7,10 *, which fires at 8am on the first day of January, April, July and October. Move the day later if your quarter's numbers land in Airtable after the quarter closes.
- 02
SourceToDocs: Document, Generate
Pick the split Google Slides document that reads your Airtable base. In its Split step, the Accounts table is the driver and the Split by expression {{ name }} gives one deck per account. The driver's own rows are not content, so every data set, Accounts included, is set to Only matching rows with a match key. Rows Come From stays on Connected Data Sources, the default, so the document reads Airtable itself and delivers the decks into a folder for that run inside your Drive folder. A split run produces decks and no PDFs.
- 03
Airtable: Record, Update
Optional. With Wait for Completion on, the default, the SourceToDocs node outputs one item per deck, each with file_url and split_key, the account name that deck was generated for. This node matches the account record on Name and writes file_url into a QBR deck link field.
| Airtable field | Template placeholder |
|---|---|
| Accounts: Name | {{ name }} |
| Accounts: Tier | {{ tier }} |
| Accounts: Executive sponsor | {{ executive_sponsor }} |
| Accounts: Primary CSM | {{ primary_csm }} |
| Accounts: Renewal date | {{ renewal_date }} |
| Outcomes: Outcome (first row) | {{ outcomes[1].outcome }} |
| Outcomes: Target (first row) | {{ outcomes[1].target }} |
| Outcomes: Actual (first row) | {{ outcomes[1].actual }} |
| Outcomes: Delta (first row) | {{ outcomes[1].delta }} |
Or have Claude set it up
The QBR decks skill
works through the SourceToDocs connector at https://app.sourcetodocs.com/api/mcp. Install the skill, connect, then paste:
Use the qbr-decks skill. My accounts are in the Airtable base "Customer Success", table "Accounts", one row per account, with linked "Outcomes" records that carry Quarter, Outcome, Target, Actual and Delta. I will pick the Google Slides QBR template and the Drive folder "QBRs 2026" when you send me the links. Set up one deck per account, with the outcomes slide showing only that account's rows for Q4 2026. Show me the placeholder mapping and the number of decks before you run anything.
To produce a QBR deck per account from n8n, schedule the workflow once a quarter and let the SourceToDocs node start a split document that reads your Airtable base: one Google Slides deck per account, delivered to Google Drive. The node returns one item per deck, so an optional last node writes each link back to the account record. The build is three nodes. Most of the work is the one-time setup of the split document, described first.
What you need
- An Airtable base with an
Accountstable, one row per account, and at least one table of quarterly rows linked to it. This page usesOutcomes, with a linkedAccountfield and the fieldsQuarter,Outcome,Target,ActualandDelta. Account names must be unique, because the name is what separates the decks. The QBR template post lays out the full five-table base and the five sections of the deck. - A
QBR deck linkURL field onAccounts, if you want the links written back. - A QBR template in Google Slides with a cover slide and an outcomes slide carrying the placeholders listed below. The QBR deck template is a fuller design with its own placeholder names: a design reference, not a drop-in file.
- A SourceToDocs workspace and an API token for it. A workspace owner or admin creates the token on the API Tokens page.
- On the Accounts page, an Airtable connection for the data, a Google Slides connection for the template and a Google Drive connection for delivery. Every Google tile is a separate connection.
- n8n, Cloud or self-hosted, with the SourceToDocs node installed. On a self-hosted instance that is Settings, then Community nodes, then Install, with the package name
@twovmodules/n8n-nodes-sourcetodocs; on n8n Cloud, add it from the nodes panel, where it has a verified listing. Add an Airtable credential in n8n if you use the last node.
Set up the document in SourceToDocs
The document reads Airtable itself. n8n only starts it.
- Create a Google Slides document and connect your Airtable base as its data source.
- Add a data set named
Accountson theAccountstable and tick the fields the cover slide prints:Name,Tier,Executive sponsor,Primary CSM,Renewal date. - Add a data set named
Outcomeson theOutcomestable. TickOutcome,Target,ActualandDelta, then tick the linkedAccountfield andNameunder it. The match key in step 6 reads that linked name, and it can only read linked fields the data set picks. - Add a subset on each data set with Add Subset. On the Outcomes subset, add a filter on
Quarterfor the quarter you report on. - On the Split step, set the driver: your Airtable source, the
Accountstable, and the Split by expression{{ name }}. Expressions use the column alias, a snake-case identifier derived from the field name. You get one deck per distinct value, and rows with a blank value are skipped. - In the participation table on the same step, set both data sets to Only matching rows. The match key for
Accountsis{{ name }}and forOutcomesit is{{ account.0.name }}. The driver’s own rows are not content: the Accounts data set on Only matching rows is what puts each account’s own row on its cover slide. - Press Estimate to see the number of decks before anything runs.
- In Template Config, add a
dynamic_slideentry on the Accounts subset for the cover slide and one on the Outcomes subset for the outcomes slide, with a capacity equal to the number of outcome rows the slide has room for. Pick your template in Presentation Access, map each entry to its slide in the Slide Editor and press Save Mappings. A Slides document will not generate until the entries exist and are mapped. - Add a Google Drive distribution and choose the folder.
On the outcomes slide, each row slot is written with an index, starting at 1: {{ outcomes[1].outcome }}, {{ outcomes[1].target }}, {{ outcomes[1].actual }}, {{ outcomes[1].delta }}, then [2], [3] and so on up to the capacity. The Slide Editor lists each slide’s placeholders as Matched, Available or Unresolved, which is the quickest check that the names in your template agree with the data set.
Usage metrics, risks and asks follow the same pattern as Outcomes: a data set on the table with the linked account name ticked, a subset filtered to the quarter, Only matching rows with the match key {{ account.0.name }}, and a dynamic_slide entry mapped to its slide.
Keeping the quarter filter current
The quarter filter is a saved setting, so it does not move on its own. Either change its value before each cycle, or filter on a field your base computes. A formula field is filtered by its result type, so a formula in Airtable that marks the current quarter’s rows gives the subset a value to filter on that you do not have to edit. Check the result with the data set preview before you rely on it.
Build it in n8n
Add the nodes in this order and connect them in a line.
| Node | Operation | Key settings |
|---|---|---|
| Schedule Trigger | Trigger Interval: Custom (Cron) | Expression: 0 8 1 1,4,7,10 *. That is 8am on the first day of January, April, July and October, in the workflow’s timezone. |
| SourceToDocs | Resource: Document. Operation: Generate | Document: your QBR document. Rows Come From: Connected Data Sources, the default. Under Options, raise Max Wait above the default 300 seconds if you have many accounts. Wait for Completion stays on. |
| Airtable | Resource: Record. Operation: Update | Base and Table: your base, Accounts. In Columns, match on Name in place of the record ID. Values: see below. |
The values the Airtable node writes:
| Column | Value |
|---|---|
| Name | {{ $json.split_key }} |
| QBR deck link | {{ $json.file_url }} |
The Schedule Trigger also offers Trigger Interval Months with Months Between Triggers set to 3, plus Trigger at Day of Month and Trigger at Hour. The cron expression is used here because it names the four months outright.
What the node returns
With Wait for Completion on, the SourceToDocs node outputs one item per deck. Each item carries file_url and file_name at the top level and split_key, the account name that deck was generated for. The Airtable node runs once per item, which is why matching on Name with split_key puts every link on the right record. The Airtable node updates the first record that matches, one more reason account names must be unique.
In Drive, the decks sit together in a folder created for that run inside the folder you chose, named after the document and the time the run started, so one quarter’s decks never mix with the next. With the default file name each deck is named after its account.
Or have Claude set it up
The nine setup steps above can be done by Claude instead of by hand. With the SourceToDocs connector added to Claude and the qbr-decks skill installed, paste the prompt from the block at the top of this page. Claude creates the document, attaches your Airtable base through the connected account, reads the placeholders in your template, configures the data sets, the slide entries and their mappings, the split and the Drive destination, shows you the mapping and the deck count, and starts a run when you ask.
Claude asks first whether you need PDFs. One deck per account from a split run delivers Google Slides decks and no PDFs; a PDF with every deck means one run per account, which suits a handful of key accounts.
Two things stay with you. Claude sends links for you to pick the template and the Drive folder in Google’s own picker, and it cannot edit the template file, so a missing placeholder is yours to add in Google Slides. And Claude runs when you ask: the quarterly schedule is the n8n workflow above.
Where this fits
The workflow removes the copying, not the thinking. The CSM still owns the narrative, the risks and the asks on each deck before the meeting. When that prep is the bottleneck, or the numbers come from more than one system, the QBR automation guide covers the wider process. For the split setup itself in more depth, see the Airtable to Google Slides walkthrough.
Related
- QBR automation: the full guide this recipe belongs to.
- Free QBR deck template for Google Slides: the template this workflow fills.
- The SourceToDocs n8n node: every action and setting.
- The SourceToDocs MCP server: what Claude can do through the connector.