Server SDK
Leaderboards
Surface competitive rankings to drive member engagement
Leaderboards rank members by points earned over a time period. Use them to drive competition, highlight top members, and motivate engagement.
Get Leaderboard
Fetch the ranked list of members.
GET /api/v1/leaderboardQuery Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
period | string | all_time | all_time, monthly, or weekly |
limit | number | 10 | Results per page (max 100) |
offset | number | 0 | Pagination offset |
cursor | string | — | Cursor for cursor-based pagination |
SDK
// Top 10 all-time
const { data: entries } = await useLoyalty.leaderboards.get({ limit: 10 });
// Top 25 this month
const { data: entries } = await useLoyalty.leaderboards.get({
period: 'monthly',
limit: 25,
});Response
{
"data": [
{
"rank": 1,
"externalId": "user_456",
"name": "Sarah K.",
"avatarUrl": "https://example.com/avatars/sarah.jpg",
"points": 12500
},
{
"rank": 2,
"externalId": "user_123",
"name": "John D.",
"avatarUrl": null,
"points": 9800
}
],
"total": 842,
"hasMore": true,
"nextCursor": "cursor_abc123"
}Get Member's Rank
Fetch the rank and points of a specific member without loading the full leaderboard.
GET /api/v1/leaderboard/rank/:externalId?period=monthlySDK
const rank = await useLoyalty.leaderboards.getMemberRank('user_123', 'monthly');
// { rank: 14, points: 3200 }Response
{
"rank": 14,
"points": 3200
}Code Examples
Leaderboard Widget
import { useLoyaltyLeaderboard } from '@useloyalty/sdk/react';
function LeaderboardWidget() {
const { entries, isLoading } = useLoyaltyLeaderboard({
fetcher: (opts) =>
fetch(`/api/leaderboard?period=${opts.period}&limit=${opts.limit}`)
.then(r => r.json()),
period: 'monthly',
limit: 10,
});
if (isLoading) return <div>Loading...</div>;
return (
<ol>
{entries.map(entry => (
<li key={entry.externalId}>
<span>#{entry.rank}</span>
<span>{entry.name ?? 'Anonymous'}</span>
<span>{entry.points.toLocaleString()} pts</span>
</li>
))}
</ol>
);
}Show "Your Rank" Alongside the Leaderboard
async function getLeaderboardWithUserRank(userId: string) {
const [{ data: top10 }, myRank] = await Promise.all([
useLoyalty.leaderboards.get({ period: 'monthly', limit: 10 }),
useLoyalty.leaderboards.getMemberRank(userId, 'monthly'),
]);
return { top10, myRank };
}Period Tabs
const [period, setPeriod] = useState<'all_time' | 'monthly' | 'weekly'>('monthly');
const { entries, refetch } = useLoyaltyLeaderboard({
fetcher: (opts) => fetch(`/api/leaderboard?period=${opts.period}`).then(r => r.json()),
period,
});
// When user switches tab, period changes → fetcher re-runs automaticallyPrivacy Considerations
Leaderboard entries return externalId, name, and avatarUrl. If your members haven't set a display name, name is null. Consider showing a masked identifier ("Member #1234") instead of the raw externalId in your UI.
function displayName(entry: LeaderboardEntry): string {
return entry.name ?? `Member #${entry.externalId.slice(-4)}`;
}