Points
How members earn, spend and compete with points, and how to run more than one kind.
Points are how your members keep score. They earn points for what they do, spend them on rewards, and climb leaderboards with them. For example:
- XP for every quest a member completes.
- Raffle tickets a member spends to enter a prize draw.
- Event credits your own system hands out at the door.
Each kind of points lives in its own point ledger. A project can have several, and every member has a balance in each one. Quests, referrals and your own trusted systems can all add points.
What members see
A signed-in member sees their own balance in each ledger and the history of how they earned and spent it, newest first. Each history entry names the quest that paid it when there is one. Members never see the notes an operator wrote when changing their points.
Points only ever come from you: from a quest, a referral, a leaderboard prize, an engagement reward, or a change your team or your server makes. A member can't give themselves points.
More than one kind of points
Make a separate ledger when the points mean different things, such as XP that ranks members and tickets that members spend. Several leaderboards can read one ledger with different time windows, so you rarely need a ledger per board.
- Renaming is safe. A ledger keeps its identity when you rename it. Balances and history don't change, and two ledgers both named "XP" stay separate.
- Archive to retire. Archive a ledger when new quests and rewards should stop using it. Nothing is deleted: rewards you already published can still pay it, and members and operators can still read its balances and history. Console leaves an archived ledger out of new reward pickers.
- Restore any time. See Restore an archived ledger.
For Console setup, see Choose a point ledger.
Define a ledger in code
In shared authored configuration, use a stable ledger key. Domino resolves it to the environment's ID during publication. Define the ledger in ledgers.ts:
import { defineLedger } from "@domino-sdk/relay/authoring";
export const community = defineLedger({
key: "community",
name: "XP",
description: "Community participation",
});Publish that export from relay.json:
{
"pointLedgers": [
{ "entry": "ledgers.ts", "exportName": "community" }
]
}Merge this property into the existing manifest. A quest can import the handle and award points(community, 10).
Match ledgers in your app
Reads return ledger IDs, not keys. A referral reward, point account, or history entry has balance: "ledger_…" even when your code declared "community". Comparing that value with a key never matches, and showing it puts an ID on screen.
- Read the project's ledgers with
relay.pointLedgers.list(), orusePointLedgers()in React, whosedataholds the list oncestatusisready. Each entry hasid,key, andname. Signed-out visitors can read it too. - Find your ledger by key, then compare IDs:
ledgers.find((l) => l.key === "community")?.id. - Show the ledger's
name, never its ID. Ledgers created in Console without a key havekey: null.
Quest views already name their ledger: each points reward carries amount and ledger: { id, key, name }, and its label reads like "10 XP".
Entries, balances, and available points
Every award, purchase, correction and reversal is recorded as an entry. A member's balance adds them up.
Engagement points are dated when the growth was measured. An engagement rule pays once a day, but each of its entries takes effect when the content sample that measured the growth was observed, so the points land in the leaderboard window and budget period of the measurement, not of the payment.
| Term | Meaning |
|---|---|
| Current balance | The sum of the member's entries. |
| Reservation | Points held for a reward that's on its way. They aren't spent yet, but the member can't spend them twice. |
| Available points | What the member can spend after reservations. |
- Balances never go negative. Deductions cannot make a balance negative or consume reserved points.
- Only trusted server operations change points. A member's own session cannot grant points.
- A retried award pays once. Retrying an external award requires the same action ID and payload, so a lost response does not produce a second award. See Supply points from a trusted backend.
Record points as an operator
Your team can award, take away or correct a member's points. Each change needs a reason, and Audit history records it with who made it.
| Change | CLI | Management API kind |
|---|---|---|
| Award | domino points award MEMBER LEDGER --amount 50 --reason "…" | award |
| Record spending | domino points spend MEMBER LEDGER --amount 20 --reason "…" | spend |
| Correct by an amount | domino points adjust MEMBER LEDGER --amount -5 --reason "…" | adjust |
| Set an absolute total | domino points set MEMBER LEDGER --total 120 --expected-total 100 --classification earned --reason "…" | set |
| Reverse an entry | domino points reverse MEMBER LEDGER --entry ENTRY --amount 50 --reason "…" | reverse |
Show members their points
A signed-in member reads their own points from the browser. No server route or management key is needed.
import { createBrowserRelayClient } from "@domino-sdk/relay/browser"
const relay = createBrowserRelayClient({ baseUrl: "/relay" })
const { items } = await relay.me.balances()
const points = items.find((b) => b.ledger.key === "community")
// points.balance: the current balance. points.available: what they can spend now.
const page = await relay.me.pointHistory({ ledger: "community" })
// page.items: most recently recorded first, each { amount, kind, at, quest };
// pass page.nextCursor for more.In React, useBalances() and usePointHistory("community") hold the same answers in data, and both read again whenever one of the member's quests completes.
- Own points only. Neither read takes a member: each answers for the session's member, in the project and environment the session belongs to.
- Every ledger.
balances()lists every ledger in the project, including archived ledgers, with zero where the member has no entries. - No operator notes. History entries leave out the reason and actor an operator recorded. Operators see them in Console, with
domino points list, and throughmanagement.points.history(member, ledger). - Recorded order. History lists entries in the order Domino recorded them.
atis when an entry took effect: a backdated award has an earlierat, and a reversal keeps theatof the entry it reverses. - Where points came from.
questnames the quest that paid an entry, through a completion or an engagement settlement.kindisaward,spend,adjustorreverse, and Domino may add kinds. Referral payouts appear as adjustments (adjust, with no quest). An opening balance a member import recorded is an adjustment withimported: true.
Completion and standings
A leaderboard ranks members by a ledger. You choose whether spending lowers a member's rank:
| Board | Spending | Adjustments and reversals | Imported opening balances |
|---|---|---|---|
| Current balance | Lowers the score | Included | Included |
| Earned points | Excluded | Relevant ones included | Excluded |
A score that comes from outside Domino, such as a game's high score, gets its own ledger, updated with absolute values. That ledger is never spent or priced by rewards. See external scores.
Restore an archived ledger
Choose Unarchive ledger beside it in Rewards → Point ledgers, or Unarchive point ledger in Settings → Resources, and give a reason. The same ledger becomes available to new rewards again, with its balances and history unchanged.