Landings and Offers: The Money End of a Click Flow
Offers and Landings are the two libraries the money end of a click flow is assembled from: the offer holds the URL a click ultimately leaves for, the landing holds the page that sits in front of it. Neither library routes anything on its own. Until a landing is placed as a node on the click flow canvas, the flow is published again, and a campaign is attached, the row you created is just a row in a table and will never see traffic. That is where most people trip, which is why the order of operations gets its own section below.
Offers: the money destination
- Open Offers and click New offer.
- Name is the label used in pickers and reports.
- URL is the money destination, where the offer sends the click. Only
http(s)://andtg://are accepted. - Payout is the amount a conversion inherits when the event arrives without a
payoutof its own: the platform looks the offer up by theoffer_idstamped on the click and takes the payout from there. An explicitpayouton the event always wins. - Target geo is a hint for the picker, not a routing rule. Geo routing is the Condition node's job.
On the canvas the Offer node is terminal, the click ends there. The offer's URL is snapshotted at publish time, so editing the offer in the library does not change an already published program until you publish the flow again. Archiving works the same way: the offer disappears from the pickers immediately, but published flows keep routing to it until the next publish.
Macros in the offer URL
Exactly these tokens are substituted in an offer URL, and no others:
{click_id}, {campaign_id}, {offer_id}, {sub1}, {sub2}, {sub3}, {sub4}, {sub5}, {fbclid}, {gclid}, {gbraid}, {wbraid}, {ttclid}
Values are URL-encoded as they go in. A token with no value becomes an empty string, so &gclid={gclid} won't break the link on Meta traffic. A token outside this list is left in the URL as literal text, deliberately, so the next tracker's macros in the chain survive. Note that {sub6}-{sub9} are captured on the click and can be routed on in a Condition, but they are not macros.
After substitution the resulting URL is validated once more: only http, https and tg are allowed. If that check fails (a macro expanded into something that breaks the address), the click falls back to the campaign's existing redirect rather than going nowhere.
Landings: Hosted vs External
Open Landings and click New landing. The Type field splits two completely different scenarios:
- External means you supply the URL of a page you host yourself. The click 302s straight there. Only
{click_id}and{campaign_id}are substituted on that path; the rest of the macros above do not work here, so anything else you need on your own page has to ride on those two or on parameters you append yourself. - Hosted means you supply a Slug and, optionally, a Default offer. The click 302s to an internal
/l/{id}page whose address already carries the click id and the effective offer id.
The Landing node on the canvas is terminal too, with one exception: it may carry exactly one outgoing edge, and only into an Offer node. A landing's settings (type, URL, default offer) are snapshotted at publish, exactly like an offer's.
What Hosted actually shows
It is not a landing page builder. There is no editor, no HTML upload, no images and no blocks, and none of that appears further into the setup.
The /l/{id} page is three strings and one button on a gradient background, in full: the heading "You're almost there", the subheading "Tap the button below to continue." and a Continue button pointing at the offer URL. Those three strings come from the platform's own localization, are identical for every organization and are not editable. Only the language changes. The page is excluded from indexing.
If you want your own page content, choose External and supply your own URL. Hosted means we serve our interstitial, not that we will host your markup.
When the interstitial can't be served (the landing is archived, the offer was deleted, archived or belongs to another organization, the final address failed validation), the visitor gets a "This page isn't available" stub with a support link. This route never returns a 404: the click has already been paid for, and losing it on an empty page is worse than showing a stub.
Why the interstitial exists at all
Three things a plain redirect does not give you:
- A referrer break. The button leaves with
rel="noopener noreferrer sponsored", so the receiving side does not see which placement the visitor came from. - A deliberate click. A human makes the jump by pressing a button, not a server by issuing a redirect. For some offers and some review processes those are materially different events.
- Macro expansion on the spot.
sub1-sub5and the platform-native click ids are read off the click row,click_idandoffer_idarrive in the page's own address. The button's final href is validated by the same rule (http,https,tg), so the page can never turn into an open redirect no matter what the macros expand to.
If the click row hasn't been committed yet (it is written asynchronously so the redirect stays fast), the button still renders, just with empty sub macros. Attribution is unaffected: offer_id is stamped on the click earlier, on the redirect itself.
The offer for a hosted landing: canvas beats default
A hosted landing must have an effective offer, otherwise the button has nowhere to point. There are two sources, with a hard precedence between them:
- The canvas override, an Offer node wired to the Landing node. It is read straight off the graph at publish and always wins.
- The library default, the Default offer field on the landing itself. It applies when there is no edge on the canvas.
With neither, the flow simply does not publish and the node shows the error: "A hosted Landing needs an Offer — connect one or set a default offer". Dragging an edge from a landing into anything other than an offer is refused on the canvas with "A Landing can only connect to an Offer", and if such an edge ends up in the graph anyway, publish fails with the same verdict. A landing can never have more than one outgoing edge: a second edge from the same point is refused.
The slug is only an operator label
A hosted landing has a slug, and it is easy to mistake it for the page's address. It is not: /l/ resolves a landing by its immutable id, never by slug. That property is a safety boundary rather than cosmetics, because slug-keyed resolution would let one organization hijack another's interstitial by guessing a slug. The slug is still globally unique and is never released on archive, so unarchiving holds no surprises.
The offer whose id arrives in the page address is likewise resolved within the landing's own organization, so pasting somebody else's offer id in to leak their URL doesn't work.
Order of operations
In exactly this order, because every step leans on the previous one:
- Create the offer on Offers. Without it a hosted landing won't publish.
- Create the landing on Landings: Hosted with a slug and a default offer, or External with your own URL.
- Open the campaign's click flow: the Click flow item in the campaign's row menu on Campaigns. A flow created from there is attached to the campaign right away, and that attachment is the only one there is. There is no Click flow field in the campaign dialog.
- Put the Landing node on the canvas and wire it. The node has to be reachable from the Traffic source: a node sitting off to the side gets zero clicks, and publish will say so. Wire an edge from the landing into an Offer node if you want to override the default offer.
- Save, then press Publish. Until you publish, the canvas changes nothing: live traffic is routed by the compiled program from the previous publish, not by what is on your screen.
- Make sure the campaign exists and is active. The tracking link lives on the campaign, not on the flow: a flow with no campaign never receives a single click, however active it looks.
After that, editing runs in a loop: a published flow is read-only ("This flow is live and read-only. Deactivate it to edit."), so the edit cycle is Deactivate, fix the canvas, Publish again. While the flow is deactivated the campaign routes to its previous redirect URL.
Common mistakes
- The landing exists but isn't on the canvas. A library is a library. A row on Landings takes no part in routing until a Landing node in the graph references it.
- Reading Hosted as "they will host my page". It is a fixed interstitial of three strings and a button. Your own content means External.
- The flow is live but there is no campaign. There is nothing to click: the tracking link is issued by the campaign, and a flow with no campaign attached is unreachable.
- Canvas edited, publish forgotten. Graph autosave and publishing are different things; traffic only ever sees the published version.
- Archiving an offer or landing and expecting traffic to stop. They vanish from the pickers immediately, but published flows keep routing to them until the next publish.
- Expecting macros on an external landing. Only
{click_id}and{campaign_id}are substituted there. The full set works in the offer URL and in the hosted interstitial's button. - Editing an offer's URL and seeing no change. The URL is baked into the program at publish, so publish the flow again.