Guide · Google Sheets
Google Sheets: your conversions, no code
The spreadsheet is still where you really understand your numbers: you sort, filter, color-code. What makes no sense is filling it in by hand on Monday morning.
What the sheet does for you
0
Zero rows to copy: the sheet fills itself while you sleep
Every lead and every sale arrive as soon as they are recorded, with the label of the link that brought them in. What you used to do on Monday morning becomes one more column.
8
columns to set up
2
tries per send
5 s
before giving up
Two routes, and the difference matters
No code, or no go-between: you have to choose
The steps below describe the first route, because that's the one the title promises. The second is covered right after, with its catch — and there is one, a real one.
In both cases, what leaves Subtraq is the same: a signed JSON payload, and a field that can be empty when the conversion could not be attributed.
What each route costs
No code: Subtraq notifies Make, Zapier, or n8n, which adds the row. One more subscription, one more link in the chain, zero lines written. No go-between: a Google Apps Script web app receives the POST and writes the row. Free, but fifteen lines of JavaScript to paste.
The no-code route, 6 steps
From the header row to the pivot table
Nothing to install on the Google side, nothing to authorize: the go-between holds access to the sheet, and you can revoke it in one click.
Create the sheet and its header row
Eight columns, in the order shown in the table below. The headers are not decorative: a pivot table needs them to offer fields.
In Subtraq, add the outgoing webhook
Settings → Connect other tools → Outgoing webhooks. Choose what is sent — leads, sales, or both — and whether the webhook covers one client workspace or the whole account.
Paste the destination URL
The URL of a Make scenario, a Zap, or an n8n workflow. The URL must be HTTPS and publicly reachable: an http address or a private network address is rejected at save time.
In the go-between, add the "add a row" action
All three tools have a ready-made Google Sheets integration. Map each field from the received JSON to its column: that's the only step that needs attention, and you do it once.
Trigger a test conversion
A submitted linked form is enough. The row appears, and you can see right away if a column is off — much easier to fix now than after three hundred rows.
Set up the pivot table
Insert menu, then Pivot table. Source link in rows, amount in values, Sum operation: you have revenue by placement, and it updates on its own.
Pivot table path recorded in Google Help on 12 September 2026 — create a pivot table. Interfaces change: if what you see no longer matches, the source takes precedence.
The eight columns, in the order they arrive
This table is not a suggestion: these are the fields Subtraq sends, exactly as the code writes them.
| Column | What it contains | What to know |
|---|---|---|
| Date | at | Timestamp in ISO format. Formatting the column as a date makes it sortable. |
| Type | event | lead for a prospect, sale for a sale. Two values, never more. |
| Workspace | space.slug | The client workspace involved. Essential if the sheet serves multiple clients. |
| person.email | Can be empty: a codeless conversion does not always provide an address. | |
| Source link | placement.label | Empty when the conversion is not attributed. This is the column to watch. |
| Link slug | placement.slug | Shorter than the label, and stable: better for a pivot table. |
| Amount | amountMinor | In cents, and zero for a lead. Divide by a hundred for display, not for storage. |
| ID | eventId | Stable. This is what lets you spot a row written twice. |
A row with an empty source link is not an error: it's a conversion Subtraq could not attribute, and it says so rather than inventing an origin. Count them: their share measures the health of your tracking.
The direct route
Fifteen lines of Apps Script, and two traps to know about
Google Apps Script can receive a request and write to the sheet. It's free and depends on no one. Here is what you need to know beforehand, rather than after.
A doPost function, deployed as a web app
From the script editor: Deploy, then New deployment, type Web app. Access must be set to Anyone, otherwise Subtraq cannot reach the URL. The doPost function receives the body, and appendRow writes the row.
First trap: Subtraq does not follow redirects
The send fails if the URL responds with a redirect instead of a reply. Test it: after deploying, trigger a test conversion and read the webhook status in the app — it shows the response code, the message, and the date. If it doesn't go through, the route with a go-between does.
Second trap: five seconds, no more
After that, the send is abandoned, and there are only two tries. A script that writes one row fits comfortably inside that limit; a script that calculates, formats, and sends an email does not. Write the row, return the response, and do the rest later.
And the trap in the other direction: a simple trigger cannot call a URL
If you want a change to the sheet to send a sale to Subtraq, know this: Google's documentation is clear, a simple trigger like onEdit is not allowed to call UrlFetchApp. You need an installable trigger. This is the leading cause of "my script doesn't fire".
Recorded in Google documentation on 12 September 2026 — web apps, simple triggers and UrlFetchApp.
The annoying cases, dealt with straight
A sheet that fills itself will eventually contain surprises. Here they are.
I have the same row twice. Why?
Because there is no queue: two tries per send, and the second fires when the first failed after being processed. The eventId column is there for that: a conditional format highlights duplicates, and a formula excludes them from the pivot table.
Some rows are missing for a period.
This is the accepted downside of having no queue: a destination unavailable for several minutes loses the sends from that period. The conversions themselves remain recorded in Subtraq — nothing is lost on the revenue side. The webhook status in the app retains the date and message of the last failure.
How do I get revenue by channel, not just by link?
Name your links with a convention and use it: a pivot table can group by the start of a label if you extract the prefix into an intermediate column. That is why the slug column is better than the label — it does not change when you rename.
How long does the sheet hold up?
A long time, but not forever: a spreadsheet gets slow long before it's full. If the sheet serves as a client report, Subtraq's report export does the same job without maintenance. If it serves as a log, open a new one each year.
Frequently asked questions
Does Subtraq need access to my Google account?
No, never. Subtraq sends a request to a URL you give it. On the no-code route, the go-between holds access to the sheet; on the other, it's your own script.
Does the amount arrive in euros or cents?
In cents, as everywhere in Subtraq: $4,300 is written 430000. The currency arrives alongside, in three letters. Divide in a display column, never in the storage column.
Why do some rows have no email?
Because a codeless conversion does not always provide an address: when a third-party form redirects to a Subtraq link, we know the click, not the person. The row is real, it is just anonymous.
Are sends signed?
Yes. Each send carries a signature header containing a timestamp and a digest computed with a secret shown only once. Verifying it is optional, but without it anyone who knows the URL can write to your sheet.
Can you send only sales?
Yes, and the webhook can also be limited to a single client workspace instead of the whole account.
If a client report is what you need
A spreadsheet is built to understand, not to present. The Subtraq report carries your name, fits on a screen, and is shared by a link.
Client reportThe sheet can start filling on the next conversion
Create the account, add the outgoing webhook, map the eight columns. Monday morning is freed up.
Create a free account