Polling the order endpoint works, but if you’re integrating a legacy system or want one fixed URL to fetch codes in real time, SimSmsBox has a smoother way: a custom receive URL + templated responses. Every order carries an apiBindingKey; with it you fetch the latest SMS from a single fixed URL — only our address is exposed, never the upstream provider.
Get the apiBindingKey
The order response (POST /api/sms/orders/purchase) includes that order’s apiBindingKey. It’s the credential for this receive URL: when calling the record endpoint you don’t send the X-API-Key header — the key itself authorizes the request.
The fixed receive URL
Call the record endpoint with the key to fetch the order’s latest SMS in real time:
# Default JSON: status=YES means received, NO means not yet; data holds the full SMS
curl "https://api.simsmsbox.com/api/sms/record?key=YOUR_API_BINDING_KEY"
# Minimal text: received -> YES|<full SMS content>, not yet -> NO|
curl "https://api.simsmsbox.com/api/sms/record?key=YOUR_API_BINDING_KEY&format=txt"
Default JSON response:
{
"code": 200,
"msg": "OK",
"status": "YES",
"data": {
"orderNo": "S2606...",
"phone": "+1xxxxxxxxxx",
"content": "Your code is 123456",
"codeValue": "123456",
"sender": "Telegram",
"receivedAt": "2026-06-02T08:00:00Z"
}
}
The format param: omit it for JSON (rendered via your template if you configured one); format=json forces JSON; format=txt returns minimal text.
Templated responses (for legacy systems)
If your receiver only accepts a fixed shape (say a legacy system expecting certain field names), create a template under “Code settings → Return templates”, map the fields to your structure, and bind it to the order. Templates use single-brace placeholders (case-insensitive):
Template: { "otp": "{Code}", "order": "{OrderNo}", "from": "{Sender}" }
Rendered: { "otp": "123456", "order": "S2606...", "from": "Telegram" }
Available placeholders:
| Placeholder | Meaning |
|---|---|
{Code} | Verification code |
{Content} | Full SMS content |
{Phone} | Number |
{OrderNo} | Order number |
{Sender} | Sender |
{ReceivedAt} | Received timestamp |
The template’s response Content-Type is also configurable under “Code settings” (e.g. text/plain or application/json), so the receiver gets exactly the format you want.
Poll the fixed URL straight from a script
A fixed URL drops nicely into a polling script; format=txt is the simplest:
# Wait 15s, then query every 5s for up to 2 minutes
sleep 15
for i in $(seq 1 24); do
resp=$(curl -s "https://api.simsmsbox.com/api/sms/record?key=YOUR_API_BINDING_KEY&format=txt")
case "$resp" in YES\|*) echo "$resp"; break;; esac
sleep 5
done
Security notes
- The URL is authorized by the key and carries no account info, but still treat it like a secret — don’t expose it in the frontend or logs.
- The key can be rotated under “Code settings → Bindings”; rotate it immediately if you suspect a leak.
- The receive URL is read-only and only exposes our address, never the upstream provider.
A fixed receive URL (real-time pull) plus order polling (fallback) is the most robust combo. Further reading: Automated ordering and polling.