Returning.AIDevelopers
v1

API reference / Gamification

.md

Get daily user XP and coin changes

Get the net XP and coin change for up to 100 traders on one UTC day.

Last updated 26 Sep 2026API v1

Method
POST
Path
https://api.returning.ai/v1/users/activity/daily
Permission
getUserStats
Retries
Read-only; exact retries are safe

When to use this

  • Pay out or report on what traders earned yesterday, in one request per day.
  • Check a trader's XP and coin movement on the day they raised a support case.
  • Reconcile your own reward records against Returning.AI for a given date.

Authentication#

Header
Authorization: Bearer <API_KEY>
Permission
getUserStatsShown in the dashboard as “Get User Stats”

Use a Community API key with getUserStats, shown in the dashboard as Get User Stats, and keep it on your server. The key decides the community: totals only count XP and coins earned in your community.

Behaviour#

This read changes nothing. Each total is the sum of every XP and coin change the trader had in your community between 00:00 and 23:59:59 UTC on date, positive and negative. It is not the trader's balance; read that with Get User Data.

An overwrite that sets a trader's balance directly can be counted as the full new balance for that day rather than the difference. For example, a trader who earned 150 XP, was set to 200 XP, then had 200 XP subtracted on the same day shows xp: 150, although their balance moved from 0 back to 0. Check days with overwrites against Search user gamification logs.

Request#

Headers#

Authorization#stringREQUIRED
Community API key with getUserStats.

RuleBearer <API_KEY>

Content-Type#stringREQUIRED
Request body format.

Ruleapplication/json

Body#

Send identifier, identifier_type and date. Email lookups ignore case. Platform user IDs match any account; a trader from outside your community comes back with 0 for both totals. A trader with no changes that day also returns 0, which is a real result, not a missing trader.

To check more than 100 traders, send separate requests. page and limit only split the identifiers you send in one request.

identifier#string | string[]REQUIRED
One email or platform user ID, or an array of up to 100. Every value must be the kind named in identifier_type.

RuleString, or array of 1-100 strings

Eg["trader@example.com"]

identifier_type#stringREQUIRED
What the identifiers are: email or userId (platform user ID). userID is rejected.

Ruleemail or userId

Eg"email"

date#stringREQUIRED
The day, in UTC. A date that doesn't exist, such as 31/02/2026, returns 500.

RuleDD/MM/YYYY

Eg"26/09/2026"

page#integerOPTIONAL
Which slice of your identifier list to process, starting at 1. Only needed when you send more identifiers than limit.

RuleJSON number, 1 or more; default 1

Eg1

limit#integerOPTIONAL
Identifiers processed per page.

RuleDefault 100

Eg100

curl --request POST \
  --url https://api.returning.ai/v1/users/activity/daily \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "identifier": ["trader@example.com"],
    "identifier_type": "email",
    "date": "26/09/2026"
  }'

Response#

A 200 returns one row per matched identifier in data.results. Compare data.pagination.found with the number of identifiers you sent to spot ones that matched no trader. This endpoint has no top-level code; branch on the HTTP status.

status#stringALWAYS
Result of the request.

Rulesuccess

message#stringALWAYS
Human-readable summary. Do not branch on it.

RuleUser gamification stats fetched successfully

data#objectALWAYS
The day's totals.

Eg{ ... }

date#stringALWAYS
The date you sent.

Rule^\d{2}/\d{2}/\d{4}$

Eg"26/09/2026"

pagination#objectALWAYS
Paging over the identifiers you sent, not over results.

Eg{ ... }

page#integerALWAYS
The page of identifiers processed.

RuleMin 1

Eg1

limit#integerALWAYS
Identifiers per page.

Rule1-100

Eg100

total#integerALWAYS
Identifiers you sent, counting repeats.

RuleMin 0

Eg1

total_pages#integerALWAYS
Pages needed for all your identifiers at this limit.

RuleMin 0

Eg1

found#integerALWAYS
Identifiers on this page that matched a trader.

RuleMin 0

Eg1

results#object[]ALWAYS
One row per matched identifier on this page, in the order you sent them. Identifiers that match no trader are left out; a repeated identifier appears again.

Eg[ ... ]

identifier#stringALWAYS
The identifier as you sent it.

Eg"trader@example.com"

user_id#stringALWAYS
The trader's internal user record ID, not the platform user ID.

Rule^[a-fA-F0-9]{24}$

Eg"<userObjectId>"

date#stringALWAYS
The date you sent.

Rule^\d{2}/\d{2}/\d{4}$

Eg"26/09/2026"

coins#numberALWAYS
Net coin change on that day, rounded to 2 decimals. Can be negative.

Eg25

xp#numberALWAYS
Net XP change on that day, rounded to 2 decimals. Can be negative.

Eg150

{
  "status": "success",
  "message": "User gamification stats fetched successfully",
  "data": {
    "date": "26/09/2026",
    "pagination": {
      "page": 1,
      "limit": 100,
      "total": 1,
      "total_pages": 1,
      "found": 1
    },
    "results": [
      {
        "identifier": "trader@example.com",
        "user_id": "<userObjectId>",
        "date": "26/09/2026",
        "coins": 25,
        "xp": 150
      }
    ]
  }
}

Errors#

401 and 403 responses, and the authentication errors 404 COMMUNITY_NOT_FOUND and 500 AUTHENTICATION_FAILED, carry the code in meta.code. Other errors have no code: a validation 400 names each field in detail, and a 500 carries the reason in detail.

Fix the request03

400Fix the request
A field is missing or invalid: identifier_type isn't email or userId, date isn't DD/MM/YYYY, more than 100 identifiers, or page or limit out of range or sent as a string. detail names each field. An empty identifier returns 400 with message At least one identifier is required and no detail.
401AUTHENTICATION_REQUIREDFix the request
The key is missing, invalid or expired. Send Authorization: Bearer <API_KEY> with a current Community API key.
403API_KEY_PERMISSION_DENIEDFix the request
The key lacks getUserStats, or it is a personal key. Use a Community API key and add Get User Stats in Settings > Integration > API Keys.

Fix the data01

404COMMUNITY_NOT_FOUNDFix the data
The community this key belongs to no longer exists. Contact Returning.AI support.

Retry with backoff02

500Retry with backoff
The totals could not be read. If detail mentions Invalid Date, the date doesn't exist; fix it rather than retrying. Otherwise retry the same request with exponential backoff.
500AUTHENTICATION_FAILEDRetry with backoff
The key could not be checked. Retry with backoff; nothing was read.
{
  "meta": {
    "status": "error",
    "statusCode": 400
  },
  "message": "Get user gamification stats endpoint validation error.",
  "detail": {
    "date": "Date must be in DD/MM/YYYY format"
  },
  "solution": "Check your body in request and try again"
}

Next step#

Search user gamification logsPOST/v1/gamifications/logsList the individual changes behind a trader's total for the day.