Add reward points to users via a secure REST endpoint exposed by the plugin.
What does this API do?
It exposes a REST endpoint that adds reward points to a WooCommerce user and returns the user’s new total.
Internally it reuses the plugin’s manually_add_user_points() logic so totals, logs, and hooks behave like a manual admin add.
What is the endpoint?
- Method: POST
- Route: /wp-json/wc-reward-points/v1/add-points
What permissions are required?
Only authenticated users who can manage_woocommerce may call this endpoint (typically Administrators or Shop Managers). Unauthorized requests are rejected.
What request parameters are required?
All parameters are required and validated on the server:
| Field | Type | Rules | Purpose |
|---|---|---|---|
user_id |
integer | Must exist in WordPress | Which user to credit |
points |
integer | Must be a positive integer (> 0) | How many points to add |
message |
string | Sanitized server-side (sanitize_text_field) |
Shown in the points log/note |
Example JSON body
{
"user_id": 123,
"points": 250,
"message": "Customer service gesture for delayed shipment"
}
What does a successful response look like?
{
"success": true,
"user_id": 123,
"points_added": 250,
"new_total": 1420,
"message": "Customer service gesture for delayed shipment"
}
Note: new_total is read from user meta after the add completes.
What errors might I see?
| HTTP | Code | When it happens |
|---|---|---|
| 400 | invalid_user |
user_id is missing/invalid or the user doesn’t exist |
| 400 | invalid_points |
points is <= 0 or missing |
| 401 | n/a | Not authenticated |
| 403 | n/a | Authenticated but lacks manage_woocommerce capability |
| 404 | n/a | Route not registered (plugin disabled or API not enabled) |
How do I authenticate?
- Application Passwords (recommended for server-to-server): WordPress 5.6+ → User Profile → Application Passwords → Create new. Use HTTP Basic Auth (
user:application-password). - Logged-in cookies + nonce (for in-dashboard calls from wp-admin).
- JWT/OAuth (via separate auth plugins) if your stack uses them.
cURL example (Application Passwords)
curl -X POST "https://example.com/wp-json/wc-reward-points/v1/add-points" \
-u "admin:YOUR-APP-PASSWORD" \
-H "Content-Type: application/json" \
-d '{"user_id":123,"points":250,"message":"Promo: Spring bonus"}'
Postman/Insomnia quick setup
- Method/URL: POST https://your-site/wp-json/wc-reward-points/v1/add-points
- Auth: Basic → username: your WP user, password: Application Password
- Headers:
Content-Type: application/json - Body (raw JSON): see example above
PHP example (server-side with Application Passwords)
<?php
$url = site_url('/wp-json/wc-reward-points/v1/add-points');
$resp = wp_remote_post($url, array(
'headers' => array(
'Authorization' => 'Basic ' . base64_encode('admin:YOUR-APP-PASSWORD'),
'Content-Type' => 'application/json',
),
'body' => wp_json_encode(array(
'user_id' => 123,
'points' => 100,
'message' => 'Welcome bonus',
)),
'timeout' => 20,
));
if (is_wp_error($resp)) {
error_log($resp->get_error_message());
} else {
$code = wp_remote_retrieve_response_code($resp);
$body = json_decode(wp_remote_retrieve_body($resp), true);
// Handle $code / $body
}
fetch('/wp-json/wc-reward-points/v1/add-points', {
method: 'POST',
credentials: 'include', // send auth cookies
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_id: 123, points: 50, message: 'Manual adjustment' })
}).then(r => r.json()).then(console.log);
current_user_can('manage_woocommerce')), so cookies + a logged-in admin session are sufficient for auth in this context.Does this work on multisite?
Yes. If both are true: WordPress is multisite and the plugin setting multisiteSplitPoints is enabled, points are stored under a site-specific meta key:
woocommerce_reward_points_<BLOG_ID>
Otherwise, the meta key is:
woocommerce_reward_points
This matters if you read totals directly from user meta elsewhere.
Why might the route be missing (404)?
- The plugin (or its API feature) is disabled.
- The plugin option
enableis false (routes register only when enabled). - Your caching layer blocks
/wp-jsonor POST requests. - A security/firewall plugin interferes with REST calls.
What happens internally when I call the API?
- Inputs are sanitized and validated.
- The code sets
$_POST['userId'],$_POST['points'],$_POST['text'], and$_POST['action']='woocommerce_reward_points_add_points'. - It initializes
WooCommerce_Reward_Points_Earningand callsmanually_add_user_points(). - It reads the updated total from user meta and returns it in the response.
Can I use it to deduct points?
No—this endpoint only adds points (requires points > 0). To deduct, create a separate endpoint or extend this one with a safe decrement workflow.
Is there rate limiting or idempotency?
Not built-in. If you integrate with external systems, implement client-side idempotency (e.g., a unique operation ID) to avoid duplicate awards.
How can I test quickly?
- Enable the plugin’s API setting (
enable = true). - Confirm your user can
manage_woocommerce. - Run the cURL example.
- Verify the user’s points in the admin or via:
get_user_meta(123, 'woocommerce_reward_points', true);
(or the multisite-aware key if applicable)
Troubleshooting checklist
- 401/403: Not authenticated or lacks capability. Use Application Passwords or an admin session.
- 404: Ensure the feature is enabled; confirm no firewall blocks
/wp-json. - 400
invalid_user:user_idmust be an existing WP user. - 400
invalid_points: Use a positive integer. - Totals not changing: Check for custom hooks or object caching layers that might roll back/buffer changes.
Security best practices
- Prefer Application Passwords for server-to-server calls; restrict to a low-privilege admin account if possible.
- Serve over HTTPS only.
- Log each award with a clear, human-readable
message. - Consider adding rate limiting or WAF rules if exposing this beyond internal systems.

