API Reference
Rent disposable phone numbers and receive SMS codes programmatically. Rentals you create through the API show up in the website dashboard as well — it's the same account either way.
Authentication
All endpoints require an API key passed via the Authorization header. Get your key from Settings.
Authorization: Bearer omo_live_...Example request:
curl https://ohmyotp.com/api/v1/user/me \
-H "Authorization: Bearer $API_KEY"Base URL
https://ohmyotp.com/api/v1Endpoints
/api/v1/servicesList available services
Returns all services you can rent a number for.
Request
curl https://ohmyotp.com/api/v1/services \
-H "Authorization: Bearer $API_KEY"Response
{
"services": [
{ "id": "AppID-3", "name": "Uber", "price": 0.4, "available": 20, "category": "Food" },
{ "id": "AppID-1", "name": "Walmart", "price": 0.4, "available": 10, "category": "retail" }
],
"total": 2
}/api/v1/services/:idService detail
Full metadata for a single service.
Request
curl https://ohmyotp.com/api/v1/services/Uber \
-H "Authorization: Bearer $API_KEY"/api/v1/balanceBalance + transactions
Your current balance and recent transactions (rental charges, refunds, deposits).
Request
curl https://ohmyotp.com/api/v1/balance \
-H "Authorization: Bearer $API_KEY"Response
{
"balance": 9997.60,
"transactions": [
{ "type": "rental_charge", "amount": -0.4, "service_id": "Uber", "created_at_unix": 1776276700 }
]
}/api/v1/rentalsRent a number
Creates a new rental. Use the service name (not id) as service_id. Returns the phone number to use.
Request
curl -X POST https://ohmyotp.com/api/v1/rentals \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id":"Uber"}'Response
{
"id": "fd7b389f-e678-4676-b937-4fef295a34a4",
"service_id": "Uber",
"phone_number": "3026873874",
"status": "active",
"cost": 0.4,
"rented_at": 1776619687,
"expires_at": 1776620287,
"sms_messages": []
}/api/v1/rentals/activeActive rentals
Request
curl https://ohmyotp.com/api/v1/rentals/active \
-H "Authorization: Bearer $API_KEY"/api/v1/rentals/historyRental history
Query params: status (all | active | completed | expired | cancelled), page, limit (max 200), used (true → only rentals that received an SMS). Each entry includes last_code, last_sms_full_text, last_sms_received_at for the most recent received SMS, plus rentable + rentable_reason indicating whether the phone is eligible for re-rent right now.
Request
curl "https://ohmyotp.com/api/v1/rentals/history?status=all&used=true&limit=20" \
-H "Authorization: Bearer $API_KEY"/api/v1/rentals/:idRental detail (with SMS history)
Returns the full rental including all SMS messages received so far. Poll this to get new codes.
Request
curl https://ohmyotp.com/api/v1/rentals/RENTAL_ID \
-H "Authorization: Bearer $API_KEY"/api/v1/rentals/:id/codeLatest code (lightweight poll)
Returns just the most recent SMS code — cheaper than the full rental endpoint.
Request
curl https://ohmyotp.com/api/v1/rentals/RENTAL_ID/code \
-H "Authorization: Bearer $API_KEY"Response
{
"rental_id": "fd7b389f...",
"status": "completed",
"code": "5384",
"message": "<Uber> Your code: 5384...",
"received_at": 1776619718,
"expires_at": 1776620287
}/api/v1/rentals/:id/cancelCancel a rental (release the number)
Releases the rented phone number before it expires. A full refund is issued if no SMS has been received yet; if a code has already arrived, the rental is just marked cancelled without a refund. You can only cancel rentals you own.
Request
curl -X POST https://ohmyotp.com/api/v1/rentals/RENTAL_ID/cancel \
-H "Authorization: Bearer $API_KEY"Response
{
"id": "fd7b389f-e678-4676-b937-4fef295a34a4",
"status": "cancelled",
"refund_amount": 0.4,
"cancelled_at": 1776276800
}/api/v1/rentals/rerentRe-rent a phone number you used before
Rents a specific phone number you've previously used for the same service. The number must still be in inventory, not expired, and not currently active in another rental. Pass an idempotency_key (≥8 chars) as a query param — replays within ~24h return the same rental instead of double-charging. Use /rentals/history to find phones you've used and check rentable=true on each entry.
Request
curl -X POST "https://ohmyotp.com/api/v1/rentals/rerent?idempotency_key=rerent-20260515-0001" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id":"Uber","phone_number":"3026873874"}'Response
{
"id": "9c1cba34-7c9d-4e8e-9f4f-9b9b1c8a4a23",
"service_id": "Uber",
"phone_number": "3026873874",
"status": "active",
"cost": 0.4,
"rented_at": 1779000000,
"expires_at": 1779000600,
"rerent": true,
"sms_messages": []
}/api/v1/rentals/rerent/checkBatch-check re-rent eligibility
Check up to 100 phone numbers at once to see which are eligible for re-rent (without actually renting). Useful for rendering a UI list. Each row returns eligible=true/false plus a machine-readable reason (ok, phone_currently_active, phone_expired, phone_not_in_inventory, insufficient_balance, etc.).
Request
curl -X POST https://ohmyotp.com/api/v1/rentals/rerent/check \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"service_id":"Uber",
"phone_numbers":["3026873874","3125550001"]
}'Response
{
"service_id": "Uber",
"cost": 0.4,
"balance": 9999.6,
"eligible_count": 1,
"results": [
{ "phone_number": "3026873874", "eligible": true, "reason": "ok", "cost": 0.4 },
{ "phone_number": "3125550001", "eligible": false, "reason": "phone_currently_active", "cost": 0.4 }
]
}Common patterns
Rent a number and wait for SMS
# 1. Create rental
RENTAL=$(curl -s -X POST https://ohmyotp.com/api/v1/rentals \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id":"Uber"}')
RENTAL_ID=$(echo "$RENTAL" | jq -r .id)
PHONE=$(echo "$RENTAL" | jq -r .phone_number)
echo "Phone: $PHONE"
# 2. Poll for code (every 5s, up to 10 min)
for i in $(seq 1 120); do
CODE=$(curl -s https://ohmyotp.com/api/v1/rentals/$RENTAL_ID/code \
-H "Authorization: Bearer $API_KEY" | jq -r .code)
if [ "$CODE" != "null" ]; then
echo "Got code: $CODE"
break
fi
sleep 5
doneCancel a rental and get a refund
Full refund if no SMS has been received. If a code already arrived, the rental is just released without a refund.
curl -X POST https://ohmyotp.com/api/v1/rentals/$RENTAL_ID/cancel \
-H "Authorization: Bearer $API_KEY"
# → { "id": "...", "status": "cancelled", "refund_amount": 0.4 }Full flow: rent → wait → use → cancel on timeout
#!/bin/bash
# Rent a number, wait up to 2 min for a code, cancel if nothing arrives.
RENTAL=$(curl -s -X POST https://ohmyotp.com/api/v1/rentals \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"service_id":"Uber"}')
RENTAL_ID=$(echo "$RENTAL" | jq -r .id)
echo "Rented: $(echo "$RENTAL" | jq -r .phone_number)"
# Poll every 5s for up to 2 minutes
for i in $(seq 1 24); do
CODE=$(curl -s https://ohmyotp.com/api/v1/rentals/$RENTAL_ID/code \
-H "Authorization: Bearer $API_KEY" | jq -r .code)
if [ "$CODE" != "null" ] && [ -n "$CODE" ]; then
echo "Got code: $CODE"
exit 0
fi
sleep 5
done
# Timed out — cancel to get a refund
echo "No code arrived, cancelling..."
curl -s -X POST https://ohmyotp.com/api/v1/rentals/$RENTAL_ID/cancel \
-H "Authorization: Bearer $API_KEY"Errors
| Status | Meaning |
|---|---|
| 401 | Missing / invalid API key |
| 402 | Insufficient balance |
| 403 | Not the owner of this rental |
| 404 | Resource not found (rental / service) |
| 409 | No numbers available for this service |
| 429 | Rate limited |
| 502 | Upstream error |