Returning.AIDevelopers
v1

API reference / Gamification

.md

Search user gamification logs

List one trader's XP and coin changes in your community, newest first, with optional date, time and action filters.

Last updated 26 Sep 2026API v1

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

When to use this

  • A trader asks why their coins went down, and support needs every change with its reason.
  • Explain a day's total from Get daily user XP and coin changes, one entry at a time.
  • Copy a trader's XP and coin history into your CRM.

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: user only matches traders in it, and you only see changes made in it.

Behaviour#

This read changes nothing. Changes to a trader's XP and coins add entries here, including corrections made through Update User XP and Currency. An XP and coin change made in the same request can share one entry, with both xp and currency set.

Filters combine, and every date and time is UTC. date bounds take whole days. time bounds compare the time of day on every date, so gte 22:00 with lte 02:00 matches nothing. Other keys inside date or time are ignored.

A trader's history stays readable after they are deleted with Manage User Account.

New entries push older ones down while you page. To copy history, page through one finished day at a time and use _id to skip entries you already have.

Request#

Headers#

Authorization#stringREQUIRED
Community API key with getUserStats.

RuleBearer <API_KEY>

Content-Type#stringREQUIRED
Request body format.

Ruleapplication/json

Body#

Send user, plus any filters. page and limit must be JSON numbers; strings such as "1" are rejected. A date value that isn't a date returns 500, so check dates before you send them.

user#stringREQUIRED
The trader's email or platform user ID. Only traders in your community match, and emails ignore case.

RuleEmail or platform user ID

Eg"trader@example.com"

date#objectOPTIONAL
Only entries on these UTC days. Combine the bounds you need.

Eg{"gte": "2026-09-01", "lte": "2026-09-30"}

gte#stringOPTIONAL
On or after this day.

RuleYYYY-MM-DD

Eg"2026-09-01"

lte#stringOPTIONAL
On or before this day. The whole day is included.

RuleYYYY-MM-DD

Eg"2026-09-30"

gt#stringOPTIONAL
After this day.

RuleYYYY-MM-DD

Eg"2026-08-31"

lt#stringOPTIONAL
Before this day.

RuleYYYY-MM-DD

Eg"2026-10-01"

time#objectOPTIONAL
Only entries at these times of day, in UTC, on any date.
gt#stringOPTIONAL
After this minute.

RuleHH:MM, 24-hour

Eg"08:59"

gte#stringOPTIONAL
At or after this time.

RuleHH:MM, 24-hour

Eg"09:00"

lt#stringOPTIONAL
Before this time.

RuleHH:MM, 24-hour

Eg"17:00"

lte#stringOPTIONAL
At or before this minute.

RuleHH:MM, 24-hour

Eg"17:00"

action#string[]OPTIONAL
Only entries with one of these action labels, such as Add or Adjusted by admin. Matched exactly, including case.

RuleArray of labels

Eg["Add"]

page#integerOPTIONAL
Page number, starting at 1.

RuleJSON number, 1 or more; default 1

Eg1

limit#integerOPTIONAL
Entries per page.

RuleDefault 100

Eg50

curl --request POST \
  --url https://api.returning.ai/v1/gamifications/logs \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "user": "trader@example.com",
    "date": {
      "gte": "2026-09-01",
      "lte": "2026-09-30"
    },
    "limit": 50,
    "page": 1
  }'

Response#

A 200 returns the page in data.data and the totals in data.pagination. The body has no message or code; branch on the HTTP status. xp, action and action_details are left out of an entry that doesn't have them.

status#stringALWAYS
Result of the request.

Rulesuccess

data#objectALWAYS
The page of entries and the paging totals.

Eg{ ... }

pagination#objectALWAYS
Paging totals for everything that matches your filters.

Eg{ ... }

total#integerALWAYS
Entries that match, across all pages.

RuleMin 0

Eg2

currentPage#integerALWAYS
The page you asked for.

RuleMin 1

Eg1

totalPages#integerALWAYS
Pages at this limit. 0 when nothing matches.

RuleMin 0

Eg1

hasNextPage#booleanALWAYS
true when a later page has entries.

Egfalse

hasPrevPage#booleanALWAYS
true when page is above 1.

Egfalse

data#object[]ALWAYS
Entries on this page, newest first. Empty when nothing matches.

Eg[ ... ]

_id#stringALWAYS
The entry's ID. Use it to skip entries you already have.

Eg"66f000000000000000000741"

email#stringALWAYS
The trader's email.

RuleEmail format

Eg"trader@example.com"

action#string
What caused the change, such as Add, Subtract or Adjusted by admin. Can be missing on older entries.

Eg"Adjusted by admin"

action_details#string
More detail, such as Added 150 XP or Overwrite 200 XP. Can be missing on older entries.

RuleNullable

Eg"Overwrite 200 XP"

xp#number
XP change. Negative when XP was taken away.

Eg200

currency#numberALWAYS
Coin change. Negative when coins were taken away. 0 when only XP changed.

Eg0

date#stringALWAYS
Day of the change in UTC, as YYYY-MM-DD.

RuleDate

Eg"2026-09-26"

time#stringALWAYS
Time of the change in UTC, as HH:MM.

Rule^([01]\d|2[0-3]):[0-5]\d$

Eg"08:45"

{
  "status": "success",
  "data": {
    "pagination": {
      "total": 2,
      "currentPage": 1,
      "totalPages": 1,
      "hasNextPage": false,
      "hasPrevPage": false
    },
    "data": [
      {
        "_id": "66f000000000000000000741",
        "email": "trader@example.com",
        "action": "Adjusted by admin",
        "action_details": "Overwrite 200 XP",
        "xp": 200,
        "currency": 0,
        "date": "2026-09-26",
        "time": "08:45"
      },
      {
        "_id": "66f000000000000000000740",
        "email": "trader@example.com",
        "action": "Add",
        "action_details": "Added 150 XP",
        "xp": 150,
        "currency": 25,
        "date": "2026-09-26",
        "time": "08:30"
      }
    ]
  }
}

Errors#

Errors on this endpoint have no machine-readable code; branch on the HTTP status. A key without getUserStats gets 401, not 403, with only a message. A validation 400 names each field in detail.

Fix the request02

400Fix the request
A field is missing or has the wrong type: no user, date or time not an object, action not an array, limit outside 1-100, or page or limit sent as a string. detail names each field.
401Fix the request
The key is missing, invalid or expired, it's a personal key, or it lacks getUserStats (message is then Your api key does not have permission to access this action). Send Authorization: Bearer <API_KEY> with a current Community API key, and add Get User Stats in Settings > Integration > API Keys.

Fix the data01

404Fix the data
user matches no trader in your community. Check the email or platform user ID. A trader with no changes returns 200 with an empty list, not 404.

Retry with backoff01

500Retry with backoff
The entries could not be read, a date value isn't a date, or the key could not be checked (Authentication failed). Check the dates, then retry with exponential backoff.
{
  "meta": {
    "status": "error",
    "statusCode": 400
  },
  "message": "Get gamification logs endpoint validation error.",
  "detail": {
    "user": "Required"
  },
  "solution": "Check your body in request and try again"
}

Next step#

Get daily user XP and coin changesPOST/v1/users/activity/dailyGet the net XP and coin change for a day, for one trader or many.