# Get user field histories for a specific user

List every recorded change to one trader's user field values, XP and coins, newest first, a page at a time.

- Endpoint: `GET https://api.returning.ai/v1/communities/{communityId}/users/{userId}/user-field-histories`
- Section: Users and data / Field history
- Authentication: `Authorization: Bearer <API_KEY>` (Community API key)
- Permission: `userFields` (Shown in the dashboard as "User Fields")
- Retries: Read-only; exact retries are safe
- Guide: hand-written
- Verified: live, 2026-09-27
- Last updated: 26 Sep 2026
- Web page: https://docs.returning.ai/api-reference/user-fields-user-field-history/get-user-field-histories-for-a-specific-user

## When to use this

- Support asks why a trader's value, XP or coin balance changed, and you need the full timeline.
- Check everything your platform wrote for one trader after an onboarding or sync.
- Reconcile one trader's record between your systems and Returning.AI.

**Instead:** Use [Get a trader's field history](https://docs.returning.ai/api-reference/user-fields-user-field-history/get-a-traders-field-history.md) instead to read this trader's changes to one field only.

## Authentication

- Header: `Authorization: Bearer <API_KEY>`
- Permission: `userFields`

Use a Community API key with the `userFields` permission, and keep it on your server. `communityId` must be the ID of the community that owns the key.

## Behaviour

The list holds the trader's changes to every field, newest first, so `data[0]` is the latest change. It includes:

- Changes to your custom fields. Creating the trader with a broker identifier adds an entry for the identifier field.
- XP and coin changes, as entries for the built-in `total_xp` and `total_coins` fields. Their `action` uses the platform's own labels rather than `overwrite`, `increase` and `decrease`, and `storedValue` is usually `null`. Premium currency changes are not included.

Entries for a field you've deleted stay in the list, with `fieldType` set to `null`. Once you delete the trader, their history can't be read.

## Request

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `communityId` | `string` | Yes | Your community's ID. It must be the community that owns your API key. (24 hex characters) |
| `userId` | `string` | Yes | The trader. Use the platform user ID, or their internal record ID, email or username. URL-encode an email. (Platform user ID recommended) |

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | `integer` | No | The page to return, starting at `1`. (Whole number from 1; default `1`) |
| `limit` | `integer` | No | Entries per page, from 1. `page` × `limit` can't be more than 10,000. (Default 50; max 100) |

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | `string` | Yes | Community API key with `userFields`. (`Bearer <API_KEY>`) |

### Example request

```bash
curl --request GET \
  --url 'https://api.returning.ai/v1/communities/66f000000000000000000010/users/3247779/user-field-histories?page=1&limit=50' \
  --header 'Authorization: Bearer <API_KEY>'
```

## Response

A `200` returns one page of entries in `data`. Branch on the HTTP status and `meta.code`, never on `message`. To read everything, start at `page=1` and ask for the next page while `meta.hasNext` is `true`. Only the first 10,000 entries can be paged to. A trader with no changes returns `200` with an empty list, not `404`.

### Response fields

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `meta` | `object` | always | Result details and paging. |
| `meta.status` | `string` | always | `success`. |
| `meta.statusCode` | `number` | always | `200`. |
| `meta.code` | `string` | always | Machine-readable result code. (`USER_FIELD_HISTORIES_LISTED`) |
| `meta.scope` | `string` | always | Always `user` on this endpoint. |
| `meta.total` | `number` | always | Entries for this trader across all pages. |
| `meta.page` | `number` | always | The page returned. |
| `meta.limit` | `number` | always | The page size used. |
| `meta.hasNext` | `boolean` | always | `true` when there are more entries after this page. Ask for `page + 1`. |
| `message` | `string` | always | Human-readable summary. Do not branch on it. |
| `data` | `object[]` | always | This page of entries, newest first, across every field. Empty when the trader has no changes, or past the last page. |
| `data._id` | `string` | always | ID of the history entry. |
| `data.communityID` | `string` | always | Your community ID. |
| `data.userID` | `string` | always | The trader's internal record ID. For `total_xp` and `total_coins`, their platform user ID as a number instead; use `userNumericID` to be safe. |
| `data.userObjectID` | `string` | always | The trader's internal record ID. |
| `data.userNumericID` | `integer` | always | The trader's platform user ID, as a number here. Store it as a string. |
| `data.fieldID` | `string` | always | The field definition's `_id`. |
| `data.fieldName` | `string` | always | The field key, such as `kycstatus` or `total_xp`. |
| `data.fieldType` | `string` | always | The field's current type. `null` when the field has since been deleted. |
| `data.value` | `any` | always | The value written, or for `increase` and `decrease` the amount. For `total_xp` and `total_coins`, the signed change, such as `-25`. |
| `data.storedValue` | `any` | always | The trader's value after this change. For numerical fields, the new total. `null` when no value after the change was recorded, which is usual for `total_xp` and `total_coins`. |
| `data.action` | `string` | always | `overwrite`, `increase` or `decrease`. For `total_xp` and `total_coins`, the platform's own label for the change instead, such as `adjust xps,api` or `add,api`. |
| `data.createdAt` | `string` | always | When the change was recorded. (Date-time) |
| `data.updatedAt` | `string` | always | When the entry last changed. |

### Example response (200)

```json
{
  "meta": {
    "status": "success",
    "statusCode": 200,
    "code": "USER_FIELD_HISTORIES_LISTED",
    "scope": "user",
    "total": 3,
    "page": 1,
    "limit": 50,
    "hasNext": false
  },
  "message": "Read user field histories for specific user api success.",
  "data": [
    {
      "_id": "66f000000000000000000511",
      "communityID": "66f000000000000000000010",
      "userID": "<userObjectId>",
      "userObjectID": "<userObjectId>",
      "userNumericID": 3247779,
      "fieldID": "66f000000000000000000510",
      "fieldName": "kycstatus",
      "fieldType": "single-line-text",
      "value": "verified",
      "storedValue": "verified",
      "action": "overwrite",
      "createdAt": "2026-09-26T08:30:00.000Z",
      "updatedAt": "2026-09-26T08:30:00.000Z"
    },
    {
      "_id": "66f000000000000000000601",
      "communityID": "66f000000000000000000010",
      "userID": 3247779,
      "userObjectID": "<userObjectId>",
      "userNumericID": 3247779,
      "fieldID": "66f000000000000000000602",
      "fieldName": "total_coins",
      "fieldType": "numerical",
      "value": -25,
      "storedValue": null,
      "action": "subtract,api",
      "createdAt": "2026-09-26T07:10:00.000Z",
      "updatedAt": "2026-09-26T07:10:00.000Z"
    },
    {
      "_id": "66f000000000000000000512",
      "communityID": "66f000000000000000000010",
      "userID": "<userObjectId>",
      "userObjectID": "<userObjectId>",
      "userNumericID": 3247779,
      "fieldID": "66f000000000000000000510",
      "fieldName": "kycstatus",
      "fieldType": "single-line-text",
      "value": "pending",
      "storedValue": "pending",
      "action": "overwrite",
      "createdAt": "2026-09-20T10:05:00.000Z",
      "updatedAt": "2026-09-20T10:05:00.000Z"
    }
  ]
}
```

## Errors

Every error carries its code in `meta.code`.

### Fix the request

| Status | Code | What to do |
| --- | --- | --- |
| 400 | `INVALID_PAGINATION` | `page` or `limit` isn't a whole number from 1, `limit` is over 100, or `page` × `limit` is over 10,000. `detail` names the `limit` and 10,000 rules; a bad `page` only says `Invalid input`. |
| 401 | `AUTHENTICATION_REQUIRED` | The key is missing, invalid or expired. Send `Authorization: Bearer <API_KEY>` with a current Community API key. |
| 403 | `API_KEY_PERMISSION_DENIED` | The key lacks `userFields`. Add the permission in Settings > Integration > API Keys. |
| 403 | `API_KEY_COMMUNITY_MISMATCH` | `communityId` is not the community that owns your key, or isn't a valid ID. Use your own community's ID. |

### Fix the data

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `USER_NOT_FOUND` | No active trader in your community matches `userId`. A trader who isn't a member, or whom you deleted, returns this too. A 12-character username or email can't be matched, so use the platform user ID. `meta.userIdentifier` echoes what you sent. |
| 404 | `COMMUNITY_NOT_FOUND` | The community this key belongs to no longer exists. Contact Returning.AI support. |

### Retry with backoff

| Status | Code | What to do |
| --- | --- | --- |
| 500 | `USER_FIELD_OPERATION_FAILED` | The history could not be read. Retry the same request with exponential backoff. |

**Retries:** This endpoint is read-only, so retrying the exact same request is safe after a network error or a `500`. Use bounded exponential backoff. Over the [rate limit](https://docs.returning.ai/how-it-works.md#rate-limits), requests return `429`; wait for the window to reset, then retry.

## Next step

- [Get a trader's field history](https://docs.returning.ai/api-reference/user-fields-user-field-history/get-a-traders-field-history.md): `GET /v1/communities/{communityId}/users/{userId}/user-fields/{fieldIdOrName}/histories`. Narrow to one field for this trader.
- [Compare with current values in Get User Data](https://docs.returning.ai/api-reference/users/get-user-data.md): `POST /v1/users/info`.
