Gamification API
Server-to-server REST API for adding gamification to any application. Award points, unlock badges, manage tiers, track streaks, and run leaderboards, all via API key authentication.
Authentication
All Gamification API endpoints use API key authentication. Pass your key in the X-API-Key header.
curl -X POST https://YOUR_API_DOMAIN/api/v1/gamify/points/award \
-H "X-API-Key: bq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"participant_id": "user_123", "amount": 100, "reason": "Purchase completed"}'Standard API Key
Used for participant-facing operations (awarding points, recording streaks, querying state). Any active API key works.
Admin API Key
Used for definition management (creating badges, tiers, leaderboards). Requires admin or gamify:admin scope on the API key.
Quick Start
A complete gamification flow in four API calls. Participants are auto-created on first interaction, no registration step needed.
curl -X POST https://YOUR_API_DOMAIN/api/v1/gamify/points/award \
-H "X-API-Key: bq_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"participant_id": "user_123",
"amount": 250,
"reason": "Completed onboarding",
"idempotency_key": "onboarding_user123"
}'
# Response
{
"transaction_id": "a1b2c3d4-...",
"participant_id": "user_123",
"amount": 250,
"new_balance": 250,
"tier_upgrade": null
}curl -X POST https://YOUR_API_DOMAIN/api/v1/gamify/badges/award \
-H "X-API-Key: bq_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"participant_id": "user_123",
"badge_code": "first_steps"
}'
# Response
{
"participant_id": "user_123",
"badge_code": "first_steps",
"badge_name": "First Steps",
"rarity": "common",
"earned_at": "2026-02-14T10:00:00Z",
"already_earned": false
}curl -X POST https://YOUR_API_DOMAIN/api/v1/gamify/streaks/record \
-H "X-API-Key: bq_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"participant_id": "user_123",
"streak_code": "daily_login"
}'
# Response
{
"streak_code": "daily_login",
"new_count": 3,
"longest_count": 14,
"is_new_record": false,
"already_recorded": false
}curl https://YOUR_API_DOMAIN/api/v1/gamify/participants/user_123/state \
-H "X-API-Key: bq_live_your_key"
# Response
{
"participant_id": "user_123",
"points": { "balance": 250, "total_earned": 250, "total_spent": 0 },
"tier": { "code": "bronze", "name": "Bronze", "level": 1 },
"badges": [{ "code": "first_steps", "name": "First Steps", "earned": true }],
"streaks": { "current": 3, "longest": 14 },
"challenges": { "active": 0, "completed": 0 },
"rewards": { "total_claimed": 0 }
}API Resources
Explore each resource for full endpoint details, request/response schemas, and examples.
Award, deduct, batch award, balance, and transaction history. 5 endpoints.
Idempotent badge awards and earned/unearned status queries. 2 endpoints.
Current tier, next-tier progress, history, and manual assignment. 2 endpoints.
Rankings with time-period filters and individual rank/percentile. 2 endpoints.
Record activities, automatic period calculation, and grace periods. 2 endpoints.
List, claim with points deduction, and view claimed history. 3 endpoints.
Emit custom events, batch processing, and event history queries. 3 endpoints.
Register, profile, update attributes, and unified state. 4 endpoints.
CRUD for badges, tiers, leaderboards, streaks, rewards, and participant management.
Common Patterns
Idempotency
Points awards and events support idempotency_key to prevent duplicate processing. Badge awards and streak recordings are naturally idempotent (same badge/period returns success without duplication).
// First call, processes normally
POST /api/v1/gamify/points/award
{ "participant_id": "user_123", "amount": 100,
"idempotency_key": "purchase_ord_001" }
→ { "transaction_id": "txn_abc", "new_balance": 100 }
// Second call with same key, returns cached result
POST /api/v1/gamify/points/award
{ "participant_id": "user_123", "amount": 100,
"idempotency_key": "purchase_ord_001" }
→ { "transaction_id": "txn_abc", "new_balance": 100 } // Same resultParticipant Registration
Participants are automatically created on their first interaction with any endpoint, no registration step required. Optionally, use POST /gamify/participants to pre-register participants with a display name, avatar, and custom attributes. The participant_id is your application's user identifier (string, 1-255 chars).
Pagination
List endpoints support pagination via page and page_size query parameters.
GET /api/v1/gamify/participants/user_123/points/transactions?page=2&page_size=20
{
"transactions": [...],
"total": 156, // Total across all pages
"page": 2, // Current page
"page_size": 20 // Items per page (max 100)
}Automatic Tier Evaluation
Every points award automatically evaluates tier thresholds. If the participant qualifies for a higher tier, the tier_upgrade field is populated in the response. No separate API call needed.
Error Handling
All errors return a consistent JSON format with an appropriate HTTP status code.
// Error response format
{
"detail": "Human-readable error message"
}
// Common status codes
401 Unauthorized, Missing or invalid API key
403 Forbidden, API key lacks required scope (admin endpoints)
404 Not Found, Badge code, tier code, or participant not found
400 Bad Request, Insufficient points, invalid parameters
422 Unprocessable, Request validation failed (missing required fields)
429 Too Many Requests, Rate limit exceeded| Scenario | Status | Detail |
|---|---|---|
| Deduct more than available | 400 | Insufficient points. Available: 30, requested: 50 |
| Unknown badge code | 404 | Badge definition not found: unknown_badge |
| Missing admin scope | 403 | API key requires 'admin' scope |
| No reward codes left | 400 | No available reward codes |
| Max claims exceeded | 400 | Maximum claims per participant exceeded |
Integration Example
A typical server-side integration that awards points on purchase and checks for tier upgrades.
const BRICQS_API = 'https://YOUR_API_DOMAIN/api/v1/gamify';
const API_KEY = process.env.BRICQS_API_KEY;
const headers = {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
};
// After a purchase is completed
app.post('/api/purchase/complete', async (req, res) => {
const { userId, orderId, amount } = req.body;
// 1. Award points based on purchase amount
const pointsRes = await fetch(`${BRICQS_API}/points/award`, {
method: 'POST',
headers,
body: JSON.stringify({
participant_id: userId,
amount: Math.floor(amount), // 1 point per dollar
reason: `Purchase #${orderId}`,
metadata: { order_id: orderId, amount },
idempotency_key: `purchase_${orderId}`,
}),
});
const points = await pointsRes.json();
// 2. Record daily activity streak
await fetch(`${BRICQS_API}/streaks/record`, {
method: 'POST',
headers,
body: JSON.stringify({
participant_id: userId,
streak_code: 'daily_purchase',
}),
});
// 3. Check for tier upgrade
if (points.tier_upgrade) {
// Trigger your own notification
await sendPushNotification(userId,
`Congratulations! You've reached ${points.tier_upgrade.name}!`
);
}
res.json({
points_earned: points.amount,
new_balance: points.new_balance,
tier_upgrade: points.tier_upgrade,
});
});import httpx
BRICQS_API = "https://YOUR_API_DOMAIN/api/v1/gamify"
HEADERS = {
"X-API-Key": os.environ["BRICQS_API_KEY"],
"Content-Type": "application/json",
}
@app.post("/api/purchase/complete")
async def complete_purchase(order: Order):
async with httpx.AsyncClient() as client:
# Award points
resp = await client.post(
f"{BRICQS_API}/points/award",
headers=HEADERS,
json={
"participant_id": order.user_id,
"amount": int(order.total),
"reason": f"Purchase #{order.id}",
"idempotency_key": f"purchase_{order.id}",
},
)
result = resp.json()
# Record streak
await client.post(
f"{BRICQS_API}/streaks/record",
headers=HEADERS,
json={
"participant_id": order.user_id,
"streak_code": "daily_purchase",
},
)
return {
"points_earned": result["amount"],
"new_balance": result["new_balance"],
"tier_upgrade": result.get("tier_upgrade"),
}