One integration, several carriers. You keep the customer; we provision the line. Base URL https://solutiontelecommobile.com/v1 — OpenAPI 3.0.
curl https://solutiontelecommobile.com/v1/balance \ -H "Authorization: Bearer stm_sandbox_your_key_here"
curl -X POST https://solutiontelecommobile.com/v1/orders \
-H "Authorization: Bearer $STM_KEY" \
-H "Idempotency-Key: your-order-4711" \
-H "Content-Type: application/json" \
-d '{"sku":"PFRQ8FIBC","quantity":1,"reference":"your-order-4711"}'
| Method | Path | What it does |
|---|---|---|
| GET | /v1/catalog | Plans available to you, already at your price |
| GET | /v1/catalog/{sku} | A single plan |
| POST | /v1/orders | Buy — requires Idempotency-Key |
| GET | /v1/orders | Your orders, newest first |
| GET | /v1/orders/{id} | One order, with ICCID, LPA and QR payload |
| POST | /v1/orders/{id}/topup | Add data to an eSIM already sold — the QR does not change |
| GET | /v1/balance | Prepaid balance |
| GET | /v1/usage/{iccid} | Data used, remaining and expiry for one eSIM |
{
"data": {
"id": 5,
"environment": "sandbox",
"status": "delivered",
"sku": "PFRQ8FIBC",
"quantity": 1,
"unit_price_usd": "0.3750",
"total_price_usd": "0.3750",
"currency": "USD",
"reference": null,
"topup_of": 4,
"esims": [{
"iccid": "8955...",
"activation_code": "LPA:1$smdp.example$MATCHINGID",
"qrcode": "LPA:1$smdp.example$MATCHINGID"
}]
}
}
Top-ups keep the QR. POST /v1/orders/{id}/topup returns a new order with topup_of pointing at the original — the traveller installs nothing again, the data simply lands on the same eSIM.
Two of them, and the second is the one that protects you: a cap on requests per minute, and a cap on how much balance can be spent per hour. A loop without a sleep can otherwise drain your account in seconds. When you hit either, we answer 429 with Retry-After — retry with the same key, never a new one.
| Status | Code | Meaning |
|---|---|---|
| 400 | missing_idempotency_key | The buying endpoints require it |
| 401 | invalid_token | Key is wrong or revoked |
| 402 | insufficient_balance | Top up your account |
| 403 | account_not_live | Onboarding not finished — use a sandbox key |
| 404 | not_found | Plan or order not available to your account |
| 409 | idempotency_key_reuse | Same key, different body |
| 429 | rate_limit | Too many requests, or hourly spend cap |
| 502 | carrier_error | Carrier failed — your balance was returned automatically |
We add fields freely; we never rename or remove one without publishing /v2 and keeping /v1 running. Write your parser to ignore unknown fields and your integration will not break.
Talk to us about getting a key