Orders API
Last updated
Rent a US phone number, poll for its SMS code, and cancel or re-rent.
Order lifecycle
Every order is in one of four states, returned as status:
active: waiting for the SMS code.expires_atis the deadline.completed: the code arrived.sms_codeis set; this happens on its own, without any call from you.expired: no code arrived. The order expires when its code window ends and its price is credited back to your balance automatically. If a service has a very shortcode_window_seconds, no code arrives after it, but the order still expires, and is credited back, a few minutes after purchase.cancelled: you cancelled it, at least 60 seconds after purchase. The price is credited back to your balance.
The order object
Every order endpoint returns orders with these fields.
| Field | Type | Description |
|---|---|---|
id | integer | Unique order ID |
service | string | Service identifier |
service_display_name | string | Human-readable service name |
phone_number | string | The rented US number as 10 digits, with no +1 country code and no formatting (e.g. "2025551234"). Add +1 yourself if a form needs E.164. |
status | string | One of: active, completed, cancelled, expired |
price | number | Amount charged in USD |
carrier | string or null | The carrier of the number ("at&t" or "tmobile") when you chose one, or null when you got whichever carrier was available |
requested_carrier | string or null | The carrier you asked for. Equals carrier, except when carrier_fallback "any" bought a number on whichever carrier was available, at the normal price: then carrier is null and this keeps your choice. |
sms_code | string or null | Received SMS code (null until received). Digits come without spaces. For a few services the code is a link plus an ID rather than digits. |
sms_message | string or null | The full SMS text the code came in, as plain text (null until received). It may contain a link: treat it as untrusted text. Set to null 30 days after the SMS arrived; sms_code stays. |
messages | object[] | Every SMS received on the order, oldest first: the one with sms_code, then any follow-up codes. Each item has code, text (the full SMS, or null) and received_at (ISO 8601). Empty until the code arrives. text becomes null 30 days after the SMS arrived; code stays. |
expires_at | string | Deadline for the SMS code: no code arrives after it. An order with no code expires and is credited back at this time or, for a service whose code window is shorter than most, a few minutes later. ISO 8601. |
created_at | string | ISO 8601 creation timestamp |
completed_at | string or null | ISO 8601 completion timestamp |
followup_codes | string[] | Additional codes received after the order completed. Only present when a follow-up code has actually arrived; the key is omitted from every other response. Available for a small number of services that send more than one message to the same number after completion; codes may be alphanumeric. Best effort, no guarantee: delivery depends on the number remaining active. Re-fetch this endpoint later to check. Each follow-up code is also in messages, with its full text. |
POST /v1/orders
Rent a US phone number for a service
Request body for buying a number
| Name | Type | Required | Description |
|---|---|---|---|
service | string | Yes | Service name from GET /v1/services (e.g. "google") |
carrier | string | No | Optional: choose "at&t" or "tmobile", for about 20% more. You get a number on exactly that carrier; if it has none, the purchase fails with 409 OUT_OF_STOCK (scope "carrier") and nothing is charged. Omit to get whichever carrier is available. |
carrier_fallback | string | No | Only with carrier. "none" (default): fail when that carrier has no numbers. "any": buy a number on whichever carrier is available instead, at the normal price; the order then has carrier null and requested_carrier set to the carrier you asked for. |
curl -X POST https://api.diddysms.com/v1/orders \
-H "Authorization: Bearer dsk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"service": "google", "carrier": "at&t"}'resp = requests.post(
"https://api.diddysms.com/v1/orders",
headers={"Authorization": "Bearer dsk_your_api_key_here"},
json={"service": "google", "carrier": "at&t"},
)
order = resp.json()["order"]Response (201 Created)
{
"order": {
"id": 200,
"service": "google",
"service_display_name": "Google",
"phone_number": "2025551234",
"status": "active",
"price": 1.80,
"carrier": "at&t",
"requested_carrier": "at&t",
"sms_code": null,
"sms_message": null,
"messages": [],
"expires_at": "2026-02-26T22:49:00Z",
"created_at": "2026-02-26T22:40:00Z",
"completed_at": null
}
}If that carrier has no numbers (409 Conflict)
Nothing is charged.
{
"detail": {
"error": {
"code": "OUT_OF_STOCK",
"message": "T-Mobile numbers for Google are out of stock right now: choose Any as the carrier, or try again in a few minutes.",
"scope": "carrier"
}
}
}Fall back to whichever carrier is available, at the normal price
Send "carrier_fallback": "any". The order then has carrier: null and requested_carrier keeps your choice.
curl -X POST https://api.diddysms.com/v1/orders \
-H "Authorization: Bearer dsk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"service": "google", "carrier": "tmobile", "carrier_fallback": "any"}'{
"order": {
"id": 201,
"service": "google",
"service_display_name": "Google",
"phone_number": "2025551234",
"status": "active",
"price": 1.50,
"carrier": null,
"requested_carrier": "tmobile",
"sms_code": null,
"sms_message": null,
"messages": [],
"expires_at": "2026-02-26T22:49:00Z",
"created_at": "2026-02-26T22:40:00Z",
"completed_at": null
}
}Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | ORDER_ERROR | The purchase was rejected; the message says why. Any charge is credited back automatically. |
| 402 | INSUFFICIENT_BALANCE | Not enough funds to purchase |
| 404 | NOT_FOUND | Service does not exist |
| 409 | OUT_OF_STOCK | No numbers left right now. scope "carrier": none on the chosen carrier (retry without carrier, or send carrier_fallback "any"); scope "service": none for the service. Nothing is charged. |
| 429 | MAX_RENTALS | Maximum 100 concurrent active rentals reached |
| 503 | SERVICE_UNAVAILABLE | Service temporarily unavailable. Please try again. |
GET /v1/orders
List your orders, or only the active ones
Query parameters for listing orders
| Name | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by "active" or omit for all orders |
limit | integer | No | Max results, 1-100 (default: 20) |
offset | integer | No | Results offset (default: 0) |
curl "https://api.diddysms.com/v1/orders?status=active" \
-H "Authorization: Bearer dsk_your_api_key_here"Response
{
"orders": [
{
"id": 200,
"service": "google",
"service_display_name": "Google",
"phone_number": "2025551234",
"status": "active",
"price": 1.50,
"carrier": null,
"requested_carrier": null,
"sms_code": null,
"sms_message": null,
"messages": [],
"expires_at": "2026-02-26T22:49:00Z",
"created_at": "2026-02-26T22:40:00Z",
"completed_at": null
}
],
"pagination": {
"limit": 20,
"offset": 0,
"total": 1
}
}GET /v1/orders/{order_id}
Get one order, including its SMS code once it arrives
Order status updates in real time as soon as a message arrives.
Path parameter for fetching an order
| Name | Type | Required | Description |
|---|---|---|---|
order_id | integer | Yes | Order ID |
curl https://api.diddysms.com/v1/orders/200 \
-H "Authorization: Bearer dsk_your_api_key_here"Response (the code has arrived)
{
"order": {
"id": 200,
"service": "google",
"service_display_name": "Google",
"phone_number": "2025551234",
"status": "completed",
"price": 1.50,
"carrier": null,
"requested_carrier": null,
"sms_code": "123456",
"sms_message": "123456 is your Google verification code.",
"messages": [
{
"code": "123456",
"text": "123456 is your Google verification code.",
"received_at": "2026-02-26T22:40:48Z"
}
],
"expires_at": "2026-02-26T22:49:00Z",
"created_at": "2026-02-26T22:40:00Z",
"completed_at": "2026-02-26T22:40:48Z"
}
}sms_code field will be null until a code is received. Stop when status is no longer active.Error responses
| Status | Code | Meaning |
|---|---|---|
| 404 | NOT_FOUND | Order not found |
POST /v1/orders/{order_id}/cancel
Cancel an active order and get its price credited back to your balance
Path parameter for cancelling an order
| Name | Type | Required | Description |
|---|---|---|---|
order_id | integer | Yes | Order ID |
curl -X POST https://api.diddysms.com/v1/orders/200/cancel \
-H "Authorization: Bearer dsk_your_api_key_here"Response (200 OK)
The updated order, with status "cancelled". Its price is credited back to your balance.
Recommended whenever you stop waiting for a code: the credit is immediate and the order stops counting toward your active rentals.
If the SMS code arrives while you cancel, the order completes instead: the response is 400 ORDER_ERROR and the order is charged like any order that got its code. Fetch the order to read sms_code.
Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | COOLDOWN | Cannot cancel within 60 seconds of purchase |
| 400 | ORDER_ERROR | Order is not in "active" status, or its SMS code arrived first (the order completed with the code) |
| 404 | NOT_FOUND | Order not found |
| 503 | SERVICE_UNAVAILABLE | Could not cancel right now. Please try again. |
POST /v1/orders/{order_id}/complete
Check an active order for its SMS code right now
If the code has arrived, the order comes back completed with sms_code and completed_at set; if not, it comes back unchanged and still active. Orders complete on their own as soon as the code arrives, so polling the order is enough; call this only to force an immediate check.
Path parameter for checking an order
| Name | Type | Required | Description |
|---|---|---|---|
order_id | integer | Yes | Order ID |
curl -X POST https://api.diddysms.com/v1/orders/200/complete \
-H "Authorization: Bearer dsk_your_api_key_here"Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | ORDER_ERROR | Order is no longer active (already completed, cancelled or expired) |
| 404 | NOT_FOUND | Order not found |
| 503 | SERVICE_UNAVAILABLE | Could not check the order right now. Please try again. |
POST /v1/orders/{order_id}/re-rent
Rent the phone number from a previous order again
Path parameter for re-renting a number
| Name | Type | Required | Description |
|---|---|---|---|
order_id | integer | Yes | Original order ID |
curl -X POST https://api.diddysms.com/v1/orders/200/re-rent \
-H "Authorization: Bearer dsk_your_api_key_here"Response (201 Created)
Returns a new order object with a new ID but the same phone number.
Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | ORDER_ERROR | Cannot re-rent this order |
| 402 | INSUFFICIENT_BALANCE | Not enough funds |
| 404 | NOT_FOUND | Order not found |
| 409 | OUT_OF_STOCK | That number can't be rented again right now. Any charge is credited back automatically; buy a new number instead. |
| 429 | MAX_RENTALS | Maximum 100 concurrent active rentals reached |
| 503 | SERVICE_UNAVAILABLE | Could not re-rent right now. Please try again. |