Content and discovery
Which post came before the orders
You want to know which post sold something. What a timeline join can tell you is narrower, and more useful for being narrow: which posts went out shortly before an unusual run of orders. That is a shortlist to investigate, not a cause. The platform data contains no path from a viewer to a buyer, so no amount of joining will produce one — and a flow that lets people read the output as attribution is worse than no flow, because it makes a guess look audited.
- Triggers
- Two
- Runs
- Nightly
- Stack
- 5 tools
- Durable execution
- Not required
The flow
The top track records what went out and when. The bottom track reads the day's orders against a baseline. They meet on time, which is the only key these two datasets share.
A post goes live
Instagram Graph API
Label the post
OpenAI · Anthropic
Write one row per post
Sheets · Airtable
Every night
n8n schedule
Pull the day's orders
n8n
Above baseline in the window?
n8n IF
Flag it for a look
Slack · WhatsApp
Leave it unmarked
—
Step by step
- 01
A post goes live
Instagram Graph APIRecord the moment it actually published, read from the platform rather than from the calendar. Scheduled time and published time are not the same timestamp, and the whole exercise is built on timestamps.
- 02
Label the post
OpenAI · AnthropicA model reads the caption and assigns a theme from a fixed list — product, founder, customer story, offer. It is classifying, nothing more. The labels you set now are the only dimensions you can group by later, and a free-form label is not a dimension.
- 03
Write one row per post
Sheets · AirtablePost id, published time, surface, theme, format. Nothing about orders yet — the two sides stay separate until the join, so that anyone can see where the seam is.
- 04
Every night
n8n scheduleRuns after the day closes, so whole days are compared with whole days. A partial day dragged into the comparison is the easiest way to manufacture a result.
- 05
Pull the day's orders
n8nOrder times and totals, plus the baseline for that weekday. A Tuesday belongs against other Tuesdays; comparing it with last Saturday produces a finding about Saturdays.
- 06
Above baseline in the window?
n8n IFPick a window you can defend — say the 48 hours after publishing — and a baseline that accounts for the weekday and for anything else running that day. The question is whether the orders were unusual, not whether the post worked.
- 07
Flag it for a look
Slack · WhatsAppThe message says what went out, when, and how the orders in that window compared with the baseline. It does not say the post caused the orders, because the data cannot support that and the message will be quoted. Argue about this wording before launch, not after somebody puts it in a board pack.
What the platform will not allow
The gap between correlation and cause is not an analytical shortcoming you can engineer around. It is written into what these APIs return.
"Data used to calculate metrics can be delayed up to 48 hours." A nightly join reads numbers that are still moving, so the first pass is provisional and the table has to say which rows have settled.
Instagram Platform — Instagram Media InsightsMedia insights return aggregate counts — views, reach, shares, saves, total_interactions — with no viewer identity. Story metrics below five viewers return error code 10, "Not enough viewers for the media to show insights". There is no path from a viewer to a buyer in this data, which is precisely why the join is on time and nothing else.
Instagram Platform — Instagram Media Insights"You will not engage in Automated Data Collection without first obtaining Meta's express written permission." The missing identity link cannot be recovered by collecting it yourself, so the correlation is the ceiling rather than a first version.
Meta — Automated Data Collection TermsA YouTube project's default allocation is "100 search.list calls, 100 videos.insert calls, and 10,000 units per day combined for all other endpoints". If the join covers video as well, the nightly pull is paced by that, and a historical backfill has to be spread across days.
YouTube Data API — Getting started (quota)
When this is not worth building
Three cases where the upkeep costs more than the missing report.
One channel, one post a week. The timeline is short enough to read directly, and the join only adds arithmetic to something already visible.
Your orders are entered by hand, hours after they happen. Joining a soft timestamp to a hard one produces a confident-looking table resting on the softer of the two, and the table will outlive everyone's memory of that caveat.
Somebody senior will read the flag as attribution regardless of how the column is labelled. If the output will be quoted as "this post made X sales", the honest choice is not to build it — a shortlist that gets read as proof does more damage than the absence it replaced.