Routy

Incoming Postbacks

One URL per account that your advertiser or network fires on every conversion, with auto-correction for the four ways a tracker commonly puts the click id in the wrong parameter, and an issue naming the sender so you can get it fixed.

What this feature does

Conversions reach Routy as server-to-server postbacks. You hand your advertiser or network a URL, their tracker calls it when a conversion happens, and Routy matches it to the click that produced it.

The URL looks like this:

https://your.routy.domain/postbacks/v2/{your-api-key}?clickId={the-guid}&dyn={your-dynamic}

clickId is the UUID Routy handed back on the click redirect. dyn is your own tracking string, in one of two formats: a short form of one to six letters followed by four to ten digits, or an 18 to 21 character nanoid. Either one on its own is enough to match a click.

Senders get this wrong constantly. They put the GUID in the dyn slot, or the dynamic value in the clickId slot, or they swap the two, or they send junk in one of them. Routy classifies what arrived, recovers the conversion when the two values can only have been meant one way, and raises an issue either way so the tracker config gets fixed at the source instead of being patched around every month.

What you'll get out of it

  • A postback URL per account, built for you with the click-id placeholder already set to the macro name that account's affiliate program software uses, and a parameter for each conversion type you tick.
  • Four recoverable anomalies corrected in place. A swapped pair is unswapped, a GUID sitting in the dyn slot is used as the click id, a dynamic value sitting in the clickId slot is used as the dynamic, and a valid click id with junk alongside it is processed on the click id alone.
  • Two rejections you're told about. When neither parameter is in a recognisable format, or when both are missing, the conversion is lost and the issue is raised as a warning rather than an informational note.
  • An issue per anomaly type with the evidence in it: the api key the postback hit, the anomaly, the click id Routy ended up using, the reason, and exampleRequestUrl, which is the sender's own request exactly as it arrived. Where the click resolved, you also get accountId, brandLinkId and clickAt, so you can line it up against your own logs.
  • One push notification per issue rather than one per bad postback. Later postbacks of the same type roll into the same issue and update its last-seen time.
  • Issues that close themselves once the sender stops: after three days of silence for the four recoverable types, 24 hours for the two rejections. You can also resolve one by hand.
  • A list of every postback received, searchable by click id or dynamic value and filterable by account, traffic source, brand and date range. A filter narrows it to the ones that failed, and any row can be re-queued from there.

How it actually works

Generating the URL

Open the postbacks section for the account and pick the conversion types the sender will report. Routy fills in the click-id parameter name from what the account's program software declares, and writes one parameter per conversion type, named what that platform expects and wrapped in the placeholder syntax it uses.

The syntax comes from the affiliate program software, or from the program itself, not from you. HasOffers takes {sale_amount}, CAKE takes #sale_amount#, and a program can override its software's template. A conversion type with no variable name configured at either level falls back to amount when it carries money and 1 when it doesn't.

One conversion type never appears here. Click conversions are tracked separately, so they're left out of the generator and silently ignored if a sender reports one, with the rest of that postback processed as normal.

What the api key is scoped to

The key in the URL path identifies an incoming-postback setting belonging to your affiliate. A setting can be scoped to one account, or to one traffic source, or left unscoped as the affiliate's main key, and you can hold at most one of each: one key per account, one per traffic source, one main. So the sender you give an account's key to is the sender whose conversions arrive under that account.

Four older URL paths still answer, for senders configured before the current one: /postbacks/{apiKey}, /pixel/{apiKey}, /post-back/{apiKey} and /incoming/event/post-back/{apiKey}. Use /postbacks/v2/{apiKey} for anything new.

Parameters beyond the identifiers

bi names a brand. date with an optional date-format sets the conversion's timestamp, defaulting to yyyy-MM-dd hh:mm:ss and to the time of arrival when you send nothing. debug marks the postback as a test. A date that doesn't parse is refused with the expected format in the message, rather than being recorded at the wrong time.

Correction, then the issue, in that order

Routy classifies clickId and dyn by format before anything else, and that resolution decides whether the conversion is processed. Raising the issue is diagnostics and is kept out of the decision: it runs inside its own error handling, so a failure to report an anomaly never changes how the postback itself was handled.

The reporting also doesn't sit on the critical path. The endpoint runs on a read-only tier that publishes an event and returns; the click lookup and the issue write happen downstream, so neither adds latency to a postback. A flood guard limits publishing to one event per minute per key and anomaly type, which bounds what one badly configured sender can put on the queue. Grouping the issues themselves is separate from that window.

What the sender sees

The status codes are chosen around whether a retry could help. Neither identifier supplied, or an unparseable date, returns 400. An unknown api key or a failed validation returns 404. An inactive account returns 401. None of those are worth retrying and the codes say so.

An unhandled exception returns 500 on purpose. That case means Routy dropped a conversion through its own fault, and answering 200 would tell the sender it was received and guarantee the conversion was gone for good. A 5xx lets them try again, and the retry may well work.

Quota

Postbacks are metered against your plan's pixels quota. At 100 percent, a postback is refused with a quota message unless your account carries the never-block option. A refused postback isn't recorded anywhere, so this is one of the limits worth watching rather than discovering.

Why this is worth doing

A malformed postback that gets rejected without comment is the worst failure mode in conversion tracking. The conversion never existed as far as your reports are concerned, the sender's tracker thinks it fired, and the gap shows up weeks later as a shortfall you then have to argue about with the advertiser. There's nothing to re-send, because the postback came and went.

Auto-correction handles the cases where the intent is unambiguous. A UUID is a UUID wherever it was put, so a GUID sitting in the dyn slot is recoverable without guessing, and the conversion is recorded today instead of being lost.

The issue is the part that stops the problem recurring. It carries the sender's own request, which is usually all it takes to show someone that their macro is in the wrong slot, and it closes itself three days after they fix it. Fix it even while the correction is working: the recovery depends on Routy being able to tell which value is the GUID, so a sender that also starts producing malformed GUIDs stops being recoverable. The heuristics are a safety net rather than a contract.

The two unrecoverable types are worth treating differently. Neither parameter recognisable, or both missing, means Routy has no way to know which click a conversion belonged to. Those are raised as warnings and they auto-resolve in 24 hours rather than three days, because every one of them is a conversion already gone.

Frequently asked questions

Is the endpoint GET or POST?

GET. The postback endpoint takes its values on the query string, and the current URL is /postbacks/v2/{apiKey}. Four older paths are still served for senders configured against them.

Do I need to send both `clickId` and `dyn`?

No. Either one identifies the click. Send the GUID in clickId where you can, since that's the direct match, and put your own tracking string in dyn.

What exactly does auto-correction fix?

Four cases: the two parameters swapped, the click id sent in the dyn slot, the dynamic value sent in the clickId slot, and an unreadable dynamic value alongside a valid click id. If neither value is in a usable format, or both are missing, nothing can be recovered.

Does Routy retry a postback that failed?

Retrying is the sender's side of this. Routy answers 4xx on the cases a retry won't fix, and 500 on the cases where it might, which is what the sender's tracker should act on.

Can I have a different postback URL per campaign?

Not per campaign. A key can be scoped to an account or to a traffic source, plus one main key for the affiliate, and that's the full set of scopes.

What happens to a postback that doesn't match any click?

It's recorded and it shows up in your incoming postbacks list, where the failed filter narrows the view to exactly those. Search the click id or the dynamic value to see what arrived, then re-queue the row if the click turns up later.

Will a conversion type we don't use break the postback?

No. Click conversions are the one type that can't be reported this way, and a postback naming one has that part ignored and the rest processed.

Ready to try Incoming Postbacks?

Open the postbacks section for the account the sender reports on, pick the conversion types, and give them the URL Routy generates. Check the incoming postbacks list after the first few conversions arrive, and watch your issues for anything prefixed postback_.