DEVELOPERS · V1

API documentation

Your account API key is assigned automatically and can rent numbers and receive OTPs using your balance.

maxPriceUsdt is optional. Leave it blank to rent at the current price; enter it to set a price ceiling per order. Only the actual price is charged, never the ceiling.

Account · API key

Log in · Your account API key is assigned automatically and can rent numbers and receive OTPs using your balance.

Base URL: https://cheapestotp.com/api/v1
Authentication: Authorization: Bearer YOUR_API_KEY

Get started in 3 steps

  1. Open Account and copy your API key.
  2. Paste your key below. Open Balance request and click Send request to test the connection.
  3. Get countries → get services and prices → rent a number → poll OTP every 5 seconds.

serviceId is a stable CheapOTP ID. When renting, use the service and country ID or code; if you send both, they must agree.

Example using codes: tg = Telegram, us = United States. Maximum price is optional: leave blank to rent at the current price, or enter a cap per order.

{"serviceCode":"tg","countryCode":"us","maxPriceUsdt":"0.50"}
Used only when you click Send request. Never saved in browser storage or included in examples.

Download Python example · Download Postman collection

Select a method → enter parameters → copy cURL or click Send request. Response examples are sample data; your live result appears after sending.

Request a numberPOST

POST /api/v1/orders

Rent a number at its current price. Optional maxPriceUsdt sets your maximum price per order in USDT; omit it to accept the current price. A low cap returns price_limit_exceeded; unavailable stock returns no_numbers. Only the current price is charged. Only the current server price is charged, never the maximum cap.

Request URL

https://cheapestotp.com/api/v1/orders

Rent with a single URL

Replace YOUR_API_KEY with your key. Keep requestId when retrying the same purchase; use a new ID for a new purchase. Keep URLs containing your key private.

cURL — replace YOUR_API_KEY with your key

POST https://cheapestotp.com/api/v1/orders

Changes real orders and wallet funds. Keep the same Idempotency-Key when retrying the same purchase.

Response example (sample data)

{
  "data": {
    "balance": "3.800000",
    "order": {
      "countryCode": "us",
      "createdAt": "2026-10-06T14:00:00Z",
      "id": 123,
      "otp": null,
      "phoneNumber": "+12025550123",
      "price": "0.200000",
      "serviceCode": "tg",
      "serviceName": "Telegram",
      "status": "waiting",
      "updatedAt": "2026-10-06T14:00:00Z"
    }
  },
  "success": true
}
Get the activation statusGET

GET /api/v1/orders/{id}

Poll your order at least 5 seconds apart; use a bounded queue for many orders and respect rate-limit headers. Stop at a final state.

Request URL

https://cheapestotp.com/api/v1/orders/{id}

cURL — replace YOUR_API_KEY with your key

GET https://cheapestotp.com/api/v1/orders/{id}

Response example (sample data)

{
  "data": {
    "countryCode": "us",
    "createdAt": "2026-10-06T14:00:00Z",
    "id": 123,
    "otp": "123456",
    "phoneNumber": "+12025550123",
    "price": "0.200000",
    "serviceCode": "tg",
    "serviceName": "Telegram",
    "status": "received",
    "updatedAt": "2026-10-06T14:00:00Z"
  },
  "success": true
}
Cancel an activationPOST

POST /api/v1/orders/{id}/cancel

Cancel a waiting order after at least 120 seconds if supported by the provider. Refund requires provider confirmation. Received OTP orders cannot be cancelled. No Idempotency-Key is needed. Repeating a completed cancellation returns the cancelled order without another refund.

Request URL

https://cheapestotp.com/api/v1/orders/{id}/cancel

cURL — replace YOUR_API_KEY with your key

POST https://cheapestotp.com/api/v1/orders/{id}/cancel

Response example (sample data)

{
  "data": {
    "balance": "4.000000",
    "order": {
      "countryCode": "us",
      "createdAt": "2026-10-06T14:00:00Z",
      "id": 123,
      "otp": null,
      "phoneNumber": "+12025550123",
      "price": "0.200000",
      "serviceCode": "tg",
      "serviceName": "Telegram",
      "status": "cancelled",
      "updatedAt": "2026-10-06T14:00:00Z"
    }
  },
  "success": true
}
Balance requestGET

GET /api/v1/account

Read your wallet balance in USDT. No email, name or account ID is returned.

Request URL

https://cheapestotp.com/api/v1/account

cURL — replace YOUR_API_KEY with your key

GET https://cheapestotp.com/api/v1/account

Response example (sample data)

{
  "data": {
    "balance": "4.000000",
    "currency": "USDT"
  },
  "success": true
}
Get a list of servicesGET

GET /api/v1/services

List service names and stable public IDs across the catalogue. No country filter is needed. Choose a country when renting; optionally set a maximum USDT price; checkout checks price and stock.

Request URL

https://cheapestotp.com/api/v1/services

cURL — replace YOUR_API_KEY with your key

GET https://cheapestotp.com/api/v1/services

Response example (sample data)

{
  "count": 1,
  "data": [
    {
      "serviceCode": "tg",
      "serviceId": 123,
      "serviceName": "Telegram"
    }
  ],
  "nextOffset": null,
  "success": true
}
Get a list of activationsGET

GET /api/v1/orders

Page through your recorded orders with limit and beforeId. The waiting filter returns the last recorded state, not a fresh provider poll; refresh individual pending orders within your rate budget.

Request URL

https://cheapestotp.com/api/v1/orders

cURL — replace YOUR_API_KEY with your key

GET https://cheapestotp.com/api/v1/orders

Response example (sample data)

{
  "count": 1,
  "data": [
    {
      "countryCode": "us",
      "createdAt": "2026-10-06T14:00:00Z",
      "id": 123,
      "otp": null,
      "phoneNumber": "+12025550123",
      "price": "0.200000",
      "serviceCode": "tg",
      "serviceName": "Telegram",
      "status": "waiting",
      "updatedAt": "2026-10-06T14:00:00Z"
    }
  ],
  "nextBeforeId": null,
  "success": true
}
Get a list of countriesGET

GET /api/v1/countries

Country codes for price and rental requests.

Request URL

https://cheapestotp.com/api/v1/countries

cURL — replace YOUR_API_KEY with your key

GET https://cheapestotp.com/api/v1/countries

Response example (sample data)

{
  "count": 2,
  "data": [
    {
      "countryCode": "us",
      "countryId": 187,
      "countryName": "United States"
    },
    {
      "countryCode": "fr",
      "countryId": 78,
      "countryName": "France"
    }
  ],
  "success": true
}
Wallet transaction historyGET

GET /api/v1/transactions

Page through wallet entries with limit and beforeId. Positive values credit the wallet, negative values debit it. All amounts are decimal strings in USDT.

Request URL

https://cheapestotp.com/api/v1/transactions

cURL — replace YOUR_API_KEY with your key

GET https://cheapestotp.com/api/v1/transactions

Response example (sample data)

{
  "count": 1,
  "data": [
    {
      "amount": "4.000000",
      "createdAt": "2026-10-06T14:00:00Z",
      "id": 1,
      "type": "crypto_usdt"
    }
  ],
  "nextBeforeId": null,
  "success": true
}
OpenAPIJSON

OpenAPI 3.1 describes request and response fields. Import the URL into Postman or your OpenAPI client.

https://cheapestotp.com/developers/openapi.json

Open OpenAPI JSON

Integration rules

Money is USDT, returned as decimal strings with 6 decimal places. maxPriceUsdt is a cap: the server charges the current verified price, not the cap. Dates use ISO 8601 UTC, for example 2026-10-06T14:00:00Z.

Purchase: keep the same Idempotency-Key and parameters after timeout/retry. Cancellation needs no such key. For purchasing or reconcile_required, do not start a replacement purchase with a new key; contact support. No automatic refund deadline or fixed expiresAt is guaranteed.

240 reads/60 writes per minute per account, shared with the website. Invalid keys: 30/minute/IP. X-RateLimit-Limit/Remaining/Reset show the budget and next window (Unix UTC); Remaining can be zero if rejection preceded the counter. Respect Retry-After on 429/503.

For many orders, queue and space individual polls according to your budget instead of polling every order every 5 seconds. The waiting list contains stored states; individual order GET refreshes the provider. Authenticated API responses are no-store and must never enter a shared cache.

The services catalogue is independent of countries. A rental requires countryCode or countryId; both must agree; the same applies to serviceCode/serviceId. countryId can be zero by catalogue design; serviceId starts at one. Order IDs are sequential, but another account’s order always returns 404.

active means a configured price, not guaranteed stock. The account key permits read/rent and can be revoked/rotated in Account; older read-only keys still enforce scope. The database stores verification hashes and derivation nonces, never raw keys. Never send keys in URLs or store them in localStorage.

Stable error codes

invalid_api_key
A valid Bearer API key is required.
insufficient_scope
This key does not permit this operation.
invalid_request
Invalid parameters. See the API documentation.
invalid_country
Unknown or conflicting country.
invalid_search
Search must be at most 100 characters.
invalid_status
Invalid order status.
idempotency_conflict
This Idempotency-Key was used with different parameters.
request_in_progress
Processing. Retry with the same Idempotency-Key.
already_submitted
This request was already submitted.
repeat_order_active
An active order already exists for this service and country.
price_changed
Price changed. Get a new quote before a new purchase.
price_above_limit
No number is available within maxPriceUsdt.
price_limit_exceeded
No number is available within maxPriceUsdt. Increase the limit or try again later.
insufficient_balance
Insufficient wallet balance.
no_numbers
No numbers available.
rental_unavailable
Rental is currently unavailable.
purchase_unconfirmed
Purchase needs review. Do not start a replacement purchase.
cancel_unavailable
This order cannot be cancelled.
cancel_too_early
Wait at least 120 seconds before cancellation.
cancel_unsupported
Cancellation is unavailable for this order.
cancel_unconfirmed
Cancellation needs review. No refund is confirmed yet.
order_not_found
Order not found.
forbidden
Access denied.
not_found
Resource not found.
method_not_allowed
Method not allowed.
rate_limited
Too many requests. Respect Retry-After.
server_busy
Temporarily busy. Respect Retry-After.
request_entity_too_large
Request body is too large.
unsupported_media_type
Use application/json.
bad_request
Invalid request.
internal_error
Unable to process the request. Contact support if it persists.