otp/docs

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

StatusMeaning
WAITINGNumber is live and listening for the incoming SMS. Poll until it changes.
COMPLETEDThe OTP arrived. code and full_text are now populated. Terminal.
CANCELLEDYou cancelled the activation before a code arrived. Wallet refunded. Terminal.
EXPIREDThe window closed with no code. Wallet refunded automatically. Terminal.
REFUNDEDThe charge was returned to your wallet. Terminal.
FAILEDThe number could not be provisioned. Nothing is charged. Terminal.

Polling example

poll.sh
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

On this page