Bulk update users from CSV
Upload a CSV that changes many traders' profiles, roles, balances or custom fields in one background job.
- Method
- POST
- Path
https://api.returning.ai / v1/ users/ bulk-update - Permission
- bulkUpdateUser
- Retries
- No Idempotency-Key; list jobs before retrying
When to use this
- A nightly feed from your platform adds coins or XP, or writes custom field values, for many traders at once.
- You fill in broker customer IDs for traders who were created without one.
- Support needs to correct balances or roles for a list of traders, with a result for every row.
Authentication#
- Header
Authorization: Bearer <API_KEY>- Permission
- bulkUpdateUserShown in the dashboard as “Bulk Update User”
Uploading needs bulkUpdateUser. Reading jobs back needs getBulkUpdate, shown in the dashboard as Get Bulk Update History, so give your key both. Every row is limited to traders in the key's community. Keep the key on your server.
Behaviour#
The upload only queues a job. Jobs for one community run one at a time, oldest first. A job moves from In Queue to In Progress, then ends as Completed or Failed.
Failedusually means the file was rejected as a whole, for example an unknown column, a number column without its_opcolumn, or a missing identifier column. The API does not return the reason, so check the file against the rules below.Completedcan still include failed rows. Get bulk update job details lists the rows, a page at a time, withstatus, and failed rows carryerrors, each with acodesuch asUSER_NOT_AVAILABLE. Read details only once the job isCompleted.- XP and coin changes are saved to each trader's history, and XP changes can also update the trader's level and XP-based roles. New roles and badges can send the trader a role or badge email if your community has those emails switched on.
Request#
Headers#
bulkUpdateUser.RuleBearer <API_KEY>
Body#
Send multipart/form-data with the file in field data. The first line must be a header row, and columns are separated by commas. You can also send the rows as JSON, {"data": [{"Email": "trader@example.com", "Total Coins": "500", "Total Coins_op": "add"}]}, with the same column names.
Email,Total Coins,Total Coins_op,KYC status
trader@example.com,500,add,verified
- Rows are matched by
Email, not case-sensitive. Only the first row for each trader is applied; repeats fail. - Columns, spelled exactly like this:
Email,First Name,Last Name,Phone Number,Country,Language,Role,Tag,Badges,Total XP,Total Coins,Penalty(warned/suspended/banned), and each custom field by its display name. Any other column fails the job. Total XP,Total Coinsand numerical custom fields need a matching_opcolumn, such asTotal Coins_op, withadd,subtractoroverwrite. Fill the operator cell on every row, even where the value is empty.- An empty cell is skipped, so it never clears a value.
Rolereplaces the trader's roles, apart from@all, with the comma-separated list in the cell. Add aRole_opcolumn withaddorsubtractto change only the listed roles.TagandBadgesreplace the current list.- To set a broker customer ID, add its column by display name. It fills an empty identifier but cannot change one that is already set.
- There is no row limit; the file can be up to 30 MB.
data.Rule.csv, max 30 MB
Eg"users.csv"
Eg"Coins top-up 2026-09-26"
Email column. To match by broker customer ID instead, send the key of your community's active identifier field and include a column with that name.RuleYour active identifier field's key
Eg"customerid"
false applies coin additions in full. Otherwise, if your community has a coin earning cap, add amounts in Total Coins are limited by it.Ruletrue or false
Eg"false"
Send the body as multipart/form-data.
curl --request POST \
--url https://api.returning.ai/v1/users/bulk-update \
--header 'Authorization: Bearer <API_KEY>' \
--form 'data=@users.csv' \
--form 'log_name=Coins top-up 2026-09-26'
Response#
A 200 returns only a confirmation that the job is queued. It has no job ID, so use a unique log_name and look the job up with List bulk update jobs.
Rulesuccess
Eg"Bulk update user process is queued"
Eg{ ... }
Eg"Bulk update user process is queued. You can check in Api Log ( community settings )"
{
"status": "success",
"message": "Bulk update user process is queued",
"data": {
"message": "Bulk update user process is queued. You can check in Api Log ( community settings )"
}
}
Errors#
Errors from the API key check, such as 401 and 403, carry the code in meta.code. Other errors from this endpoint have no code, so branch on the HTTP status. Problems inside the file never cause an error here; they show up in the job's status and row details.
Fix the request03
data is not a non-empty array. Send the file as multipart form field data, with a .csv name or a text/csv type.AUTHENTICATION_REQUIREDFix the requestAuthorization: Bearer <API_KEY> with a current key.API_KEY_PERMISSION_DENIEDFix the requestbulkUpdateUser. Add the permission in Settings > Integration > API Keys.Fix the data01
COMMUNITY_NOT_FOUNDFix the dataRetry with backoff02
500 means the file was not saved and no job was created; retry with backoff. A 500 error page without JSON means the file is over 30 MB or was sent under a form field other than data; fix the upload instead.AUTHENTICATION_FAILEDRetry with backoff{
"status": "fail",
"message": "Uploaded file must be a CSV"
}