API Authentication
Authentication Methods
1. WordPress Nonce (Same-Origin)
For requests from the WordPress frontend (React app):
// WordPress provides the nonce automatically
const response = await fetch('/wp-json/ec/v1/cart', {
headers: {
'X-WP-Nonce': window.wpApiSettings?.nonce,
'Content-Type': 'application/json',
},
});
The nonce is available through wp_localize_script():
wp_localize_script('my-script', 'wpApiSettings', [
'nonce' => wp_create_nonce('wp_rest'),
'root' => esc_url_raw(rest_url()),
]);
2. Cookie Authentication
WordPress cookie authentication works automatically for logged-in users when the request includes the nonce.
3. Application Passwords (External)
For external applications (mobile apps, integrations):
- Go to Users → Your Profile → Application Passwords
- Create a new application password
- Use it with Basic Auth:
curl -u "admin:xxxx xxxx xxxx xxxx" \
https://your-site.com/wp-json/ec/v1/orders
const credentials = btoa('admin:xxxx xxxx xxxx xxxx');
fetch('https://your-site.com/wp-json/ec/v1/orders', {
headers: {
'Authorization': `Basic ${credentials}`,
},
});
Permission Levels
| Endpoint | Required Permission |
|---|---|
GET /products | Public (no auth) |
GET /categories | Public (no auth) |
*/cart/* | Session-based (any visitor) |
GET /orders/my | Logged-in customer |
POST /products | Admin (manage_options) |
*/orders/* (admin) | Admin (manage_options) |
*/settings/* | Admin (manage_options) |
Error Responses
401 Unauthorized
{
"code": "rest_not_logged_in",
"message": "You are not currently logged in.",
"data": { "status": 401 }
}
403 Forbidden
{
"code": "rest_forbidden",
"message": "Sorry, you are not allowed to do that.",
"data": { "status": 403 }
}
CORS Configuration
For headless setups where the frontend is on a different domain:
// In your theme or plugin
add_filter('rest_pre_serve_request', function ($served, $result, $request) {
header('Access-Control-Allow-Origin: https://your-frontend.com');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-WP-Nonce, Authorization');
return $served;
}, 10, 3);