Every affiliate network solves the same five problems, and every one of them solves those problems differently. That is the whole difficulty, and it is why a publisher's second integration costs almost as much as the first.
Five problems, no shared answer
Any performance program has to let a publisher find out what is on offer, generate a link that carries attribution, receive notice when something converts, reconcile what is owed, and enforce the rules of the program. Those five needs are universal. The implementations are not.
Discovery
Some providers expose a catalogue endpoint with pagination and filters. Some publish a nightly product feed as CSV or XML dropped on FTP. Some expect you to browse a dashboard and copy IDs by hand. The shape of an “offer” differs too: one provider's record is a merchant, another's is a specific creative, a third's is a product SKU. Writing code against three providers means writing three notions of what you are even iterating over.
Tracking links
The link is where attribution lives, and it is the least standardised part of the stack. The parameter that identifies the downstream publisher might be subId, sub1, u1, aff_sub, sid or something proprietary. Length limits vary. Some providers accept several slots, some one. Some strip characters you did not expect. An identifier scheme that works cleanly on one network silently truncates on another, and you find out weeks later when reconciliation does not balance.
Conversion notification
Postbacks arrive as GET with query parameters, or POST with form encoding, or POST with JSON. Signing might be an HMAC over the body, a shared secret in a header, a token in the URL, or nothing at all. Retry behaviour differs: some retry on any non-200, some never retry, some retry so aggressively that a slow endpoint produces duplicates you must dedupe yourself. Timestamps arrive in provider-local time, in UTC, or as epoch seconds, sometimes without saying which.
Reporting and reconciliation
This is where the cost really accumulates. Conversion states are the same idea everywhere and different words everywhere: pending, locked, validated, approved, confirmed, rejected, declined, reversed, clawed back. Mapping them is not mechanical, because the state machines differ. One provider's “approved” can still reverse for 90 days; another's is final. Currency handling differs — some report in the advertiser's currency, some in yours, some convert at a rate they do not disclose.
Rules
Every program restricts something: geographies, traffic sources, brand-term bidding, coupon and incentive models, creative use. These are rarely machine-readable. They live in PDFs, in dashboard text fields, in emails from account managers. A publisher acting in good faith can breach a rule they were never shown in a format their code could read.
Why the cost does not amortise
Integrations that look similar do not share code. Each new provider brings its own auth, its own pagination quirks, its own postback dialect and its own reconciliation semantics. The abstraction you built for the first two providers usually leaks by the fourth, because the differences are not cosmetic — they are differences in the underlying model.
The practical result is that most software publishers integrate one or two programs and stop. Not because more would not pay, but because the engineering cost of the third is roughly the cost of the first, forever.
What a normalising layer has to get right
Collapsing this into one interface is not just a matter of wrapping each provider's API. A layer that helps rather than hides has to:
- Preserve attribution end to end. The downstream publisher identifier must survive whatever the provider's parameter is called and however short it is. If the layer cannot pass a stable identifier through, the provider loses visibility and the publisher loses trust.
- Make program rules machine-readable. Geography, permitted traffic sources and commission structure should be fields you can filter on before you promote, not prose you find afterwards.
- Normalise state honestly. If a provider's “approved” can still reverse, the normalised model must be able to say so rather than flattening it into a false certainty.
- Not route around the provider. A layer that obscures who the traffic came from solves the publisher's problem by creating the network's. That trade is not worth making, and networks are right to refuse it.
That last point is the one that matters most for whether this kind of infrastructure is legitimate. Normalising the interface is an engineering problem. Preserving the accountability that makes performance marketing work is a design commitment, and it has to be made before the first integration, not retrofitted after.