GiftingStack
Sign in Get started
Docs menu

Docs

Leaderboards, away and inbox

Three read-only views of who sent what: a ranking, a summary of what arrived since the user last looked, and a 24-hour list of received gifts. None of them moves coins.

Checked against the API and the live OpenAPI on 2026-11-04.

Each view has a server endpoint (secret key) and a client endpoint (client token, for the signed-in user). The SDKs draw all three; the pages below are for when you build your own screen or want the numbers on your server. Reads are not counted towards your plan. The numbers are display counters, never balances: a receiver never gets spendable coins.

ViewServer (secret key)Client (client token)
LeaderboardGET /v1/leaderboards/{board}GET /v1/client/leaderboards/{board}
Hide a userPUT /v1/users/{external_id}/leaderboard-visibility(your server only)
While you were awayGET /v1/users/{external_id}/away
PUT /v1/users/{external_id}/away/cursor
GET /v1/client/me/away
PUT /v1/client/me/away/cursor
InboxGET /v1/users/{external_id}/inboxGET /v1/client/me/inbox

Leaderboards

{board} is senders (who sent gifts) or receivers (who received them), ranked by the value of the gifts or by their number. Reversed gifts never count; deleted users and users who opted out never appear.

QueryMeaning
periodday, week (Monday to Sunday), month or all, in UTC. Default week. Kept: today and 7 days back, this week and 4 before, this month and 12 before.
metricunits (value of the gifts in your own coin units) or gifts (their number). Default units.
atAny day inside the wanted period, YYYY-MM-DD. Default today. Ignored for all. Outside the kept range: 400 period_out_of_range.
limitRows, 1 to 100. Default 10. The board is the top 100: there is no page 2.
user (server) / include_me (client)The server adds a me block for that user. The client call includes one for the token user unless include_me=false.
GET /v1/leaderboards/senders?period=week&metric=units&limit=3&user=ava

{
  "board": "senders", "period": "week", "metric": "units",
  "label": "2026-W44",
  "starts_at": "2026-10-26T00:00:00Z", "ends_at": "2026-11-02T00:00:00Z",
  "as_of": "2026-10-29T10:15:02Z",
  "data": [
    { "rank": 1, "user": "ben", "gifts": 14, "units": 5200 },
    { "rank": 2, "user": "cem", "gifts": 9, "units": 3100 },
    { "rank": 2, "user": "dilan", "gifts": 4, "units": 3100 }
  ],
  "has_more": true,
  "me": { "user": "ava", "rank": 41, "gifts": 2, "units": 300, "hidden": false }
}
  • rank: competition rank. Equal scores share a rank (1, 2, 2, 4).
  • label: 2026-10-26, 2026-W44, 2026-10 or all. starts_at and ends_at (exclusive) are null for all.
  • as_of: when the ranking was computed. At most 30 seconds old for day and all time, 2 minutes for week and month, 10 minutes for finished periods.
  • me.rank: the exact rank when the user is in the top 1,000, otherwise null (show "1,000+"). Also null without a score in the period or when hidden. me.hidden says the user opted out.
  • The first read after the feature starts counting older gifts can answer 503 leaderboard_building. Retry after the Retry-After header (30 seconds).

Hiding a user

For users who asked not to be ranked. PUT /v1/users/{external_id}/leaderboard-visibility with { "hidden": true } removes the user from every board at once and keeps their counters; { "hidden": false } shows them again. It needs an Idempotency-Key, creates the user if it does not exist yet, and is not counted towards your plan.

While you were away

The gifts a user received since they last looked, at most the last 7 days, grouped by gift: for a card on the home screen and a short replay of the effects. Reading changes nothing. After the person has seen the summary, send its cursor to the cursor endpoint so the next read starts from there. Nothing here is real time. A user who does not exist yet gets an empty summary.

GET /v1/users/ava/away?max_groups=5

{
  "user": "ava",
  "since": "2026-10-27T08:00:00Z", "until": "2026-10-29T10:15:02Z",
  "cursor": "aw1.MTcyODYzMTgwMjUxMS40MjE3",
  "truncated": false,
  "total_gifts": 7, "total_units": 1900, "sender_count": 3,
  "groups": [
    { "gift": { "id": "rose", "name": "Rose", "price": 100, "icon_url": "…", "animation_url": null },
      "count": 5, "units": 500, "sender_count": 2,
      "senders": [ { "user": "ben", "count": 3 }, { "user": "cem", "count": 2 } ] }
  ],
  "top_senders": [ { "user": "ben", "count": 4, "units": 1200 } ]
}

PUT /v1/users/ava/away/cursor
{ "cursor": "aw1.MTcyODYzMTgwMjUxMS40MjE3" }
  • max_groups: gift groups to return, 1 to 10. Default 5. Groups are biggest first by units; each lists at most 3 senders. top_senders has at most 5, by gift count.
  • since (query): an earlier cursor to read from, for this read only. It does not change the stored cursor.
  • cursor: send it to PUT .../away/cursor after showing the summary. It is unchanged when nothing is new.
  • truncated: more than 2,000 gifts arrived in the window, so the totals are lower bounds.
  • price is today's catalog price, so effects match the gift tray. A user of null is a deleted sender; all of them are merged into one entry.
  • The cursor only moves forward. An older or equal cursor changes nothing, so repeating the call is safe. It needs no Idempotency-Key and is not counted towards your plan.

Inbox

The gifts a user received in the last 24 hours, one row per gift, newest first: who sent which gift and when, for an inbox or activity list. Messages, metadata and references are never included. The server keeps no read state: keep the time of the newest row you showed and compare on your side to draw a badge.

GET /v1/users/ava/inbox?limit=20

{
  "user": "ava",
  "since": "2026-10-28T10:15:02Z", "until": "2026-10-29T10:15:02Z",
  "data": [
    { "id": "gtx_01JA0Q8X2M4N6P8R0T2V4W6Y8Z", "created_at": "2026-10-29T09:58:11Z",
      "sender": "ben",
      "gift": { "id": "rose", "name": "Rose", "price": 100, "icon_url": "…", "animation_url": null },
      "quantity": 3, "units": 300, "status": "completed" }
  ],
  "has_more": false,
  "next_cursor": null
}
  • limit: rows per page, 1 to 100. Default 20. cursor: the next_cursor of the previous page (Pagination).
  • sender is null for a deleted sender. units is the value when the gift was sent (price times quantity).
  • status: a reversed gift stays in the list as reversed. The SDK components hide it.
  • A user who does not exist yet gets an empty list; a deleted user is 422 user_deleted.

Errors

  • 400 invalid_request: a bad query value. 400 period_out_of_range: at outside the kept leaderboard history or in the future.
  • 503 leaderboard_building: the first leaderboard count is still running. Retry after Retry-After.
  • The client endpoints can also answer 401 invalid_client_token (mint a new token) and 503 temporarily_unavailable.

Every error type is listed under Errors. The SDK components that draw these views are in Customize the SDK.

Questions or something unclear? support@giftingstack.com.