Skip to main content
XP is 4D’s loyalty currency. It’s run like money, not like a score: every XP movement is a balanced double-entry ledger transaction in whole integer units, append-only, with a full audit trail - and member balances settle to an on-chain token.

How members earn XP

XP accrual is rules, not code. Your organization defines XP rules - data, managed from the console - and the accrual engine evaluates them against every incoming event:
  • a rule matches an event type (e.g. an engagement.* or commerce.* event) plus optional conditions on its fields;
  • its award is a fixed amount or a formula over event fields, optionally with a per-event cap;
  • when several rules match one event, the awards are summed and the most restrictive cap applies;
  • rules are versioned with effective time windows - a rule change never rewrites history, it supersedes from a point in time.
Accrual is exactly-once: duplicate event deliveries are detected and become no-ops, so a member can’t be double-awarded for one action.

What can stop an award

A matching rule is necessary for an award, not sufficient. Before XP is issued, the accrual engine runs your organization’s earning controls, and any one of them can decline to pay. A declined award is a normal, recorded outcome, not an error: the event was accepted and stored, nothing was written to the ledger, and sending the same event again gets the same answer. Don’t retry it. The same-content guard is always on, including for organizations that have configured nothing. One content item pays a member once for a given action, for life. Reading an article and answering the quiz on that same article stay separately earnable, because the guard keys on the action as well as the item. It reverses nothing - XP already issued stays issued, and only future repeat awards stop. Where a canonical event carries no stable content identity (a purchase, for example) there is nothing to key on, and the guard doesn’t apply. Earning events lists which event types the guard covers and which stay repeatable. Four further controls are optional and configured per organization from the console. Each one, and the guard, records the reason it declined: Daily windows run midnight to midnight in the organization’s own earning timezone, which isn’t necessarily UTC. A sponsor campaign award runs the three controls that measure what the member has already been paid: content_already_earned, action_lifetime_limit and action_daily_limit. It skips the two XP-counted ones (member_daily_cap, org_daily_pool), which measure what the organization gives away out of its own budget rather than out of a sponsor’s. An admin grant runs none of the five. None of this shows up in the /v1/track or /v1/ingest response, which reports only whether the event was accepted; accrual happens after. To show a member what they can still earn, read GET /v1/users/{user_id}/xp-earning. It returns their remaining XP for the day, the per-action headroom, the instant the day resets, and recent refusals already written as member-facing sentences. An organization with no earning controls answers limited: false, and there’s nothing to show.

Where XP comes from

Every award is a transfer from somewhere - that’s the double-entry part. Organizations fund awards from their engagement reserve, or from a sponsor campaign: a budgeted pool a sponsor funds, drawn down as its rules award XP, reported against its budget. Admins can also make direct grants to a member, with a recorded reason.

Tiers

Tiers rank members by qualifying XP - what they’ve earned, separate from what they’ve spent. Your organization defines ordered thresholds (Bronze/Silver/Gold-style) with attached benefits, computed on lifetime qualifying XP by default or on a rolling 365-day window if configured. A member’s spendable balance going down (redemption) doesn’t demote them.

Redemption

Members spend XP on rewards from your organization’s catalog. A redemption burns the spent XP - ledger-first, then settled on-chain - so total supply always reconciles. Eligibility is checked when the claim is made, and a claim already made is never taken back. If a member’s tier later falls, the rule applies only to new claims. A reward with no minimum tier behaves as it always has: every member can claim it when the existing cap, stock, and XP balance checks allow it. A claim can be refused for one of these reasons. Treat these as expected outcomes, not generic server errors: Keep a catalog useful while you gate it: putting most rewards behind the top tier makes the program read as closed. This is merchandising guidance, not a product restriction. A tier that rewards are gated at cannot be deleted while they still require it. Deleting one, or saving a ladder that leaves one out, is refused with TIER_HAS_GATED_REWARDS (409) and nothing is written. The blocking rewards come back in error.details.rewards, each with its id, name, and the minTierId it requires - so when a single save removes several tiers, you can tell which removal each blocker is about. Clear or move minTierId on those rewards, then delete the tier.

On-chain settlement

Member balances are backed by an XP token on LightLink (an Ethereum L2; nonprod uses the Pegasus testnet). Awards mint to the member’s platform-custodied wallet, redemptions burn, and the platform continuously reconciles ledger totals against on-chain supply. As an integrator you don’t have to touch any of this - the REST API and ledger are the interface - but the trail is publicly verifiable.