Changelog
What has changed in the API: new endpoints, parameters, fields and webhook events, changes to what a value means, fixes to wrong data, and anything we plan to retire. Each item says what, if anything, you need to do about it.
Newest first. Follow along with the RSS feed.
Know when your prices change
- New
catalog.updatedwebhook. Once a day, when anything in your catalogue changed, you get the price changes, new packages and withdrawn packages at your own prices. Each list holds at most 100 entries, largest price moves first; the counts are always complete, andtruncatedis true when a list was cut short.What to do: Optional. Tick it on the Developers page - it is not part of "all events". When
truncatedis true, readGetPackages?all=truefor the rest. - New
catalog.price_scheduledwebhook. Announces price increases before they reach you, witholdPrice,newPriceand theeffectiveAtdate for each package. Until that date you keep paying the old price.What to do: Optional, and only sent while advance notice of increases is in force for your account. Tick it on the Developers page to receive it.
- Fixed
The daily catalogue report no longer loses a day's changes when its email fails to send. They are now reported on the next run instead of being dropped.
What to do: Nothing.
Load the whole catalogue in one call
- New
GetPackagesacceptsincludeDetails=true, which addspackageData.networksto every row - the same carriers and 5G flagsGetPackageDetailsreturns - so a separate details call per package is no longer needed.What to do: If you call
GetPackageDetailsfor every package, drop that loop. Without the flag,networksisnull, which means "not asked for"; an empty list means "no networks". - New
GetPackagesacceptsall=true, which ignorespageandpageSizeand returns up to 10,000 rows in one response. Combine it withincludeDetails=trueto read the full catalogue with its networks in a single request.What to do: Send
Accept-Encoding: gzipand cache the result - it is a large response that changes far less often than you would read it. - Changed
API responses are compressed (gzip or brotli) when your client asks for it.
What to do: Nothing. Most HTTP libraries already send the header and decompress for you.
Install status and wider usage coverage
- New
lifecycleonGetOrderDetails: whether the customer has downloaded and installed the eSIM, and on which phone. It carriesstate(NotDownloaded,Downloaded,Installed,Enabled,Disabled,DeletedorBlocked),device,eidand a datedeventslist, newest first.What to do: Read
lifecycle: nullas "unknown", not "not installed" - it is null on plans whose network does not report installs, and on test orders. - New
esim.installedandesim.activatedwebhooks.esim.installedfires when the customer installs the eSIM;esim.activatedwhen the plan starts counting, withactivatedAtand, once known,expiresAt. Each fires once per eSIM.What to do: Optional, and instead of polling
GetOrderDetailsfor the install. Tick them on the Developers page - they are not part of "all events". - Changed
Live usage and install status are now reported for more plans, and the direct install links (
iosInstallLink,androidInstallLink) are returned for more plans too.What to do: Nothing. Fields that were
nullbecause a plan did not report them may now be filled in, so don't treatnullas permanent. - Changed
GetOrderDetailsreads from the network, which only updates usage every few hours - on some carriers once a day. Reads are now held briefly (usage for up to ten minutes, install status for two), so polling faster than that returns the same answer.What to do: Poll no more often than every few minutes, or use the webhooks above and don't poll at all.
- Fixed
On some plans the activation and expiry times (
usage.startDate,usage.endDate) and install event dates were read as UTC when the network reports them eight hours ahead, so they came back eight hours late. They are now correct.What to do: If you stored or compared these values, expect them to move earlier by eight hours for affected plans.