Skip to content

Errors, limits, and rate limiting ​

Pro

Error responses ​

Errors are deliberately generic. They never include configuration, SQL, file paths or internal details.

StatusBody
Most errors{ "code": "…", "message": "…" }
422 validationthe error, plus a list of { path, message } for each field (see Writing values)
429 throttled{ "code": "too_many_requests", "message": "…" }, with a Retry-After header when set

Limits ​

  • Collections return at most 100 items per page.
  • A relation includes at most 100 linked entries, and linked entries' own fields go 2 levels deep.
  • Responses are cached per access tier for up to 5 minutes, and cleared as soon as content or exposure settings change.

Rate limiting ​

WordPress has no built-in rate limiting, and VX doesn't add one, because doing it properly needs a shared store (such as Redis) or your host's edge. Limit REST traffic at the layer your hosting provides:

  • CDN or firewall (for example Cloudflare): a rate-limiting rule on paths containing /wp-json/. This is usually the simplest and sturdiest option.

  • nginx:

    nginx
    limit_req_zone $binary_remote_addr zone=wp_rest:10m rate=10r/s;
    location /wp-json/ {
        limit_req zone=wp_rest burst=20 nodelay;
        try_files $uri $uri/ /index.php?$args;
    }
  • Apache: mod_ratelimit, mod_qos, or ModSecurity rules scoped to /wp-json/.

To make the decision in PHP instead, for example with per-user budgets stored in Redis, use the vxframework/rest/throttle filter. It runs before any REST route, so a refusal short-circuits the request:

php
add_filter( 'vxframework/rest/throttle', function ( $decision, array $context ) {
    if ( my_limiter_is_over_budget( $context['ip'], $context['route'] ) ) {
        return 60; // 429 with Retry-After: 60
    }
    return $decision;
}, 10, 2 );

Warning

$context['ip'] is the connecting address (REMOTE_ADDR). Behind a proxy or CDN, that's the proxy. Headers like X-Forwarded-For can be forged by clients, so resolve the real address inside your limiter only if you trust the proxy.

Technical details for LLMs
  • vxframework/rest/throttle ( $decision, array $context ) on rest_pre_dispatch; context keys route, method, viewer_id, is_logged_in, ip. Return null (allow), true (429), int > 0 (429 + Retry-After), or a WP_Error / WP_REST_Response returned verbatim.
  • Caps: vxframework/rest/max_per_page (default 100); relation depth 2, 100 refs (fixed). Cache TTL 300 s.

Documentation for the VX Framework.