Activation lifecycle
An activation is one purchased number waiting for one code. Create it, poll until the code lands, and it settles into a terminal state.
An activation is one purchased number waiting for one code. You create it, poll it until the code lands, and it settles into a terminal state. If no code arrives in the window, your wallet is credited back — you never pay for a code you didn't receive.
The flow
Buy
POST /v1/activations charges your wallet and returns an id, a number, and
an expires_at. The activation starts in WAITING.
Poll
GET /v1/activations/:id every few seconds. While the code is pending the
status stays WAITING and code is null.
Receive
Once the SMS lands the status flips to COMPLETED and code + full_text are
filled in. Stop polling.
Or refund
If the window closes first the status becomes EXPIRED (then REFUNDED) and
your wallet is credited back automatically.
Statuses
| Status | Meaning |
|---|---|
WAITING | Number is live and listening for the incoming SMS. Poll until it changes. |
COMPLETED | The OTP arrived. code and full_text are now populated. Terminal. |
CANCELLED | You cancelled the activation before a code arrived. Wallet refunded. Terminal. |
EXPIRED | The window closed with no code. Wallet refunded automatically. Terminal. |
REFUNDED | The charge was returned to your wallet. Terminal. |
FAILED | The number could not be provisioned. Nothing is charged. Terminal. |
Polling example
ID=$(curl -s -X POST https://api.otp.black/v1/activations \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"service":"whatsapp","country":"us"}' | jq -r .id)
# Poll until COMPLETED, EXPIRED, or REFUNDED
while true; do
RESP=$(curl -s https://api.otp.black/v1/activations/$ID \
-H "Authorization: Bearer $API_KEY")
STATUS=$(echo "$RESP" | jq -r .status)
echo "status=$STATUS"
case "$STATUS" in
COMPLETED) echo "$RESP" | jq -r .code; break ;;
EXPIRED|REFUNDED|CANCELLED|FAILED) echo "no code — refunded"; break ;;
esac
sleep 3
done