The major version is part of the base URL. Backward-compatible fields and endpoints may be added to v1; removals or incompatible semantic changes require a new major version and a migration notice in the changelog.
Paid endpoints accept an optional max_price in the JSON body, as a positive USD decimal string such as "3.20". This caps the order or top-up price, not the per-GB rate. For POST /numbers/bulk, the cap applies per number, not to the batch total. A quote does not lock the price. If a bulk purchase stops on price, a refusal can return 409 without price fields, or a partial batch can return 201 with purchased numbers and stopped="price". Check the returned numbers before requesting another batch. For a single-order request, a higher price returns 409 price_exceeded; an increase beyond the reserved API allowance returns 409 price_changed. Check a fresh quote and confirm the new amount before making another purchase request. After a definite price rejection, use a new idempotency key for the newly confirmed request where required.
A unique Idempotency-Key is required for new number, rental, eSIM, email and proxy orders, and for proxy data top-ups. Keep the same key and exact JSON bytes when retrying a timeout within 24 hours. A completed result is retained for 24 hours and replayed for identical retries; reusing the key with a different route or body returns 409. SMS reactivation also supports this replay middleware when an optional Idempotency-Key is supplied. Keep the same key, method, path and exact JSON bytes for uncertain retries. Without a key, fetch the SMS order before deciding whether to repeat reactivation. Free SMS another-code and email reorder actions do not use this middleware. After an uncertain response for those actions, fetch the SMS order or list recent email orders before deciding whether to repeat.
SMS billing example: a $0.20 order reserves $0.20 and charges it when its first code arrives. That is the only charge for the number. A duplicate notification does not create another paid request, and “Request another code” is free: nothing is held or charged, and the next code is added to the same order when it arrives. Reactivation starts a new paid activation window at the applicable price; it is not a free duplicate SMS. Delivery alone does not guarantee the target platform accepts a code or account.
For push delivery, create a webhook and verify X-NumberHub-Signature as HMAC-SHA256 over timestamp.raw_body, using the exact raw request body and the X-NumberHub-Timestamp value. Compare the result as v1=<hex digest> and reject stale timestamps. Events contain the order id and status, not OTP contents; fetch the order with your API key after notification. Delivery is at least once, so deduplicate using the event delivery id. Failed attempts retry for seven days, with backoff capped at 24 hours. Use the delivery-history endpoint to diagnose failures and rotate a signing secret immediately if it may have leaked.