API Errors & Rate Limits
PingPing’s API follows standard REST conventions. This page covers the error shapes you should expect, what each status code means, and how rate limiting works.
Error response shape
All non-2xx responses share the same JSON shape:
{
"message": "Human-readable summary of what went wrong.",
"errors": {
"field_name": ["Specific reason this field failed validation."]
}
}
The errors object is only present on 422 Unprocessable Entity responses where field-level validation failed.
Status codes
| Code | Meaning | When you see it |
|---|---|---|
200 | OK | Successful read or update. |
201 | Created | Successful resource creation. |
204 | No Content | Successful delete. Empty body. |
400 | Bad Request | Malformed JSON or missing required headers. |
401 | Unauthorized | Missing, invalid, or deactivated API token. See Authentication. |
403 | Forbidden | Authenticated, but the token does not have access to that resource (typically a monitor on a different account). |
404 | Not Found | Resource id does not exist on this account. |
422 | Unprocessable Entity | Request was understood, but validation failed. The errors object names the offending fields. |
429 | Too Many Requests | Rate limit exceeded. See below. |
500 | Internal Server Error | Something on our side. We log and alert on these - if you see a sustained pattern, contact support. |
503 | Service Unavailable | Brief maintenance window. Retry with backoff. |
Rate limits
The PingPing API is rate-limited per token. The default limit is 120 requests per minute per token, which is enough for most automation. If you need a higher cap (for example, large-scale provisioning), contact us.
Every successful response includes three headers describing your current bucket state:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1748736042
X-RateLimit-Reset is a Unix timestamp at which the bucket refills.
When you exceed the limit you receive a 429 plus a Retry-After header (in seconds):
HTTP/1.1 429 Too Many Requests
Retry-After: 17
Recommended client behaviour
- Respect
Retry-After. Wait at least the number of seconds it gives you before retrying. - Exponential backoff on persistent 429s. Double the delay each retry up to a cap (for example, 60 seconds), with jitter.
- Do not retry 4xx errors other than
429. They will not become successful on a retry; fix the request or the auth. - Do retry 5xx errors up to 3 times with backoff. PingPing’s API is occasionally rolled during deploys.
Example retry pseudocode
import time, random, requests
def call_with_retry(url, headers, attempt=0, max_attempts=4):
response = requests.get(url, headers=headers)
if response.status_code == 429 and attempt < max_attempts:
wait = int(response.headers.get("Retry-After", 1)) + random.uniform(0, 1)
time.sleep(wait)
return call_with_retry(url, headers, attempt + 1, max_attempts)
if 500 <= response.status_code < 600 and attempt < max_attempts:
wait = (2 ** attempt) + random.uniform(0, 1)
time.sleep(wait)
return call_with_retry(url, headers, attempt + 1, max_attempts)
return response
Common 422 errors
A few validation failures show up often enough to be worth calling out:
urlfield required - The Create monitor endpoint needs a full URL including the scheme (https://orhttp://). Bare hostnames are rejected.intervalis invalid for your current plan - 30-second intervals are available on every paid plan, but free trials are capped to a higher interval. Either upgrade or pick a value from the valid list.notification_thresholdnot allowed on this check - Only uptime checks acceptnotification_threshold. Certificate health checks ignore it.
When in doubt
Always inspect the message and errors fields before retrying. Most 4xx errors come with a specific reason that tells you exactly what to fix. If you hit something opaque or unexpected, send the full response (with your token redacted) to support@pingping.io.