Use when building, extending, or debugging WordPress REST API endpoints/routes: register_rest_route, WP_REST_Controller/controller classes, schema/argument validation, permission_callback/authentication, response shaping, register_rest_field/register_meta, or exposing CPTs/taxonomies via show_in_rest.
Add this skill
npx mdskills install WordPress/wp-rest-apiClear workflow for REST endpoints with good triage, validation, and auth coverage
1---2name: wp-rest-api3description: "Use when building, extending, or debugging WordPress REST API endpoints/routes: register_rest_route, WP_REST_Controller/controller classes, schema/argument validation, permission_callback/authentication, response shaping, register_rest_field/register_meta, or exposing CPTs/taxonomies via show_in_rest."4compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Filesystem-based agent with bash + node. Some workflows require WP-CLI."5---67# WP REST API89## When to use1011Use this skill when you need to:1213- create or update REST routes/endpoints14- debug 401/403/404 errors or permission/nonce issues15- add custom fields/meta to REST responses16- expose custom post types or taxonomies via REST17- implement schema + argument validation18- adjust response links/embedding/pagination1920## Inputs required2122- Repo root + target plugin/theme/mu-plugin (path to entrypoint).23- Desired namespace + version (e.g. `my-plugin/v1`) and routes.24- Authentication mode (cookie + nonce vs application passwords vs auth plugin).25- Target WordPress version constraints (if below 6.9, call out).2627## Procedure2829### 0) Triage and locate REST usage30311. Run triage:32 - `node skills/wp-project-triage/scripts/detect_wp_project.mjs`332. Search for existing REST usage:34 - `register_rest_route`35 - `WP_REST_Controller`36 - `rest_api_init`37 - `show_in_rest`, `rest_base`, `rest_controller_class`3839If this is a full site repo, pick the specific plugin/theme before changing code.4041### 1) Choose the right approach4243- **Expose CPT/taxonomy in `wp/v2`:**44 - Use `show_in_rest => true` + `rest_base` if needed.45 - Optionally provide `rest_controller_class`.46 - Read `references/custom-content-types.md`.47- **Custom endpoints:**48 - Use `register_rest_route()` on `rest_api_init`.49 - Prefer a controller class (`WP_REST_Controller` subclass) for anything non-trivial.50 - Read `references/routes-and-endpoints.md` and `references/schema.md`.5152### 2) Register routes safely (namespaces, methods, permissions)5354- Use a unique namespace `vendor/v1`; avoid `wp/*` unless core.55- Always provide `permission_callback` (use `__return_true` for public endpoints).56- Use `WP_REST_Server::READABLE/CREATABLE/EDITABLE/DELETABLE` constants.57- Return data via `rest_ensure_response()` or `WP_REST_Response`.58- Return errors via `WP_Error` with an explicit `status`.5960Read `references/routes-and-endpoints.md`.6162### 3) Validate/sanitize request args6364- Define `args` with `type`, `default`, `required`, `validate_callback`, `sanitize_callback`.65- Prefer JSON Schema validation with `rest_validate_value_from_schema` then `rest_sanitize_value_from_schema`.66- Never read `$_GET`/`$_POST` directly inside endpoints; use `WP_REST_Request`.6768Read `references/schema.md`.6970### 4) Responses, fields, and links7172- Do **not** remove core fields from default endpoints; add fields instead.73- Use `register_rest_field` for computed fields; `register_meta` with `show_in_rest` for meta.74- For `object`/`array` meta, define schema in `show_in_rest.schema`.75- If you need unfiltered post content (e.g., ToC plugins injecting HTML), request `?context=edit` to access `content.raw` (auth required). Pair with `_fields=content.raw` to keep responses small.76- Add related resource links via `WP_REST_Response::add_link()`.7778Read `references/responses-and-fields.md`.7980### 5) Authentication and authorization8182- For wp-admin/JS: cookie auth + `X-WP-Nonce` (action `wp_rest`).83- For external clients: application passwords (basic auth) or an auth plugin.84- Use capability checks in `permission_callback` (authorization), not just “logged in”.8586Read `references/authentication.md`.8788### 6) Client-facing behavior (discovery, pagination, embeds)8990- Ensure discovery works (`Link` header or `<link rel="https://api.w.org/">`).91- Support `_fields`, `_embed`, `_method`, `_envelope`, pagination headers.92- Remember `per_page` is capped at 100.9394Read `references/discovery-and-params.md`.9596## Verification9798- `/wp-json/` index includes your namespace.99- `OPTIONS` on your route returns schema (when provided).100- Endpoint returns expected data; permission failures return 401/403 as appropriate.101- CPT/taxonomy routes appear under `wp/v2` when `show_in_rest` is true.102- Run repo lint/tests and any PHP/JS build steps.103104## Failure modes / debugging105106- 404: `rest_api_init` not firing, route typo, or permalinks off (use `?rest_route=`).107- 401/403: missing nonce/auth, or `permission_callback` too strict.108- `_doing_it_wrong` for missing `permission_callback`: add it (use `__return_true` if public).109- Invalid params: missing/incorrect `args` schema or validation callbacks.110- Fields missing: `show_in_rest` false, meta not registered, or CPT lacks `custom-fields` support.111112## Escalation113114If version support or behavior is unclear, consult the REST API Handbook and core docs before inventing patterns.115
Full transparency — inspect the skill content before installing.