Authentication
Which endpoints are public and which need a key, how to create one and send it three ways, and the rate limits for both.
You can build everything up to your first order without an API key. The catalogue, quotes, rental pricing and email products are public: anyone can call them, and they answer with public list prices. A key is needed only for what spends money or reads your account.
Public or keyed
Endpoint | Key |
|---|---|
| Optional |
| Optional |
| Optional |
| Optional |
| Not used |
| Not used |
| Required |
| Required |
| Required |
| Required |
All paths are under https://numestri.com/api/v1. The OpenAPI document marks the same split: public operations carry no security requirement.
What a key changes on a public endpoint
No key — you get the public list prices, and the per-address rate limit below.
A valid key — you get the prices for your account, and your account's rate limit. An account can have its own negotiated prices, which may differ from the public list; with your key, what the catalogue shows is what an order will charge you.
An invalid key — refused with
403, exactly as on a keyed endpoint. It never falls back to public prices, so a typo in your key shows up while you are still browsing, not at your first order.
# Public prices, no key
curl https://numestri.com/api/v1/catalog/platforms
# Your account's prices
curl https://numestri.com/api/v1/catalog/platforms -H "Authorization: Bearer $NUMESTRI_KEY"Getting a key
- Create a key
Sign in, open Developer in the dashboard (
/dashboard/developer) and choose New key. Name it after where it will live (for example Production server). Keys exist only because you made one — none is created for you at sign-up.The full key is shown once, when you create it; only a fingerprint is stored. If you lose it, create a new one and revoke the old.
- Send it with every keyed request
Any one of these works. Use whichever your HTTP client already does.
- Bearer token
- X-API-Key header
- key parameter
curl https://numestri.com/api/v1/request/balance \ -H "Authorization: Bearer $NUMESTRI_KEY"curl https://numestri.com/api/v1/request/balance \ -H "X-API-Key: $NUMESTRI_KEY"curl https://numestri.com/api/v1/request/balance -d "key=$NUMESTRI_KEY"{ "balance": "12.50" }If more than one is sent, the
Authorizationheader wins, thenX-API-Key, thenkey. Prefer a header: a key in a URL ends up in logs. - Revoke it when you are done with it
Revoking a key in Developer stops it immediately. To change a key, create the new one, deploy it, then revoke the old one — there is never a moment with no working key.
Treat a key like a password
A key spends your balance. Keep it on your server, never in a browser, app bundle or public repository. If one leaks, revoke it. A storefront that shows prices to visitors can call the public endpoints without a key at all.
When the key is missing or wrong
Situation | HTTP | Body |
|---|---|---|
No key on an endpoint that needs one |
|
|
A key that does not exist or was revoked (any endpoint, public ones included) |
|
|
Many invalid keys from one address in a short time |
|
|
{
"success": 0,
"errors": [{
"message": "Invalid API key",
"param": "key",
"description": "Your API key, which you can create on the Developer page at /dashboard/developer"
}]
}Rate limits
Caller | Limit (default) | Counted per |
|---|---|---|
No key, public endpoints | 10 requests per second | IP address |
With a key, any endpoint | 32 requests per second | Account |
Purchases (numbers, rentals, email accounts and paid resends together) | 60 per minute | Account |
Over a limit, the request is refused with 429 and a Retry-After header saying how many seconds to wait. The two request limits also send RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset with the refusal.
{
"success": 0,
"errors": [{
"message": "Rate limit exceeded. Slow down and try again.",
"description": "Requests without an API key are limited per IP address; send your key for a higher limit."
}]
}The description appears only on the anonymous limit. If you hit it from a server, send your key: the account limit is higher and is not shared with anyone else behind your address. Polling one order every few seconds, or using /request/active for many orders at once, stays far below any of these. Catalogue levels also support If-None-Match, and a 304 is the cheapest way to check for changes.