Errors & rate limits
Every error uses the same shape: { "error": { "code", "message" } }. Branch your client on code, since it's stable across releases — message is for humans and may be reworded at any time.
Error codes
| Status | code | Meaning |
|---|---|---|
| 401 | unauthorized | Missing / malformed / unknown / revoked / expired key |
| 403 | forbidden | Valid key, but missing the required scope |
| 429 | rate_limited | Per-key rate limit exceeded |
| 400 | bad_request | Malformed input |
| 404 | not_found | No such resource |
| 500 | internal | Server error |
Some endpoints throw additional domain-specific codes beyond this table — e.g. whatsapp_not_configured or meta_error on the messages endpoint. Those are documented on the endpoint itself.
Rate limits
Requests are limited per key: 120 requests per minute. On a 429, these response headers tell you when to retry:
Retry-After— seconds until the window resetsX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset
The limiter tracks usage per key per server process. On a single-instance deployment this is exact; if VyaparPing ever scales the API across multiple instances, the effective ceiling per key becomes (number of instances) × 120/min until a shared limiter store is introduced.