You set up dynamic pricing. Your platform now bumps the price during peak hours, drops it overnight, reacts to demand the way it is supposed to. On paper, every session should be priced the way you designed it.
Then you look at the CDRs from your roaming traffic and some of them clearly are not. A session that should have billed at your evening rate settled at what looks like your old flat tariff. Nobody changed anything on your side. Nothing broke, technically. The price update just never fully arrived where it needed to.
This is a quieter problem than most pricing conversations, because it does not show up as an error. It shows up as revenue that is a little lower than your own dashboard says it should be, spread thin enough across sessions that it is easy to write off as noise.
Where the gap actually is
A dynamic tariff is not one update, it is a broadcast. Your platform pushes the new price out through OCPI (or whatever protocol you are on) to every connection that is supposed to receive it: direct eMSP integrations, roaming hubs, card networks, app partners. Each of those hops is a separate technical relationship, built and maintained by a different party, on a different release cycle.
Public documentation on OCPI integration is fairly candid about this: tariff handling is described as one of the most sensitive parts of the protocol, specifically because a tariff mismatch means the price a driver sees differs from the price that actually gets billed. CDR mismatches are also flagged as one of the most common sources of OCPI integration issues in the first place, often traced back to how a receiving party interpreted or cached the tariff, not to any error on the sending side. AMPECO's OCPI guide and Codibly's protocol breakdown both flag it as one of the most common integration issues, not an edge case.
In practice that means the update your platform sent out does not behave the same way twice. One eMSP applies it within the hour. One hub caches the previous tariff for longer than you would expect. One roaming connection still resolves to a default price because that is what its integration was actually built to do, regardless of what you push. None of these parties are doing anything wrong on their own terms. They are just not built for a tariff that changes as often as yours now does.
Why this is easy to miss
Your own platform will tell you the tariff update went out. That is true, and it is also not the whole picture, because "sent" and "received and applied" are two different events that happen on two different systems you do not control.
The only place the gap actually shows up is in the CDRs that come back afterward, and only if you are checking what price a given session actually settled at against what your schedule said it should have been at that hour, on that connector, through that specific roaming route. Most billing reconciliation checks whether the totals add up, not whether each session priced against the tariff it was supposed to.
The routes matter more than they look like they should, too. Which hub or eMSP a given roaming session comes in through is not fixed. Partners migrate between hubs, renegotiate connections, or change their integration setup on their own timeline, without necessarily telling every CPO on the other end. A route that reliably picked up your tariff updates for months can quietly stop doing that after a change on their side.
Where it breaks down on your own side (the CPMS)
Some of the gap starts before the update even leaves your platform:
- A tariff push that fires once on save, with no automatic retry if a hub connection was temporarily down when it went out.
- Overlapping tariff profiles or versions on the same connector, so it is ambiguous which one a receiving party is even supposed to apply.
- No alerting when an OCPI push to a specific route fails or gets rejected: it just silently does not land, and nothing in your own system flags it.
- Tariff updates batched or scheduled rather than pushed in real time, which opens a delay window on top of whatever delay exists downstream.
- Inconsistent tariff IDs or models across connectors and hubs, left over from older integrations that were never fully standardized.
None of these are exotic failures. They are the kind of thing that accumulates quietly in any CPMS that grew its roaming integrations one connection at a time.
Where it breaks down on the other side (the MSPs and hubs)
The rest of the gap sits with parties you do not control at all:
- Hubs or eMSPs caching a tariff for longer than your update frequency, because their systems were built around tariffs that change occasionally, not daily or hourly.
- Partner integrations built for periodic polling rather than push-based updates, so a price change simply waits for the next poll cycle.
- Silent fallback to a default or last-known-good tariff when a receiving system fails to parse or validate the new tariff object.
- Card networks and older app integrations with no real path to displaying or billing a dynamic price at all.
- Routing changes: a partner migrates to a different hub or renegotiates a connection, and the route that used to pick up your updates reliably no longer does, without anyone telling you.
None of this means dynamic pricing is not worth doing. It means the value only shows up on the traffic that actually receives your price, and right now, for most operators, nobody is watching the full chain closely enough to know which traffic that is.
Why this stays unsolved for most operators
This is not a problem you fix once. CPMS-side issues and MSP-side issues both keep recurring as partners change their integrations, hubs get migrated, and new roaming connections get added. Catching it properly means continuously matching CDRs against your pricing schedule, per route rather than per partner, and doing it fast enough that it does not quietly eat into a quarter's revenue before anyone notices.
That is exactly the gap Proxilink was built to close. We have developed a system that continuously monitors tariff sync across CPMS and roaming connections for our customers, catching the routes where a dynamic price is not actually landing before it turns into a revenue surprise three months later. It is live and running for operators today.
If this sounds like something you have never fully checked on your own network, we are happy to walk through what it would look like for your setup.
Frequently asked questions
Why doesn't a tariff update reach every roaming partner at the same time?
Because a dynamic tariff isn't one update, it's a broadcast across separate technical relationships: direct eMSP integrations, roaming hubs, card networks, app partners. Each hop runs its own release cycle and its own caching behaviour, so the same update can land within the hour on one connection and sit stale for days on another.
What's the difference between a CPMS-side and an MSP-side sync problem?
CPMS-side issues start before the update even leaves your own platform: a push that fires once with no retry, overlapping tariff versions, or a failed push nobody gets alerted about. MSP-side issues sit with the roaming partner: a hub caching a tariff longer than your update frequency, an integration built for polling instead of push, or a silent fallback to a default price.
How would an operator actually notice this is happening?
Not from the platform that sent the update, since 'sent' and 'received and applied' are two different events on two systems you don't control. It only shows up in the CDRs that come back afterward, and only if you check what a session actually billed at against your pricing schedule, per route, not just per partner.
Why isn't checking this once enough?
Because both sides keep changing. Partners migrate between hubs, renegotiate connections, or update their own integrations without telling every CPO on the other end. A route that reliably picked up your tariff updates for months can quietly stop after a change on their side, so it needs to be watched continuously, not checked as a one-off.