WordPress REST API Reference
Complete reference for all REST API endpoints provided by the Loyalteez WordPress plugin. These endpoints enable JavaScript interactions with loyalty features.
Base URL
All endpoints use the WordPress REST API base URL:
/wp-json/loyalteez/v1
Full Base URL:
https://yoursite.com/wp-json/loyalteez/v1
Authentication
Endpoints Requiring Authentication
Most endpoints require the user to be logged in to WordPress. WordPress automatically handles authentication via:
- WordPress Nonce: Included in requests via
X-WP-Nonceheader - Cookie Authentication: WordPress session cookies
- Application Passwords: For programmatic access
Nonce Generation
WordPress nonces are generated using wp_create_nonce('wp_rest'):
wp_localize_script('your-script', 'loyalteezData', [
'nonce' => wp_create_nonce('wp_rest')
]);
JavaScript Requests
Include the nonce in requests:
fetch('/wp-json/loyalteez/v1/checkin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': loyalteezData.nonce
},
credentials: 'same-origin'
});
Endpoints
POST /checkin
Daily check-in endpoint for recording user activity and maintaining streaks.
Authentication: Required (logged in user)
Request Body: None (user is determined from WordPress session)
Response:
{
"success": true,
"streak": {
"currentStreak": 7,
"multiplier": 1.5,
"nextMilestone": {
"days": 10,
"bonus": 100
},
"unclaimedMilestones": [
{
"days": 7,
"bonus": 50
}
]
},
"reward": 15,
"alreadyClaimed": false
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the check-in was successful |
streak.currentStreak | integer | Current streak count in days |
streak.multiplier | number | Current streak multiplier |
streak.nextMilestone | object|null | Next milestone information |
streak.nextMilestone.days | integer | Days required for milestone |
streak.nextMilestone.bonus | integer | LTZ bonus for milestone |
streak.unclaimedMilestones | array | List of unclaimed milestones |
reward | integer | LTZ reward for this check-in (0 if already claimed) |
alreadyClaimed | boolean | Whether user already checked in today |
Error Responses:
{
"code": "not_logged_in",
"message": "User must be logged in",
"data": {
"status": 401
}
}
{
"code": "not_configured",
"message": "Loyalteez is not configured",
"data": {
"status": 500
}
}
{
"code": "checkin_failed",
"message": "Failed to check in",
"data": {
"status": 400
}
}
Usage Example:
fetch('/wp-json/loyalteez/v1/checkin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': loyalteezData.nonce
},
credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log(`Streak: ${data.streak.currentStreak} days`);
console.log(`Reward: ${data.reward} LTZ`);
} else {
console.error('Check-in failed:', data.message);
}
});
POST /redeem
Redeem a perk using LTZ tokens.
Authentication: Required (logged in user)
Request Body:
{
"perkId": "550e8400-e29b-41d4-a716-446655440000"
}
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
perkId | string | Yes | UUID of the perk to redeem |
Response:
{
"success": true,
"confirmationCode": "ABC123XYZ",
"perk": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Discount Code",
"cost": 500,
"category": "discount"
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether redemption was successful |
confirmationCode | string|null | Confirmation code for redeemed perk |
perk | object|null | Redeemed perk information |
Error Responses:
{
"code": "not_logged_in",
"message": "User must be logged in",
"data": {
"status": 401
}
}
{
"code": "missing_perk_id",
"message": "Perk ID is required",
"data": {
"status": 400
}
}
{
"code": "redeem_failed",
"message": "Insufficient balance",
"data": {
"status": 400
}
}
Usage Example:
fetch('/wp-json/loyalteez/v1/redeem', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': loyalteezData.nonce
},
credentials: 'same-origin',
body: JSON.stringify({
perkId: '550e8400-e29b-41d4-a716-446655440000'
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('Perk redeemed:', data.perk.name);
console.log('Confirmation code:', data.confirmationCode);
} else {
console.error('Redemption failed:', data.message);
}
});
POST /claim-milestone
Claim a streak milestone bonus.
Authentication: Required (logged in user)
Request Body:
{
"milestoneDays": 7
}
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
milestoneDays | integer | Yes | Days milestone to claim (e.g., 7, 30, 100) |
Response:
{
"success": true,
"bonusLtz": 100,
"milestone": 7
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether milestone claim was successful |
bonusLtz | integer | LTZ bonus awarded for milestone |
milestone | integer | Milestone days that were claimed |
Error Responses:
{
"code": "not_logged_in",
"message": "User must be logged in",
"data": {
"status": 401
}
}
{
"code": "missing_milestone",
"message": "Milestone days is required",
"data": {
"status": 400
}
}
{
"code": "claim_failed",
"message": "Milestone not available or already claimed",
"data": {
"status": 400
}
}
Usage Example:
fetch('/wp-json/loyalteez/v1/claim-milestone', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': loyalteezData.nonce
},
credentials: 'same-origin',
body: JSON.stringify({
milestoneDays: 7
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log(`Claimed ${data.milestone}-day milestone!`);
console.log(`Bonus: ${data.bonusLtz} LTZ`);
} else {
console.error('Claim failed:', data.message);
}
});
GET /leaderboard
Get leaderboard rankings by various metrics.
Authentication: Not required (public endpoint)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
metric | string | ltz_earned | Ranking metric: ltz_earned, activity, or streak |
period | string | week | Time period: week, month, or all |
limit | integer | 10 | Number of users to return |
Response:
{
"success": true,
"leaderboard": [
{
"userIdentifier": "[email protected]",
"username": "user1",
"value": 5240,
"rank": 1
},
{
"userIdentifier": "[email protected]",
"username": "user2",
"value": 3890,
"rank": 2
}
],
"metric": "ltz_earned",
"period": "week",
"total": 2
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether request was successful |
leaderboard | array | List of ranked users |
leaderboard[].userIdentifier | string | User identifier |
leaderboard[].username | string | User display name |
leaderboard[].value | number | Value for selected metric |
leaderboard[].rank | integer | User's rank (1-based) |
metric | string | Metric used for ranking |
period | string | Time period for ranking |
total | integer | Total number of users in leaderboard |
Error Responses:
{
"code": "not_configured",
"message": "Loyalteez is not configured",
"data": {
"status": 500
}
}
{
"code": "api_error",
"message": "Failed to fetch leaderboard",
"data": {
"status": 500
}
}
Usage Example:
fetch('/wp-json/loyalteez/v1/leaderboard?metric=activity&period=month&limit=20')
.then(response => response.json())
.then(data => {
if (data.success) {
data.leaderboard.forEach(user => {
console.log(`${user.rank}. ${user.username}: ${user.value}`);
});
} else {
console.error('Failed to fetch leaderboard:', data.message);
}
});
Error Handling
Standard Error Format
All endpoints return errors in WordPress REST API standard format:
{
"code": "error_code",
"message": "Human-readable error message",
"data": {
"status": 400
}
}
HTTP Status Codes
| Status Code | Meaning | When It Occurs |
|---|---|---|
| 200 | OK | Request succeeded |
| 400 | Bad Request | Invalid parameters or request body |
| 401 | Unauthorized | User not logged in (for authenticated endpoints) |
| 500 | Internal Server Error | Plugin not configured or API error |
Common Error Codes
| Error Code | Status | Description |
|---|---|---|
not_logged_in | 401 | User must be logged in |
not_configured | 500 | Loyalteez plugin not configured |
missing_perk_id | 400 | Perk ID parameter missing |
missing_milestone | 400 | Milestone days parameter missing |
checkin_failed | 400 | Failed to check in (already claimed, API error, etc.) |
redeem_failed | 400 | Failed to redeem perk (insufficient balance, perk not available, etc.) |
claim_failed | 400 | Failed to claim milestone (not available, already claimed, etc.) |
api_error | 500 | Error communicating with Loyalteez API |
JavaScript Integration
Complete Example
// Initialize (usually done via wp_localize_script)
const loyalteezData = {
nonce: 'abc123...', // Generated by wp_create_nonce('wp_rest')
apiUrl: '/wp-json/loyalteez/v1'
};
// Daily check-in
async function checkIn() {
try {
const response = await fetch(`${loyalteezData.apiUrl}/checkin`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': loyalteezData.nonce
},
credentials: 'same-origin'
});
const data = await response.json();
if (data.success) {
console.log(`Check-in successful! Streak: ${data.streak.currentStreak} days`);
return data;
} else {
throw new Error(data.message);
}
} catch (error) {
console.error('Check-in error:', error);
throw error;
}
}
// Redeem perk
async function redeemPerk(perkId) {
try {
const response = await fetch(`${loyalteezData.apiUrl}/redeem`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': loyalteezData.nonce
},
credentials: 'same-origin',
body: JSON.stringify({ perkId })
});
const data = await response.json();
if (data.success) {
console.log(`Perk redeemed: ${data.perk.name}`);
return data;
} else {
throw new Error(data.message);
}
} catch (error) {
console.error('Redemption error:', error);
throw error;
}
}
// Claim milestone
async function claimMilestone(milestoneDays) {
try {
const response = await fetch(`${loyalteezData.apiUrl}/claim-milestone`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': loyalteezData.nonce
},
credentials: 'same-origin',
body: JSON.stringify({ milestoneDays })
});
const data = await response.json();
if (data.success) {
console.log(`Milestone claimed: ${data.bonusLtz} LTZ`);
return data;
} else {
throw new Error(data.message);
}
} catch (error) {
console.error('Milestone claim error:', error);
throw error;
}
}
// Get leaderboard
async function getLeaderboard(metric = 'ltz_earned', period = 'week', limit = 10) {
try {
const params = new URLSearchParams({ metric, period, limit });
const response = await fetch(`${loyalteezData.apiUrl}/leaderboard?${params}`);
const data = await response.json();
if (data.success) {
return data.leaderboard;
} else {
throw new Error(data.message);
}
} catch (error) {
console.error('Leaderboard error:', error);
throw error;
}
}
Testing
Using cURL
Check-in:
curl -X POST https://yoursite.com/wp-json/loyalteez/v1/checkin \
-H "Content-Type: application/json" \
-H "X-WP-Nonce: YOUR_NONCE" \
--cookie "wordpress_logged_in_XXX=COOKIE_VALUE"
Redeem Perk:
curl -X POST https://yoursite.com/wp-json/loyalteez/v1/redeem \
-H "Content-Type: application/json" \
-H "X-WP-Nonce: YOUR_NONCE" \
--cookie "wordpress_logged_in_XXX=COOKIE_VALUE" \
-d '{"perkId":"550e8400-e29b-41d4-a716-446655440000"}'
Get Leaderboard:
curl "https://yoursite.com/wp-json/loyalteez/v1/leaderboard?metric=activity&period=month&limit=10"
Related Documentation
- WordPress Integration Guide - Main WordPress integration guide
- WordPress Shortcode Reference - Shortcode documentation
- Shared Services Overview - Backend services documentation
- WordPress REST API - WordPress REST API documentation
Need help? [email protected]