Getting started
This page gets you from nothing to one successful authenticated call. It deliberately ends before anything that charges a subscriber.
What you need first
Three things, and none of them are self-service. All are arranged with the operator team:
| What it is | |
|---|---|
| API credentials | A bearer token, issued against one short code. |
| Allowlisted IPs | The public addresses your servers call us from. Requests from anywhere else are refused before your credential is even considered. |
| A configured service | The service you are integrating, set up on your short code with its tariff and rules. |
Your credential is bound to a short code, and your access to a service is granted separately. Both must line up, which is why a token that works for one service can be refused for another: that refusal is a grant problem, not a token problem.
Every call in this documentation is server-to-server. If your web page calls our API directly, your credential is published to every visitor. This includes the anti-fraud script call, which looks like a front-end concern and is not: your backend fetches the script and passes it to your page.
Base URL and version
https://<api-host>/api/sp/v1/
The version is in the path. v1 will keep working when v2 exists; you move when you choose
to. Breaking changes get a new version: see the Changelog for what has changed within v1.
Authenticating
A bearer token on every request:
Authorization: Bearer <your-token>
Every response carries an X-Request-Id header, which also appears as requestId in the body.
Keep it. It resolves to a specific row in our logs, so quoting it in a support request is the
difference between us finding your call in seconds and asking you twenty questions.
Your first call
Start with subscription status. It is a GET, it changes nothing, and it exercises the entire
authorisation chain, so a success proves your token, your allowlisted IP, your grant and your
capability are all correct.
curl -s "https://<api-host>/api/sp/v1/dcb/subscription/status?serviceId=4821&msisdn=9647500000000" \
-H "Authorization: Bearer <your-token>"
serviceId is the number the operator team gave you with your grant. Every call names its service,
because one credential can cover several services on the same short code. It is also the number that
arrives in every DataSync event, so the two always agree.
A success looks like this:
{
"requestId": "01JB2K9WQ4X7YH3M8N5P6R7T8V",
"code": "OK",
"data": {
"msisdn": "9647500000000",
"subscribed": false,
"state": null,
"subscribedAt": null
}
}
If that call works, your integration is authorised and you can move on to a flow. If it does not, the failure is almost certainly in the three prerequisites above rather than in your code.
Reading any response
Every response has the same shape.
{ "requestId": "…", "code": "OK", "data": { } }
{ "requestId": "…", "code": "PIN_EXPIRED", "message": "…", "retryable": false }
Three rules that will save you a rewrite later:
- Branch on
code, never onmessage.codeis the contract and is stable.messageis written for a human reading a log and may change without notice. retryabletells you whether trying again could possibly help. When it isfalse, retrying the identical request will fail identically: the fix is upstream of the call.- The HTTP status follows the code, not the other way round. If you find yourself mapping statuses to meanings, read the code instead.
When it fails, the order matters
Authorisation is checked in a fixed order, and the first thing that fails is the thing you are told about. So a refusal names the earliest problem, not necessarily the only one: fix it and the next call may reveal the next.
The order is: credential → short-code ownership → service grant → IP allowlist → capability → rate limit → idempotency. The full detail is on Order of checks.
Next
- Building a subscription flow? → Subscription (Landing Page)
- Want the shortest journey on mobile data? → Header Enrichment
- Charging once rather than recurring? → One-Time Purchase
- Coming from the legacy platform? → Migration from legacy, first
Before you build any of them, read Anti-fraud. It starts on your page, and a flow whose page never loaded the script is refused at the final step, with a refusal that looks like a decline. It is the most common way a first integration fails.