Returning.AIDocs
v1

API reference / Users

.md

Get User Data

Look up one trader in your community by email, platform user ID or broker identifier, and get back their profile, roles, balances, tier, activity counts and the custom fields you ask for.

Last updated 28 Oct 2026API v1

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

When to use this

  • Confirm a trader exists after Create User or a registration webhook, and save their userId.
  • Read a trader's current coins, XP, tier and roles before support changes anything.
  • Fetch a broker identifier such as customerid before you write user-field values.

Authentication#

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

Use a Community API key from Settings > Integration > API Keys and keep it on your server. The key limits every lookup to its own community, so a trader in another community returns 404 USER_NOT_FOUND.

Request#

Headers#

Authorization#stringREQUIRED
Community API key with getUserData.

RuleBearer <API_KEY>

Content-Type#stringREQUIRED
Request body format.

Ruleapplication/json

Body#

Send exactly one of idOrEmail or identifier. Sending neither or both returns 400.

idOrEmail#stringONE OF
The trader's email address or numeric platform user ID. Email matching ignores case. Usernames are not accepted.

RuleEmail, or decimal digits. Send exactly one of idOrEmail or identifier.

Eg"trader@example.com"

customFields#string[]OPTIONAL
Custom field keys to return in data.customFields. Ask only for the fields you need.

RuleKeys configured in your community

Eg["customerid"]

identifier#objectONE OF
Structured lookup. Send instead of idOrEmail.

RuleSend exactly one of idOrEmail or identifier

Eg{"key": "customerid", "value": "<brokerCustomerId>"}

key#stringREQUIRED
id for the platform user ID, email, or the key of a custom single-line text or numerical user field, usually your broker identifier such as customerid.

Ruleid, email, or a custom text or number field key

Eg"customerid"

value#stringREQUIRED
The identifier value to match. A string, or a number for numerical fields.

Eg"<brokerCustomerId>"

curl --request POST \
  --url https://api.returning.ai/v1/users/info \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "idOrEmail": "trader@example.com",
    "customFields": ["customerid"]
  }'

Response#

A 200 returns the trader in the data object. Branch on the HTTP status and code, never on message. Save data.userId for the next call. To fit, the example leaves out language, tags and the today and lifetime activity counts; every 200 carries them, as the field list shows.

status#stringALWAYS
Result of the request.

Rulesuccess

code#stringALWAYS
Machine-readable result code.

RuleUSER_DATA_RETRIEVED

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

Eg"User data retrieved successfully"

data#objectALWAYS
The trader.

Eg{ ... }

_id#stringALWAYS
Internal record ID.

Eg"<userObjectId>"

userId#stringALWAYS
Platform user ID. Store it as a string and never do arithmetic on it.

RuleDecimal digits

Eg"3247779"

username#stringALWAYS
The trader's username.

Eg"sample_trader"

firstName#stringALWAYS
First name, or an empty string when none is set.

Rule******** when the trader has not consented to sharing it

Eg"Sample"

lastName#stringALWAYS
Last name, or an empty string when none is set.

Rule******** when the trader has not consented to sharing it

Eg"Trader"

language#stringALWAYS
The language the trader picked in this community, by name.

RuleEnglish when none is set

Eg"English"

xp#numberALWAYS
Current XP total in this community.

Eg1250

coins#numberALWAYS
Current coin balance in this community.

Eg340

xpEarnedToday#numberALWAYS
Net XP change today (UTC), including deductions. An overwrite counts as the difference it made.

RuleCan be negative

Eg25

coinsEarnedToday#numberALWAYS
Net coin change today (UTC), including deductions and expiries. An overwrite counts as the difference it made.

RuleCan be negative

Eg10

roles#string[]ALWAYS
Roles the trader holds in this community.

Eg["@all"]

highestRole#stringALWAYS
The trader's highest-ranked role other than @all, or @all when that is the only role.

Eg"@all"

tags#string[]ALWAYS
Names of the tags assigned to the trader in this community.

Rule[] when none

Eg["VIP"]

current_tier#stringWHEN TIERS SET
Tier name, worked out at request time from current XP and your tier settings. A trader below the first threshold is reported in the lowest tier.

RuleAbsent when no tiers are configured

Eg"Gold"

current_level#integerALWAYS
Level number within current_tier, for level-based progression.

Rulenull for value-range progression or when no tiers are configured

Eg3

to_next_level#numberLEVELS ONLY
XP still needed to reach the next level, for level-based progression.

RuleAbsent at the top level and for value-range progression; 0 when no tiers are configured

Eg150

totalMessages#integerALWAYS
Lifetime count of messages the trader has posted in this community.

Eg42

totalReactions#integerALWAYS
Lifetime count of reactions the trader has added in this community.

Eg17

replySent#integerALWAYS
Lifetime count of replies the trader has sent in this community.

Eg8

visitCount#integerALWAYS
Lifetime count of recorded visits to this community. Counts days visited, not sessions.

Eg63

timeSpent#numberALWAYS
Total recorded active time in minutes, across the trader's whole platform account, not only this community.

RuleMinutes, up to 2 decimals

Eg312.5

loginStreak#integerALWAYS
Longest run of consecutive days (UTC) with a visit to this community. This is the best-ever streak, not the current one.

Rule0 when the trader has never visited

Eg12

customFields#objectALWAYS
The requested custom fields, keyed by field key. A field with no value and no default comes back as the string "null", not JSON null.

RuleOnly keys you requested; {} when you ask for none

Eg{"customerid": "<brokerCustomerId>"}

{
  "status": "success",
  "code": "USER_DATA_RETRIEVED",
  "message": "User data retrieved successfully",
  "data": {
    "_id": "<userObjectId>",
    "userId": "3247779",
    "username": "sample_trader",
    "xp": 1250,
    "coins": 340,
    "roles": ["@all"],
    "highestRole": "@all",
    "firstName": "Sample",
    "lastName": "Trader",
    "current_tier": "Gold",
    "current_level": 3,
    "to_next_level": 150,
    "customFields": {
      "customerid": "<brokerCustomerId>"
    }
  }
}

Errors#

401 and 403 responses carry the code in meta.code. The 400 for sending neither or both lookups has no code; every other error carries it in code.

Fix the request07

400Fix the request
You sent neither or both of idOrEmail and identifier. There is no code; detail.identifier says which. Send exactly one.
400CUSTOM_FIELD_IDENTIFIER_NOT_FOUNDFix the request
No custom user field has this key. Built-in fields such as country aren't accepted. Correct the key, or look up by email or platform user ID.
400CUSTOM_FIELD_IDENTIFIER_UNSUPPORTED_TYPEFix the request
The identifier field isn't a single-line text or numerical field. Look up by email or platform user ID instead.
400CUSTOM_FIELD_IDENTIFIER_INVALID_VALUEFix the request
The value is empty, or isn't a number for a numerical field. Correct it and retry.
400INVALID_CUSTOM_FIELDSFix the request
A key in customFields is not a custom field in your community. detail lists the keys. Remove or correct them.
401AUTHENTICATION_REQUIREDFix the request
The key is missing, malformed, invalid or expired. Send Authorization: Bearer <API_KEY> with a current key.
403API_KEY_PERMISSION_DENIEDFix the request
The key is valid but lacks getUserData. Add the permission in Settings > Integration > API Keys.

Fix the data03

404USER_NOT_FOUNDFix the data
No active trader in this community matches. Check the email or ID; do not retry against other communities.
409CUSTOM_FIELD_IDENTIFIER_DUPLICATEFix the data
More than one trader has that identifier value. Look up by email or platform user ID instead.
503CUSTOM_FIELD_IDENTIFIER_SCAN_LIMIT_EXCEEDEDFix the data
Too many records hold this identifier value to resolve one trader safely. Look up by email or platform user ID instead.

Retry with backoff02

500USER_DATA_RETRIEVAL_FAILEDRetry with backoff
Retry the same request with exponential backoff. Keep the identifier and time for support.
503CUSTOM_FIELD_IDENTIFIER_NOT_READYRetry with backoff
Custom identifier lookup is unavailable, for example for a field created in the last few minutes. Use email or platform user ID, or retry with backoff.

Retries

This endpoint is read-only, so retrying the exact same request is safe after a network error or a 5xx. Use bounded exponential backoff and keep the identifier unchanged between retries. Over the rate limit, requests return 429; wait for the window to reset, then retry.

{
  "status": "error",
  "code": "CUSTOM_FIELD_IDENTIFIER_NOT_FOUND",
  "message": "Custom field identifier does not exist."
}

Next step#

Update User DataPOST/v1/users/updateChange a trader's profile, roles or identifier using the userId you just read.