{"slug":"wordpress-rest-api","title":"WordPress REST API","tags":["rest-api","json","authentication","headless","javascript"],"agent_summary":"WordPress REST API endpoints, authentication methods (Application Passwords, JWT), custom endpoint registration in PHP, JavaScript fetch examples, and how to restrict REST API access to logged-in users.","trigger_phrases":["wordpress rest api","wp rest api","wp-json","application passwords wordpress","custom rest endpoint wordpress","headless wordpress","wordpress api authentication"],"runnable":true,"markdown":"\nThe WordPress REST API provides programmatic access over HTTP. Base: `https://site.com/wp-json/wp/v2/`\n\n## Core Endpoints\n\n| Resource | Method | Endpoint |\n|----------|--------|----------|\n| Posts | GET | /wp/v2/posts |\n| Single Post | GET | /wp/v2/posts/{id} |\n| Create Post | POST | /wp/v2/posts |\n| Pages | GET | /wp/v2/pages |\n| Users | GET | /wp/v2/users |\n| Categories | GET | /wp/v2/categories |\n| Media | GET | /wp/v2/media |\n| Custom Post Type | GET | /wp/v2/{cpt-slug} |\n\n## Authentication\n\n```bash\n# Application Passwords (WP 5.6+ — preferred for server-to-server)\n# Generate at: Users > Profile > Application Passwords\ncurl -H \"Authorization: Basic $(echo -n 'admin:XXXX XXXX XXXX XXXX XXXX XXXX' | base64)\" \\\n  https://site.com/wp-json/wp/v2/posts\n\n# JWT Auth (requires JWT Authentication plugin)\n# Get token\ncurl -X POST https://site.com/wp-json/jwt-auth/v1/token \\\n  -d \"username=admin&password=pass\"\n# Use token\ncurl -H \"Authorization: Bearer YOUR_JWT_TOKEN\" https://site.com/wp-json/wp/v2/posts\n```\n\n## Custom REST Endpoint (PHP)\n\n```php\nadd_action('rest_api_init', function() {\n    register_rest_route('myplugin/v1', '/leads', [\n        'methods'             => 'POST',\n        'callback'            => 'handle_lead_submission',\n        'permission_callback' => '__return_true',\n    ]);\n});\n\nfunction handle_lead_submission(WP_REST_Request $request) {\n    $name  = sanitize_text_field($request->get_param('name'));\n    $email = sanitize_email($request->get_param('email'));\n    // Save, send notification, etc.\n    return new WP_REST_Response(['status' => 'success'], 200);\n}\n```\n\n## Fetch Posts via JavaScript\n\n```javascript\nconst response = await fetch('/wp-json/wp/v2/posts?per_page=10&_embed');\nconst posts = await response.json();\n\nposts.forEach(post => {\n    console.log(post.title.rendered);\n    console.log(post._embedded['wp:featuredmedia']?.[0]?.source_url);\n});\n```\n\n## Restrict REST API to Logged-In Users\n\n```php\n// In functions.php — blocks unauthenticated REST requests\nadd_filter('rest_authentication_errors', function($result) {\n    if (!is_user_logged_in()) {\n        return new WP_Error(\n            'rest_not_logged_in',\n            'REST API restricted to authenticated users.',\n            ['status' => 401]\n        );\n    }\n    return $result;\n});\n```\n\n## Common Query Parameters\n\n| Parameter | Description | Example |\n|-----------|-------------|---------|\n| `per_page` | Results per page (max 100) | `?per_page=20` |\n| `page` | Pagination | `?page=2` |\n| `search` | Full-text search | `?search=keyword` |\n| `categories` | Filter by category ID | `?categories=5,8` |\n| `_embed` | Include embedded data (author, featured image) | `?_embed` |\n| `orderby` | Sort field | `?orderby=date` |\n| `order` | Sort direction | `?order=asc` |\n","html":"<p>The WordPress REST API provides programmatic access over HTTP. Base: <code>https://site.com/wp-json/wp/v2/</code></p>\n<h2>Core Endpoints</h2>\n<p>| Resource | Method | Endpoint |\n|----------|--------|----------|\n| Posts | GET | /wp/v2/posts |\n| Single Post | GET | /wp/v2/posts/{id} |\n| Create Post | POST | /wp/v2/posts |\n| Pages | GET | /wp/v2/pages |\n| Users | GET | /wp/v2/users |\n| Categories | GET | /wp/v2/categories |\n| Media | GET | /wp/v2/media |\n| Custom Post Type | GET | /wp/v2/{cpt-slug} |</p>\n<h2>Authentication</h2>\n<pre><code class=\"language-bash\"># Application Passwords (WP 5.6+ — preferred for server-to-server)\n# Generate at: Users > Profile > Application Passwords\ncurl -H \"Authorization: Basic $(echo -n 'admin:XXXX XXXX XXXX XXXX XXXX XXXX' | base64)\" \\\n  https://site.com/wp-json/wp/v2/posts\n\n# JWT Auth (requires JWT Authentication plugin)\n# Get token\ncurl -X POST https://site.com/wp-json/jwt-auth/v1/token \\\n  -d \"username=admin&#x26;password=pass\"\n# Use token\ncurl -H \"Authorization: Bearer YOUR_JWT_TOKEN\" https://site.com/wp-json/wp/v2/posts\n</code></pre>\n<h2>Custom REST Endpoint (PHP)</h2>\n<pre><code class=\"language-php\">add_action('rest_api_init', function() {\n    register_rest_route('myplugin/v1', '/leads', [\n        'methods'             => 'POST',\n        'callback'            => 'handle_lead_submission',\n        'permission_callback' => '__return_true',\n    ]);\n});\n\nfunction handle_lead_submission(WP_REST_Request $request) {\n    $name  = sanitize_text_field($request->get_param('name'));\n    $email = sanitize_email($request->get_param('email'));\n    // Save, send notification, etc.\n    return new WP_REST_Response(['status' => 'success'], 200);\n}\n</code></pre>\n<h2>Fetch Posts via JavaScript</h2>\n<pre><code class=\"language-javascript\">const response = await fetch('/wp-json/wp/v2/posts?per_page=10&#x26;_embed');\nconst posts = await response.json();\n\nposts.forEach(post => {\n    console.log(post.title.rendered);\n    console.log(post._embedded['wp:featuredmedia']?.[0]?.source_url);\n});\n</code></pre>\n<h2>Restrict REST API to Logged-In Users</h2>\n<pre><code class=\"language-php\">// In functions.php — blocks unauthenticated REST requests\nadd_filter('rest_authentication_errors', function($result) {\n    if (!is_user_logged_in()) {\n        return new WP_Error(\n            'rest_not_logged_in',\n            'REST API restricted to authenticated users.',\n            ['status' => 401]\n        );\n    }\n    return $result;\n});\n</code></pre>\n<h2>Common Query Parameters</h2>\n<p>| Parameter | Description | Example |\n|-----------|-------------|---------|\n| <code>per_page</code> | Results per page (max 100) | <code>?per_page=20</code> |\n| <code>page</code> | Pagination | <code>?page=2</code> |\n| <code>search</code> | Full-text search | <code>?search=keyword</code> |\n| <code>categories</code> | Filter by category ID | <code>?categories=5,8</code> |\n| <code>_embed</code> | Include embedded data (author, featured image) | <code>?_embed</code> |\n| <code>orderby</code> | Sort field | <code>?orderby=date</code> |\n| <code>order</code> | Sort direction | <code>?order=asc</code> |</p>\n"}