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

CodeMeaningWhen you see it
200OKSuccessful read or update.
201CreatedSuccessful resource creation.
204No ContentSuccessful delete. Empty body.
400Bad RequestMalformed JSON or missing required headers.
401UnauthorizedMissing, invalid, or deactivated API token. See Authentication.
403ForbiddenAuthenticated, but the token does not have access to that resource (typically a monitor on a different account).
404Not FoundResource id does not exist on this account.
422Unprocessable EntityRequest was understood, but validation failed. The errors object names the offending fields.
429Too Many RequestsRate limit exceeded. See below.
500Internal Server ErrorSomething on our side. We log and alert on these - if you see a sustained pattern, contact support.
503Service UnavailableBrief 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
  • 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:

  • url field required - The Create monitor endpoint needs a full URL including the scheme (https:// or http://). Bare hostnames are rejected.
  • interval is 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_threshold not allowed on this check - Only uptime checks accept notification_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.