agentleFS
ehsanenalooehsanenaloo/wordpress-devkit/skills/wp-devkit-rest-api-development/SKILL.md

wp-devkit-rest-api-development

Skill0 starsChanged 34 days agoMITView on GitHub

Build, debug or review WordPress REST routes, argument schemas, authentication, object permissions, responses and pagination. Use for 401/403/400 responses, nonce or Application Password problems, missing permission_callback, collections and caching; not admin screens.

The file

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 4 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read references/engineering-contract.md first.

    line 8
  2. Distinctive:

    Write the expected method, object scope, inputs, response shape and error behavior from the existing contract.

    line 23
  3. Distinctive:

    Check object-level authorization for reads and writes, including every identifier in the payload.

    line 24
  4. Very specific:

    Check validation at the real boundary: a custom sanitize_callback replaces implicit schema validation.

    line 25
  5. Very specific:

    Check responses: whitelisted fields, correct context, WP_Error with status, pagination bounds and headers, and cache headers for private …

    line 26
  6. Very specific:

    Read references/rest-api-development-workbook.md for symptom triage, worked decisions, benign look-alikes and verification recipes.

    line 30
  7. Distinctive:

    Write the failing test first (anonymous, wrong-role, wrong-owner, malformed, boundary), then the fix.

    line 41
  8. Very specific:

    Run only the relevant group from the first-party root.

    line 46
  9. Distinctive:

    Read the match context; confirm reachability and what core already enforces before reporting.

    line 63

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

REST contracts and request boundaries

Read references/engineering-contract.md first. Review requests stay read-only: assess, explain and recommend without edits, mutations or untrusted runtime execution. Use the implementation path only when the request authorizes changes.

Inputs and scope

Namespace and route, HTTP method, caller identity and authentication model (cookie, Application Password, custom token, webhook), request/response example, target WordPress version, protected-object policy, consumers (block editor, theme JS, mobile, partner), CDN/page-cache in front of /wp-json/.

Inspect project evidence before asking. State material assumptions. Ask only what changes the decision or execution boundary. Follow the existing public contract: route names, fields, status codes and error code strings are API.

Boundaries with sibling skills

Plugin bootstrap, hooks and storage go to wp-devkit-plugin-development; the admin screens that call the API go to wp-devkit-admin-ui-development; WPGraphQL and decoupled front ends go to wp-devkit-headless-and-wpgraphql; broad exploit analysis goes to wp-devkit-security-review. This skill owns the request boundary: routes, auth, validation, response and cache behavior.

Code Review Workflow

  1. Find registration (register_rest_route, controller register_routes, register_rest_field, register_meta with show_in_rest) and trace in dispatch order: authentication, route match, required/validate_callback checks, sanitization, permission_callback, handler, response conversion (confirmed in WP_REST_Server::dispatch() and respond_to_request()).
  2. Write the expected method, object scope, inputs, response shape and error behavior from the existing contract. Do not add a new endpoint to bypass a failing one.
  3. Check object-level authorization for reads and writes, including every identifier in the payload. Intentional public submissions can be valid; assess data exposure, side effects and abuse controls rather than demanding authentication.
  4. Check validation at the real boundary: a custom sanitize_callback replaces implicit schema validation; parameters resolve body-first; confirm the permission callback and handler read the same identifier.
  5. Check responses: whitelisted fields, correct context, WP_Error with status, pagination bounds and headers, and cache headers for private data.
  6. Describe anonymous, authorized, wrong-owner and malformed-input checks. Do not issue mutating requests during review.
  7. Classify per the contract; keep pattern hits as candidates; use insufficient evidence when the auth model, version or CDN rules are unknown.

Read references/rest-api-development-workbook.md for symptom triage, worked decisions, benign look-alikes and verification recipes. Load topic references only when in scope:

  • references/route-registration-and-schema.md: read for registration rules, controllers, how core validates args, schema keywords and coercion, fields/meta, versioning.
  • references/authentication-and-permissions.md: read for cookie nonces, Application Passwords, 401 vs 403, object checks, public routes, CORS, abuse controls.
  • references/responses-collections-and-caching.md: read for errors and statuses, pagination, _fields/_embed, caching and CDN, idempotency, retries.

Implementation workflow

  1. State the contract (method, URL, auth, schema, errors) and affected boundary before editing.
  2. Register on rest_api_init with an explicit permission_callback (a deliberate __return_true for public data), schema-typed args with validate_callback => rest_validate_request_arg whenever a custom sanitizer is used, and WP_Error with status.
  3. Authorize the object, not only the role. Read the identifier one way.
  4. Write the failing test first (anonymous, wrong-role, wrong-owner, malformed, boundary), then the fix; re-read the object after denied calls.
  5. Report unavailable checks as unexecuted. Deployment, CDN rules and live data changes need their own scope.

Search Patterns for Quick Detection

Run only the relevant group from the first-party root; narrow .. Commands read files and never load WordPress. Hits are leads, not findings; no hit proves nothing (helpers, controllers and multiline arrays hide matches). Exit 0 match, 1 none, 2 error.

# Registration and controllers
rg -n -g '*.php' -g '!**/{vendor,node_modules,build,dist,coverage,backups}/**' -e 'register_rest_route|rest_api_init|extends\s+WP_REST_Controller|register_rest_field|show_in_rest' .
# Permission and object policy (read the callbacks; __return_true can be deliberate)
rg -n -g '*.php' -g '!**/{vendor,node_modules,build,dist,coverage,backups}/**' -e 'permission_callback|__return_true|current_user_can|map_meta_cap|get_current_user_id' .
# Arguments and schema
rg -n -g '*.php' -g '!**/{vendor,node_modules,build,dist,coverage,backups}/**' -e "validate_callback|sanitize_callback|'enum'|'required'|get_param|get_json_params|get_url_params|\\\$_(GET|POST|REQUEST)" .
# Authentication and browser intent
rg -n -g '*.{php,js,jsx,ts,tsx}' -g '!**/{vendor,node_modules,build,dist,coverage,backups}/**' -e 'X-WP-Nonce|wp_rest|apiFetch|Authorization|rest_authentication_errors|rest_cookie' .
# Responses and errors
rg -n -g '*.php' -g '!**/{vendor,node_modules,build,dist,coverage,backups}/**' -e 'WP_REST_Response|WP_Error|rest_ensure_response|wp_send_json|\bdie\(|\bexit\(|Cache-Control' .
# Collections and write effects
rg -n -g '*.php' -g '!**/{vendor,node_modules,build,dist,coverage,backups}/**' -e 'per_page|posts_per_page|orderby|wp_insert_post|wp_update_post|wp_delete_post|update_(post|user)_meta' .

Read the match context; confirm reachability and what core already enforces before reporting.

Acceptance checks

For each changed route: anonymous, subscriber, correct owner, other owner, admin; malformed JSON; missing, wrong-type, boundary and unknown-object inputs; per_page over the cap; repeat of a write. Assert status, structured body, stored state after denied calls, and Cache-Control for private responses. Commands: PHPUnit via rest_do_request(), curl -i against a disposable site, Playwright request fixtures, PHPCS and PHPStan. A pass shows tested actors and inputs behave on the tested versions; it does not prove untested roles, multisite, CDN or object-cache behavior.

Output Format

Review: result and reviewed scope first. Each confirmed finding: file:line, actor, trigger, reachable path, impact, confidence, severity (per contract), minimal fix, regression. Candidates and missing evidence separate. Implementation: contract, changed boundaries, commands with exit status, unexecuted checks, residual risk.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.