Create an order
Buys packages and provisions eSIMs. The cost is taken from your balance.
Headers
Section titled “Headers”| Header | Required | Notes |
|---|---|---|
Idempotency-Key |
Yes | Unique per order attempt. Omitting it returns 422. See Idempotency |
Request
Section titled “Request”| Field | Type | Required | Notes |
|---|---|---|---|
items |
array | Yes | 1–100 line items |
items[].package_id |
string | Yes | From List packages |
items[].quantity |
integer | Yes | 1–500. Each unit produces one eSIM |
items[].customer |
object | No | Assign the buyer now, or later via Assign a customer. A customer already in your list with the same email or phone is reused, not duplicated |
payment_mode |
enum | No | BALANCE (default) or ONLINE |
client_reference |
string | No | Your own reference, max 255. Returned on the order |
expected_total |
string | No | The total you showed the buyer. If the real price differs, the order is rejected rather than charged |
curl -X POST https://partner-api.esimfo.com/v1/orders \ -H 'Authorization: Bearer esf_live_at_...' \ -H 'Idempotency-Key: 9f1c4e2a-7b3d-4a58-9c06-2e8f5d1b4a73' \ -H 'Content-Type: application/json' \ -d '{ "items": [ { "package_id": "pkg_tr_3gb_30d", "quantity": 2, "customer": { "full_name": "Ada Lovelace", "email": "[email protected]", "external_ref": "crm-88213" } } ], "payment_mode": "BALANCE", "client_reference": "cart-4821", "expected_total": "8.40" }'Response 201
Section titled “Response 201”| Field | Type | Notes |
|---|---|---|
id |
string | Order id |
order_number |
string | Human-readable reference |
status |
enum | See the table below |
payment_mode |
enum | BALANCE or ONLINE |
subtotal |
string | Before commission |
commission_amount |
string | Extra charged on ONLINE payment. "0.00" when paid from balance |
total |
string | What was taken from your balance |
currency |
string | ISO 4217 |
client_reference |
string | null | Echoed back |
created_at |
string | ISO 8601 UTC |
items[] |
array | package_id, quantity, unit_price, line_total |
esims[] |
array | The provisioned eSIMs — see Get an eSIM for the fields |
{ "id": "ord_4b21c9e7", "order_number": "ESF-2026-0004821", "status": "COMPLETED", "payment_mode": "BALANCE", "subtotal": "8.40", "commission_amount": "0.00", "total": "8.40", "currency": "EUR", "client_reference": "cart-4821", "created_at": "2026-08-22T09:14:03.512Z", "items": [ { "package_id": "pkg_tr_3gb_30d", "quantity": 2, "unit_price": "4.20", "line_total": "8.40" } ], "esims": [ { "id": "esm_9a3f1c", "iccid": "89852350326100409575", "lpa_code": "LPA:1$rsp.truphone.com$QR-G-5C-1LK-1V0FS", "qr_code_url": "https://cdn.esimfo.com/qr/esm_9a3f1c.png", "smdp_address": "rsp.truphone.com", "matching_id": "QR-G-5C-1LK-1V0FS", "status": "PROVISIONED", "data_total_mb": 3072, "data_used_mb": 0, "data_remaining_mb": null, "expires_at": null, "failure_reason": null } ]}Order status
Section titled “Order status”| Status | Meaning |
|---|---|
PENDING |
Created, not yet paid |
PAID |
Paid, provisioning not started |
PROVISIONING |
eSIMs are being produced |
COMPLETED |
Every eSIM is ready |
PARTIALLY_FAILED |
Some succeeded; the failed ones were refunded |
FAILED |
None succeeded; the full amount was refunded |
REFUNDED |
Every eSIM was refunded after the fact |
PARTIALLY_REFUNDED |
Some eSIMs were refunded after the fact; the rest are still yours |
Most orders return COMPLETED with esims already populated. Large orders may
return PROVISIONING with esims empty or partial — wait for the
order.completed webhook rather than polling.
Quantity produces separate eSIMs. quantity: 2 returns two independent
eSIMs with their own ICCIDs, not one eSIM with double the data.
Use expected_total when you have shown a price. Prices can move between
your catalog read and the order. Sending the figure the buyer agreed to turns
a silent overcharge into a price_changed error you can handle.
Failures refund automatically. On PARTIALLY_FAILED or FAILED the
balance for the eSIMs that could not be produced is returned without you
asking. Read failure_reason on each eSIM to see why.
Errors
Section titled “Errors”| Status | Code | Cause |
|---|---|---|
| 422 | validation_failed |
Missing Idempotency-Key, empty items, bad quantity |
| 422 | insufficient_balance |
Balance does not cover the total |
| 422 | package_not_available |
Package withdrawn or not sold to you |
| 422 | price_changed |
Price moved away from expected_total |
| 422 | billing_required |
Billing details missing on the account |
| 409 | idempotency_key_reused |
Key already used for a different operation |
| 403 | insufficient_scope |
Key lacks orders:write |
