> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Contact

> Update custom fields for a contact on a specific sending list.

Update the custom fields attached to a contact on a given sending list. By default, the provided fields are **merged** into the existing custom fields -- existing keys not included in the request are preserved. Set `merge_fields` to `false` to replace the entire custom fields object.

## Body Parameters

<ParamField body="phone_number" type="string" required>
  Contact phone number in E.164 format (e.g., `+14155559876`).
</ParamField>

<ParamField body="list_number" type="string" required>
  Sending list phone number in E.164 format (e.g., `+18005551234`). Must be a list owned by your account.
</ParamField>

<ParamField body="custom_fields" type="object" required>
  Key-value pairs to set on the contact's custom fields. Values can be strings, numbers, or booleans.
</ParamField>

<ParamField body="merge_fields" type="boolean" default="true">
  When `true` (default), the provided keys are merged into the existing custom fields -- keys not included in the request are preserved. When `false`, the existing custom fields are entirely replaced with the provided object.
</ParamField>

## Response Fields

<ResponseField name="success" type="boolean">
  Whether the operation completed successfully.
</ResponseField>

<ResponseField name="list_contact_id" type="string">
  Unique identifier of the ListContact record that was updated.
</ResponseField>

<ResponseField name="custom_fields" type="object">
  The full custom fields object after the update.
</ResponseField>

## Examples

<RequestExample>
  ```bash cURL - Merge (default) theme={null}
  curl -X PUT "https://api.tracklysms.com/api/v2/contacts" \
    -H "X-Api-Key: trk_your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "phone_number": "+14155559876",
      "list_number": "+18005551234",
      "custom_fields": {
        "vip_status": "gold",
        "last_purchase": "2026-02-10"
      }
    }'
  ```

  ```python Python - Merge (default) theme={null}
  import requests

  response = requests.put(
      "https://api.tracklysms.com/api/v2/contacts",
      headers={
          "X-Api-Key": "trk_your_api_key_here",
          "Content-Type": "application/json"
      },
      json={
          "phone_number": "+14155559876",
          "list_number": "+18005551234",
          "custom_fields": {
              "vip_status": "gold",
              "last_purchase": "2026-02-10"
          }
      }
  )

  print(response.json())
  ```

  ```javascript Node.js - Merge (default) theme={null}
  const response = await fetch("https://api.tracklysms.com/api/v2/contacts", {
    method: "PUT",
    headers: {
      "X-Api-Key": "trk_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      phone_number: "+14155559876",
      list_number: "+18005551234",
      custom_fields: {
        vip_status: "gold",
        last_purchase: "2026-02-10",
      },
    }),
  });

  const data = await response.json();
  console.log(data);
  ```

  ```bash cURL - Replace theme={null}
  curl -X PUT "https://api.tracklysms.com/api/v2/contacts" \
    -H "X-Api-Key: trk_your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "phone_number": "+14155559876",
      "list_number": "+18005551234",
      "custom_fields": {
        "tier": "premium"
      },
      "merge_fields": false
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Merged theme={null}
  {
    "success": true,
    "list_contact_id": "665a1b2c3d4e5f6a7b8c9d0f",
    "custom_fields": {
      "first_name": "Jane",
      "source": "landing_page_v2",
      "vip_status": "gold",
      "last_purchase": "2026-02-10"
    }
  }
  ```

  ```json 200 - Replaced theme={null}
  {
    "success": true,
    "list_contact_id": "665a1b2c3d4e5f6a7b8c9d0f",
    "custom_fields": {
      "tier": "premium"
    }
  }
  ```

  ```json 400 - Validation Error theme={null}
  {
    "code": "missing_custom_fields",
    "error": "custom_fields is required"
  }
  ```

  ```json 400 - Contact Not On List theme={null}
  {
    "code": "list_contact_not_found",
    "error": "Contact is not on this list"
  }
  ```
</ResponseExample>

## Error Codes

| HTTP Status | Error Code               | Description                                                                |
| ----------- | ------------------------ | -------------------------------------------------------------------------- |
| 400         | `missing_phone_number`   | The `phone_number` field was not provided.                                 |
| 400         | `missing_list_number`    | The `list_number` field was not provided.                                  |
| 400         | `missing_custom_fields`  | The `custom_fields` field was not provided.                                |
| 400         | `invalid_custom_fields`  | The `custom_fields` field must be a JSON object.                           |
| 400         | `invalid_phone`          | The `phone_number` is not a valid E.164 phone number.                      |
| 400         | `invalid_list_number`    | The `list_number` is not a valid E.164 phone number.                       |
| 400         | `contact_not_found`      | No contact exists with the given phone number.                             |
| 400         | `list_not_found`         | No sending list with the given `list_number` exists for this account.      |
| 400         | `list_contact_not_found` | The contact exists but is not on the specified list.                       |
| 401         | `invalid_credentials`    | Missing or invalid `X-Api-Key` header.                                     |
| 403         | `account_suspended`      | Your account is suspended. Resolve outstanding billing or contact support. |
| 429         | `rate_limited`           | Request throttled; retry with exponential backoff after the window resets. |
| 500         | `internal_error`         | An unexpected server error occurred.                                       |

## Next Steps

<CardGroup cols={2}>
  <Card title="Importing Contacts" icon="upload" href="/guides/contacts/importing">
    Bulk update contacts
  </Card>

  <Card title="Create Audience" icon="users" href="/api-reference/v2/audiences/create-audience">
    Segment contacts into audiences
  </Card>
</CardGroup>
