API reference

Create an order

Buys one or more eSIMs, debits your prepaid balance and returns the installable eSIM.

POSThttps://app.journeystack.co/api/public/v1/orders

Body parameters

FieldTypeDescription
plan_idrequireduuidA plan ID from GET /plans.
quantityintegerdefault 1How many eSIMs to issue, 1–50. Each is a separate profile.
daysintegerNumber of days for per-day (unlimited) plans, 1–365. Rejected on fixed plans with any value other than 1.
customer.namestringTraveller name, up to 120 characters. Stored for your reporting only.
customer.emailstringTraveller email, valid address up to 255 characters.
customer.referencestringYour own booking reference, up to 120 characters.

Behaviour you should rely on

  • Always send an Idempotency-Key header. Replays return the original order with Idempotent-Replay: true and never charge twice.
  • Returns HTTP 201 on a new order and HTTP 200 on an idempotent replay.
  • If issuing fails the call returns provider_error and your balance is refunded automatically in the same request.

Request

cURL
curl -X POST https://app.journeystack.co/api/public/v1/orders \
  -H "Authorization: Bearer $JS_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: booking-90210" \
  -d '{
  "plan_id": "0f4c1c2e-6f8a-4a09-9f0d-2f1b8c7d5e41",
  "quantity": 1,
  "days": 7,
  "customer": {
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "reference": "BK-90210"
  }
}'
body
{
  "plan_id": "0f4c1c2e-6f8a-4a09-9f0d-2f1b8c7d5e41",
  "quantity": 1,
  "days": 7,
  "customer": {
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "reference": "BK-90210"
  }
}

Response

201 Created
{ "data": {
    "id": "b1f0a3c9-70d2-4b55-9a3f-4f2e1c8d9a10",
    "status": "completed",
    "environment": "sandbox",
    "plan_id": "0f4c1c2e-6f8a-4a09-9f0d-2f1b8c7d5e41",
    "quantity": 1,
    "days": 7,
    "price": { "unit": 17.15, "total": 17.15, "currency": "USD" },
    "customer": { "name": "Ada Lovelace", "email": "ada@example.com", "reference": "BK-90210" },
    "error": null,
    "created_at": "2026-01-14T09:31:01.880Z",
    "esims": [{
        "id": "9ac2d51b-8f2e-4d6e-b0a1-6c5f0d9a3b77",
        "plan_name": "Singapore Unlimited",
        "iccid": "8944478000123456789",
        "qr_code_url": "https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=LPA%3A1%24sandbox.journeystack.co%24A1B2C3D4E5",
        "activation_code": "LPA:1$sandbox.journeystack.co$A1B2C3D4E5",
        "smdp_address": "sandbox.journeystack.co",
        "status": "ALLOCATED",
        "validity_days": 7,
        "data": { "unlimited": true, "total_bytes": null, "used_bytes": 0 },
        "install": { "instructions": "On the device go to Settings > Cellular / Mobile Data > Add eSIM, then scan the QR code or enter the activation code manually." },
        "created_at": "2026-01-14T09:31:02.114Z"
      }]
  } }

Selected response fields

FieldTypeDescription
statusstringcompleted when eSIMs were issued. failed orders are refunded in full.
price.unitnumberPrice of one eSIM, already multiplied by days on per-day plans.
price.totalnumberAmount debited from your balance.
esimsarrayOne object per eSIM, with QR code and activation code ready to deliver.

Errors

CodeHTTPWhat to do
unauthorized401Check the Authorization header and that the key is still active in your portal.
invalid_request400Read `error.details` for the offending field, fix and resend.
insufficient_funds402Top up, then retry with the same idempotency key.
not_found404Re-fetch the ID. Plans return not_found once they are retired from the catalogue.
rate_limited429Honour `Retry-After` (60 seconds) and back off. Ask support for a higher limit.
provider_error502You were refunded in full. Safe to place a new order with a new idempotency key.
internal_error500Retry with the same idempotency key — it can never double-charge you.

Sandbox console

Run this endpoint against the sandbox with your own test key. Nothing is provisioned on the live network and no real money moves.

Try it

/api/public/v1/orders