Integration guide

Find and display plans

The catalogue is large — a few thousand plans across countries, regions and global packs. Filter it server-side and cache it.

bash
curl -s "https://app.journeystack.co/api/public/v1/plans?country=SG&type=unlimited&limit=20&page=1" \
  -H "Authorization: Bearer $JS_KEY"
  • country takes an ISO alpha-2 code and is case-insensitive.
  • region returns multi-country packs, e.g. EU for Europe, AS for Asia, ME for the Middle East.
  • min_days and max_days bound fixed-validity plans.
  • type filters fixed versus unlimited, and is applied after the page is read — a page can come back shorter than limit.
  • pagination.total is the count before the type filter, so drive your paging from it but do not assume a full page.

Two kinds of plan

A fixed plan is a data bundle with a fixed validity: `data.bytes` is set, `validity.days` is set and `price.per` is `esim`. An unlimited plan is sold per day: `data.bytes` is null, `validity.billed_per_day` is true, and `price.amount` is the price of a single day.

pricing in your UI
const price = plan.validity.billed_per_day
  ? plan.price.amount * selectedDays   // traveller picks 1–365 days
  : plan.price.amount;

Always confirm with the order

Display the calculated price, but treat the `price` object on the order response as the amount actually charged. Rounding happens server-side after currency conversion.

Describing unlimited fairly

Unlimited plans give a full-speed allowance each day (`data.daily_allowance`) and then continue at a reduced speed (`data.throttled_speed`). Show both — travellers who expect uncapped full speed complain, and the information is in the response for exactly that reason.

Coverage and networks

`coverage.type` is `country` or `region`. To show the carriers an eSIM can roam on, fetch the single plan — `GET /plans/{id}` adds a `networks` array. Regional packs list a carrier per country, which doubles as your country list.

Caching

  • Sync the catalogue on a schedule — hourly is plenty — rather than calling /plans on every page view.
  • Store the Journey Stack plan ID as your key — it is the only identifier you ever need.
  • Re-check a plan before selling it: withdrawn plans start returning not_found on order.
  • Prices move with currency rates, so refresh cached prices at least daily.