# Update a user field definition

Rename one of your custom user fields, change its type, or set or clear its default, keeping the same key.

- Endpoint: `PUT https://api.returning.ai/v1/communities/{communityId}/user-fields/{fieldIdOrName}`
- Section: Users and data / User fields
- Authentication: `Authorization: Bearer <API_KEY>` (Community API key)
- Permission: `userFields` (Shown in the dashboard as "User Fields")
- Retries: Same body, same result; retry after reading back
- Guide: hand-written
- Verified: live, 2026-09-27
- Last updated: 26 Sep 2026
- Web page: https://docs.returning.ai/api-reference/user-fields/update-a-user-field-definition

## When to use this

- A field's display name in the dashboard should change, such as `KYC status` becoming `KYC verification`.
- You picked the wrong type when you created a field and need to correct it.
- You want new traders to start with a default value, or want to remove one.

**Instead:** Use [Create a user field definition](https://docs.returning.ai/api-reference/user-fields/create-a-user-field-definition.md) instead when the field doesn't exist yet. This endpoint never creates one.

## 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

Only the properties you send change; the rest keep their current values. The key in `field` never changes, so value writes and history reads that use it keep working after a rename.

Built-in fields, such as `email`, `total_xp` and `total_coins`, can't be updated. Nor can a field marked as a user identifier, such as your broker identifier field.

Changing the type or default doesn't touch traders' existing values or their history: nothing is converted or checked. New value writes must suit the new type. History reads show the field's current type, even on entries written under the old one.

A field changed to `single-select-dropdown` or `multi-select-dropdown` can't have values written yet.

## 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) |
| `fieldIdOrName` | `string` | Yes | The key of the field to change, or its `_id`. Not the display name. (Field key or 24-character ID) |

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | `string` | Yes | Community API key with `userFields`. (`Bearer <API_KEY>`) |
| `Content-Type` | `string` | Yes | Request body format. (`application/json`) |

### Body

Send at least one of `name`, `type` and `defaultValue`. Any other property, including `field`, is rejected.

- `name` is trimmed. It must be unique in your community, ignoring case, and use only ASCII letters, numbers, spaces, `-` and `_`. Changing only the capitals of the current name is allowed.
- `type` can be any of the nine field types.
- `defaultValue` must match the field's type after this update exactly, with the same rules as [Create a user field definition](https://docs.returning.ai/api-reference/user-fields/create-a-user-field-definition.md): for example a JSON number for `numerical` and `true` or `false` for `boolean`, never a string such as `"0"` or `"false"`. `null` removes the default.

If you change `type` and the current default doesn't suit the new type, the update is rejected with `400 INVALID_FIELD_DEFINITION` and `detail.defaultValue`. Send a new `defaultValue`, or `null`, in the same request.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `string` | No | Optional. The new display name. Unique in your community, ignoring case. (ASCII letters, numbers, spaces, `-` and `_`) |
| `type` | `string` | No | Optional. The new field type. Any of the nine types is allowed. (`single-line-text`, `multi-line-text`, `numerical`, `date`, `time`, `date-time`, `boolean`, `single-select-dropdown`, `multi-select-dropdown`) |
| `defaultValue` | `any` | No | Optional. The new default, in the field's type after this update. Send `null` to remove the default. (Matches the type; see Request body) |

### Example request

```bash
curl --request PUT \
  --url https://api.returning.ai/v1/communities/66f000000000000000000010/user-fields/kycstatus \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "KYC verification",
    "defaultValue": "pending"
  }'
```

## Response

A `200` returns the whole definition after the update. Branch on the HTTP status and `meta.code`, never on `message`.

**Note:** The definition may also include a `creator` object naming the account that created it. Build against the fields listed here.

### Response fields

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `meta` | `object` | always | - |
| `meta.status` | `string` | always | `success` |
| `meta.statusCode` | `integer` | always | `200` |
| `meta.code` | `string` | always | Machine-readable result code. (`USER_FIELD_UPDATED`) |
| `message` | `string` | always | Human-readable summary. Do not branch on it. |
| `data` | `object` | always | The definition after the update. |
| `data._id` | `string` | always | The definition's ID. It doesn't change. (`^[0-9a-fA-F]{24}$`) |
| `data.name` | `string` | always | The stored display name, trimmed. |
| `data.field` | `string` | always | The field key. It never changes. (`a-z`, `0-9`, `_`, `-`) |
| `data.type` | `string` | always | The field type. (`single-line-text`, `multi-line-text`, `numerical`, `date`, `time`, `date-time`, `boolean`, `single-select-dropdown`, `multi-select-dropdown`) |
| `data.defaultValue` | `any` | - | The stored default. `null` when you removed it, and left out when the field never had one. |
| `data.isCustom` | `boolean` | always | Always `true`. Only custom fields can be updated. |
| `data.createdAt` | `string` | always | When the definition was created. |
| `data.updatedAt` | `string` | always | When the definition last changed, which is the time of this update. |

### Example response (200)

```json
{
  "meta": {
    "status": "success",
    "statusCode": 200,
    "code": "USER_FIELD_UPDATED"
  },
  "message": "Update user field api success.",
  "data": {
    "_id": "66f000000000000000000510",
    "name": "KYC verification",
    "field": "kycstatus",
    "type": "single-line-text",
    "defaultValue": "pending",
    "isCustom": true,
    "createdAt": "2026-09-26T08:30:00.000Z",
    "updatedAt": "2026-09-27T09:00:00.000Z"
  }
}
```

## Errors

Every JSON error carries its code in `meta.code`. The exception is a request with no `Authorization` header and a JSON body: it returns `400` with a non-JSON body instead of `401`. A `400`, `404` or `409` changes nothing. An empty body, an extra property, an unknown `type` or an empty `name` is rejected first. Then the field must exist, be custom and not be an identifier field, and only then are the new name and default checked.

### Fix the request

| Status | Code | What to do |
| --- | --- | --- |
| 400 | - | No `Authorization` header was sent. With a JSON body this returns `400` with a non-JSON body (`Request body must encrypted`), not `401`. Send `Authorization: Bearer <API_KEY>`. |
| 400 | `INVALID_FIELD_DEFINITION` | The body is empty, has a property other than `name`, `type` or `defaultValue` (such as `field`, which can't change), or breaks a rule. `detail` names the property when it can; it is `{}` for an empty body or an extra property. Nothing was changed. |
| 401 | `AUTHENTICATION_REQUIRED` | The key is invalid or expired, or no key was sent with an empty body. 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. Use your own community's ID. |

### Fix the data

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `USER_FIELD_NOT_FOUND` | No field in your community has this key or ID. This endpoint never creates a field; check the key with List user field definitions, or create the field. |
| 409 | `USER_FIELD_UPDATE_FORBIDDEN` | The field is built in, such as `email` or `total_xp`. Only fields your community created can be changed. |
| 409 | `USER_FIELD_UPDATE_IDENTIFIER_LOCKED` | The field is marked as a user identifier, such as your broker identifier field, and can't be changed through the API. |
| 409 | `USER_FIELD_NAME_CONFLICT` | Another field already has this name, ignoring case. Choose another name. |
| 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` | At `409`, the field changed while your update ran and nothing was saved. At `500`, the outcome is unclear. Read the field with Get a user field definition, then send the same body again if it still differs. |

**Retries:** This endpoint doesn't take an `Idempotency-Key`, and doesn't need one: sending the same body again gives the same result. After a timeout or a `500`, read the field with [Get a user field definition](https://docs.returning.ai/api-reference/user-fields/get-a-user-field-definition.md) and send the update again only if it still differs, so you don't overwrite a change someone else made in between. 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 user field definition](https://docs.returning.ai/api-reference/user-fields/get-a-user-field-definition.md): `GET /v1/communities/{communityId}/user-fields/{fieldIdOrName}`. Read the field back and confirm its name, type and default.
- [Write values of the new type with Update a user field value](https://docs.returning.ai/api-reference/user-fields-user-field-history/update-a-user-field-value.md): `POST /v1/communities/{communityId}/users/{userId}/user-fields/{fieldIdOrName}/histories`.
