agentskills.codes
SU

superpowers-sage:wp-rest-api

>

Install

mkdir -p .claude/skills/superpowers-sage-wp-rest-api && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16234" && unzip -o skill.zip -d .claude/skills/superpowers-sage-wp-rest-api && rm skill.zip

Installs to .claude/skills/superpowers-sage-wp-rest-api

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

WordPress REST API — register_rest_route, WP_REST_Controller, WP_REST_Request, REST namespace, custom endpoints, Application Passwords, JWT REST authentication, permission_callback, schema validation, WP_REST_Response, REST API versioning, rest_ensure_response, coexistence with Acorn Routes, register_rest_route vs routes/web.php decision, REST API debugging, wp rest-api namespace list, wp json discovery, CORS, REST nonce, cookie auth, REST API disable, JSON schema validation
479 charsno explicit “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)

About this skill

WordPress REST API Patterns

When to use

Use this skill when the task involves creating, modifying, or debugging WordPress REST API endpoints, or when deciding between native REST and Acorn Routes for an API surface.

Inputs required

  • The API requirements: what data to expose, who consumes it, and authentication needs
  • Whether the project already uses Acorn Routes (check routes/web.php or routes/api.php)
  • The target consumers: Gutenberg editor, mobile apps, third-party integrations, or internal front-end

Procedure

Step 1 — Choose between Native REST and Acorn Routes

See references/acorn-coexistence.md for the full decision matrix.

Quick rule: use native REST for WordPress-ecosystem integration and Acorn Routes for application logic. Both can coexist in the same project.

Step 2 — Register native REST endpoints

Always use register_rest_route() inside a rest_api_init action. Never omit permission_callback.

See references/custom-endpoints.md for full examples including WP_REST_Controller pattern and JSON schema validation.

public function boot(): void
{
    add_action('rest_api_init', [$this, 'registerRoutes']);
}

public function registerRoutes(): void
{
    register_rest_route('myapp/v1', '/posts', [
        'methods'             => 'GET',
        'callback'            => [$this, 'getPosts'],
        'permission_callback' => '__return_true',
    ]);

    register_rest_route('myapp/v1', '/posts', [
        'methods'             => 'POST',
        'callback'            => [$this, 'createPost'],
        'permission_callback' => fn() => current_user_can('edit_posts'),
        'args'                => $this->getCreatePostArgs(),
    ]);
}

Step 3 — Authentication

See references/authentication.md for Application Passwords, cookie/nonce auth, and JWT patterns.

Quick reference:

  • Same-origin JS: Cookie + X-WP-Nonce header
  • External app / mobile: Application Passwords (Basic Auth)
  • Internal Acorn routes: JWT middleware with wp_set_current_user()

Step 4 — Expose custom fields and CPTs

// Expose a CPT in the REST API
register_post_type('event', [
    'show_in_rest' => true,
    'rest_base'    => 'events',
]);

// Register a custom field on an existing endpoint
add_action('rest_api_init', function () {
    register_rest_field('post', 'reading_time', [
        'get_callback' => fn($post) => (int) get_post_meta($post['id'], '_reading_time', true),
        'schema'       => ['type' => 'integer', 'description' => 'Reading time in minutes'],
    ]);
});

Step 5 — Avoid anti-patterns

Anti-patternProblemCorrect approach
Closure in route callbackCannot be cached; breaks serializationUse class method reference [$this, 'method']
Missing permission_callbackEmits _doing_it_wrong; endpoint unprotectedAlways include permission_callback
Returning raw arraysMissing REST response headersUse rest_ensure_response()
Hardcoded namespace versionVersion changes require find-and-replaceDefine as class constants
No schema definitionClients cannot discover endpoint shapeDefine get_item_schema() on the controller
Duplicating endpoint in both systemsConfusing and harder to maintainOne canonical endpoint per resource

Verification

  • Every register_rest_route() call includes a permission_callback
  • Argument schemas define type, required, and sanitize_callback where applicable
  • CPTs that need REST access have show_in_rest => true
  • Authentication method matches the consumer
  • Pagination headers (X-WP-Total, X-WP-TotalPages) are set on collection endpoints
  • No closures used as route callbacks
  • No direct database queries in callbacks — logic is in Service classes
  • Native REST and Acorn Routes do not duplicate the same resource

Failure modes

See references/troubleshooting.md for detailed diagnosis of 401, CORS, rest_no_route, schema validation failures, and 404 on custom namespace.

Quick reference:

SymptomCauseFix
404 on REST endpointMissing rest_api_init hook or permalink flush neededFlush permalinks: lando wp rewrite flush
rest_no_route errorTypo in namespace or route pathCheck namespace and path match
401 on authenticated endpointNonce not sent or expiredSend X-WP-Nonce header
CPT not in /wp/v2/show_in_rest not setAdd 'show_in_rest' => true

Escalation

  • If the REST API is entirely disabled (by a security plugin or custom code), check for rest_authentication_errors filters or rest_enabled overrides.
  • If performance is critical (hundreds of requests per second), recommend a dedicated caching layer (Varnish, Cloudflare) rather than transient-based caching.
  • If the API must serve a mobile app with offline support, recommend evaluating a dedicated API framework or GraphQL layer beyond the scope of this skill.

Search skills

Search the agent skills registry