agentsclimarketplace

Wp rest api

Skill ComeOnOliver/skillshub/skills/alessioarzenton/claude-code-wp-toolkit/wp-rest-api

🧠 The right skill, one API call. AI agent skills registry with token-efficient skill resolution. 5,000+ skills from 500+ top repos.

Install
npx -y skills add ComeOnOliver/skillshub --skill wp-rest-api

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

WordPress REST endpoint development and debugging. Always-active rules when working with REST routes, API authentication, or data exposure via JSON.

SKILL.md

8.1 KB, as published. Nobody here has run it

WordPress REST API

Skill for creating, managing, and debugging REST endpoints in WordPress 6.x+. Covers route registration, authentication, input validation, security, and integration with CPTs/taxonomies.

When to use

Apply this skill when the task involves:

  • Creating or modifying custom REST routes and endpoints
  • Exposing Custom Post Types or taxonomies via REST
  • Resolving authentication/authorization errors (401, 403, 404)
  • Adding custom fields to REST responses
  • Defining validation rules and JSON schemas
  • Customizing response structure, pagination, links

Prerequisites

Before starting, verify:

  • Path of the plugin/theme/mu-plugin where routes will be registered
  • Desired namespace and version (e.g., {{TEXT_DOMAIN}}/v1)
  • Authentication strategy (cookie+nonce for admin, application passwords for external clients)
  • Minimum WordPress version of the project

Procedure

1) Detecting existing implementations

Before creating new endpoints, search the codebase:

register_rest_route    β†’ custom routes already registered
WP_REST_Controller     β†’ extended controllers
rest_api_init          β†’ registration hooks
show_in_rest           β†’ exposed CPTs/taxonomies
register_rest_field    β†’ custom fields added

Check for namespace conflicts and registration patterns already in use.

2) Choosing the approach

ScenarioApproach
Expose a CPT or taxonomy'show_in_rest' => true in the CPT registration
Add fields to existing endpointsregister_rest_field() or register_meta() with show_in_rest
Custom logic (calculations, aggregations, actions)register_rest_route() with a dedicated handler
Full CRUD endpointExtend WP_REST_Controller

3) Secure endpoint registration

Mandatory rules:

add_action('rest_api_init', function () {
    register_rest_route('{{TEXT_DOMAIN}}/v1', '/items', [
        'methods'             => WP_REST_Server::READABLE,  // Use constants, not strings
        'callback'            => 'handle_get_items',
        'permission_callback' => 'check_items_permission',  // MANDATORY β€” never '__return_true' in production if data is sensitive
        'args'                => get_items_args_schema(),
    ]);
});
  • Unique namespace: {{TEXT_DOMAIN}}/v1 β€” never register under wp/v2
  • permission_callback always present: WordPress 5.5+ logs a _doing_it_wrong if missing
  • HTTP constants: WP_REST_Server::READABLE, ::CREATABLE, ::EDITABLE, ::DELETABLE
  • Response: always return rest_ensure_response() or new WP_REST_Response($data, $status)

4) Argument validation and sanitization

Define the schema for every argument β€” never access $_GET/$_POST directly:

function get_items_args_schema(): array {
    return [
        'per_page' => [
            'type'              => 'integer',
            'default'           => 10,
            'minimum'           => 1,
            'maximum'           => 100,
            'sanitize_callback' => 'absint',
            'validate_callback' => 'rest_validate_request_arg',
        ],
        'search' => [
            'type'              => 'string',
            'sanitize_callback' => 'sanitize_text_field',
        ],
        'status' => [
            'type'              => 'string',
            'enum'              => ['aperto', 'chiuso', 'in_arrivo'],
            'default'           => 'aperto',
        ],
    ];
}
  • Use JSON Schema type: string, integer, boolean, array, object
  • Add enum for allowed values, minimum/maximum for ranges
  • sanitize_callback cleans the data, validate_callback rejects it if invalid

5) Adding custom fields to responses

For ACF/post meta metadata β€” expose via register_meta():

register_meta('post', 'importo_bando', [
    'object_subtype' => 'bando',
    'type'           => 'number',
    'single'         => true,
    'show_in_rest'   => true,
    'auth_callback'  => function () {
        return current_user_can('edit_posts');
    },
]);

For computed values β€” use register_rest_field():

register_rest_field('bando', 'stato_calcolato', [
    'get_callback' => function ($object) {
        return calcola_stato_bando($object['id']);
    },
    'schema' => [
        'type'        => 'string',
        'description' => 'Automatically calculated bando status',
        'context'     => ['view', 'edit'],
    ],
]);
  • Extend existing responses, do not remove fields
  • Set context to control where the field appears (view, edit, embed)

6) Authentication and authorization

ContextMethodNotes
JavaScript in wp-adminCookie + X-WP-Noncewp_create_nonce('wp_rest') β€” automatic with wp.apiFetch
External apps / CIApplication PasswordsDedicated WP user with minimal capabilities
Authentication pluginsJWT / OAuthUse established plugins, do not reinvent

permission_callback β€” always check capabilities, not roles:

function check_items_permission(WP_REST_Request $request): bool|WP_Error {
    if (!current_user_can('edit_posts')) {
        return new WP_Error(
            'rest_forbidden',
            __('Permesso negato.', '{{TEXT_DOMAIN}}'),
            ['status' => 403]
        );
    }
    return true;
}
  • Public endpoints (reading bandi, FAQ): 'permission_callback' => '__return_true'
  • Write endpoints: always capability check
  • Never trust the user role alone β€” use current_user_can()

7) Client experience

  • Discovery: your endpoints appear in /wp-json/{{TEXT_DOMAIN}}/v1
  • Field filtering: support ?_fields=id,title,stato to reduce payload
  • Embed: support ?_embed to include related resources inline
  • Pagination: respect X-WP-Total, X-WP-TotalPages headers; maximum 100 per page
  • Cache: add Cache-Control headers for high-traffic public endpoints

Verification checklist

  • The REST index (/wp-json/) shows your namespace
  • OPTIONS on routes returns the schema
  • Responses follow the expected format (data, HTTP codes, headers)
  • Unauthenticated requests return 401 on protected endpoints
  • Requests from users without permissions return 403
  • Invalid parameters return 400 with a clear message
  • CPTs with show_in_rest appear under wp/v2
  • The project build succeeds after changes

Common errors and solutions

ProblemLikely causeSolution
404 on the endpointrest_api_init hook not executed, wrong route name, permalinks not enabledVerify the code is loaded; enable pretty permalinks; check the namespace
401 / Cookie nonce mismatchNonce missing or expired in the JS requestUse wp.apiFetch which handles the nonce automatically, or pass X-WP-Nonce in the header
403 Forbiddenpermission_callback rejects; user without capabilityVerify the required capability and user role
Custom field missingshow_in_rest not set, register_meta without object_subtypeAdd show_in_rest => true and specify the subtype
Schema not validatedvalidate_callback not defined or not usedUse rest_validate_request_arg as callback
Corrupted serialized dataregister_meta of type array/object without show_in_rest.schemaDefine the full schema in show_in_rest['schema']

What NOT to do

  • Do not register routes under the wp/v2 namespace β€” it is reserved for core
  • Do not access $_GET, $_POST, $_REQUEST β€” use $request->get_param() or $request->get_json_params()
  • Do not return echo/die() β€” always return a WP_REST_Response or WP_Error object
  • Do not omit permission_callback β€” even if the endpoint is public, use '__return_true'
  • Do not build SQL manually β€” use $wpdb->prepare() if you need direct queries
  • Do not expose sensitive data (user emails, password hashes) without authorization checks

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.