Idempotency
Two operations are safe to retry without dedup keys; the rest need application-side care.
Naturally idempotent
GET /availability— read-only.GET /sms/messages— read-only history.GET /number— read-only.POST /waitlist— duplicate emails return the originalregistered_at.
Idempotent under specific conditions
POST /subscribe— re-paying with the same wallet renews the subscription with the same number. Therenewedfield disambiguates.POST /auth— each call rotates tokens. Don't fire-and-retry; if you get200, that's your only valid bearer until next time.POST /auth/nonce— each call returns a fresh nonce, so re-calling is safe but wasteful.
Operations that need care
POST /sms/send— retrying on a network timeout can produce a duplicate SMS. Check /sms/messages for the carriermessage_idbefore re-sending.GET /sms/receive— atomic claim. The same row will not be returned twice. Don't retry blindly; the message you missed in a network failure is gone from the unread queue (use /sms/messages for replay).POST /voice/dial— retrying after a timeout can place a duplicate call. Check call status via the presence WS or wait for thecall_idin the response.
Idempotency keys
We don't accept a client-supplied idempotency key today. If your retry strategy actually needs one (vs the natural / atomic properties above), open a discussion in Payment for which rail you're on — both x402 and MPP have their own settlement-side dedup we can lean on.