Developer docs · API v1
Bring the traders. We'll bring them back.
Connect trader sign-ups, trading activity and your client portal. We calculate the rewards and run the program with you.
- 09:41:02
POST/v1/users200USER_CREATED - 09:41:03
POST/v1/users/update200USER_UPDATED - 09:41:07 activity batch accepted
batch_id2026-09-26-009 - 09:41:08 coins, XP and tiers calculated
- 09:41:30 store purchase by trader
3247779 - 09:41:30 purchase webhook sent to your URL
- 09:42:10
PUT/v1/redemption-transactions/status200REDEMPTION_TRANSACTION_STATUS_UPDATED
Each kind of data takes its own route.
How it worksYour platform
Traders
Trading activity
Read-only access
Returning.AI
coins · tiers · rewards
Back to you
Widgets in your client portal
Widget SDK for web, mobile SDKs
Your server requests a short-lived embed token.
For example: sign-ups by webhook, trades we read from your trading platform, balances back through the API.
From kickoff to live
- Together
Kickoff: we map your data with your team.
- Us
Setup: we set up your community and API keys.
- You
Build: your team connects data and places the widgets.
- Together
Launch checklist: we test it together.
- Together
Live.
What a call looks like
curl --request POST \
--url https://api.returning.ai/v1/users \
--header 'Authorization: Bearer <API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"firstname": "Sample",
"lastname": "Trader",
"username": "sample_trader",
"displayname": "Sample Trader",
"email": "trader@example.com",
"accessLevel": 1,
"joinServer": true,
"sendEmail": false,
"emailPassword": false,
"externalId": "<brokerCustomerId>"
}'
const response = await fetch("https://api.returning.ai/v1/users" , {
method: "POST",
headers: {
Authorization: "Bearer <API_KEY>",
"Content-Type": "application/json",
},
body: JSON.stringify({
firstname: "Sample",
lastname: "Trader",
username: "sample_trader",
displayname: "Sample Trader",
email: "trader@example.com",
accessLevel: 1,
joinServer: true,
sendEmail: false,
emailPassword: false,
externalId: "<brokerCustomerId>",
}),
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.code ?? result.meta?.code);
}
const { userId } = result.data;
import requests
response = requests.post(
"https://api.returning.ai/v1/users" ,
headers={
"Authorization": "Bearer <API_KEY>",
"Content-Type": "application/json",
},
json={
"firstname": "Sample",
"lastname": "Trader",
"username": "sample_trader",
"displayname": "Sample Trader",
"email": "trader@example.com",
"accessLevel": 1,
"joinServer": True,
"sendEmail": False,
"emailPassword": False,
"externalId": "<brokerCustomerId>",
},
timeout=10,
)
result = response.json()
if not response.ok:
raise RuntimeError(result.get("code") or result["meta"]["code"])
user_id = result["data"]["userId"]
{
"status": "success",
"code": "USER_CREATED",
"message": "User created successfully",
"data": {
"userId": "3247779",
"username": "sample_trader",
"email": "trader@example.com",
"communityMemberId": "66f000000000000000000001",
"identifierKey": "customerid",
"externalId": "<brokerCustomerId>",
"created": true
}
}
{
"status": "fail",
"code": "DUPLICATE_EMAIL",
"message": "Email already exists",
"data": {
"created": false
}
}
DUPLICATE_EMAIL The email already belongs to a trader. Look them up with Get User Data instead of creating again.
Browse the docs
- Users and dataTraders, custom fields, field history and bulk updates.
- GamificationLeaderboards, streaks and mini games, referrals and match predictions.
- Store and rewardsProducts, categories, redemptions and purchase history.
- CommunityMembers, channels, messaging, appearance and analytics.
- WidgetsThe Widget SDK for your web portal and the mobile SDKs for your apps.
- Broker integrationsEnrolling traders, workflow webhooks, the SQS feed, trading rewards and MetaTrader.
The fine print
- ISO 27001 certified
- 99.97% uptime
- API-key auth
- Per-community rate limits
- Dedicated customer success manager