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

# Change company external ID

> Assign a new external identifier to a company in gu1 with a mandatory audit reason; denormalized references in transactions and events are updated.

## Overview

Use this endpoint when you need to change an entity's **external ID**. It is **not** possible to change `externalId` via `PATCH /entities/:id`, `PATCH /entities/by-external-id/:externalId`, or `PATCH /entities/by-tax-id/:taxId` — those routes ignore any `externalId` in the body.

The operation:

* Validates that the new external ID is unique within your organization.
* Updates the entity row.
* When the previous external ID was non-empty and differs from the new value, rewrites denormalized references on **transactions** (`origin_external_id` / `destination_external_id`) and **user events** (`entity_external_id` / rows matched by `entity_id`), inside the same database transaction.

You must send a **reason** (minimum 5 characters) for compliance and audit. The change is recorded via the unified audit service (metadata includes `externalIdChangeReason` and `source: change_external_id_endpoint`).

## Endpoint

```
POST https://api.gu1.ai/entities/change-external-id
```

## Authentication

```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```

## Request Body

Provide **exactly one** lookup field to identify the entity, plus the new value and reason.

<ParamField body="entityId" type="string (uuid)">
  Internal gu1 entity ID. Use this when you already store our UUID.
</ParamField>

<ParamField body="externalId" type="string">
  **Lookup only**: the entity's **current** external ID (not the new value). Use when you identify entities by your own ID in daily operations.
</ParamField>

<ParamField body="taxId" type="string">
  **Lookup only**: tax ID of an entity that **already has** a non-empty tax ID stored. Matching uses the same alphanumeric normalization as elsewhere (ignores punctuation). If more than one entity matches, the API returns `409` with code `AMBIGUOUS_TAX_ID_LOOKUP` — use `entityId` or `externalId` instead.
</ParamField>

<ParamField body="newExternalId" type="string" required>
  The new external identifier (trimmed on the server). Must not be in use by another entity in the organization.
</ParamField>

<ParamField body="reason" type="string" required>
  Audit reason, **at least 5 characters** (after trim), max 4000.
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  `true` when the request completed successfully.
</ResponseField>

<ResponseField name="changed" type="boolean">
  `false` if `newExternalId` equals the current value (no-op); `true` if the entity was updated.
</ResponseField>

<ResponseField name="entity" type="object">
  Current entity snapshot after the operation.
</ResponseField>

## Errors

| HTTP | Code / shape                         | Meaning                                             |
| ---- | ------------------------------------ | --------------------------------------------------- |
| 400  | `VALIDATION_ERROR`, `INVALID_LOOKUP` | Zero or more than one lookup field, or invalid body |
| 404  | `NOT_FOUND`                          | No entity matches the lookup                        |
| 409  | `DUPLICATE_EXTERNAL_ID`              | Another entity already uses `newExternalId`         |
| 409  | `AMBIGUOUS_TAX_ID_LOOKUP`            | Several entities share the normalized tax ID        |

## Example

```bash theme={null}
curl -X POST "https://api.gu1.ai/entities/change-external-id" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entityId": "550e8400-e29b-41d4-a716-446655440000",
    "newExternalId": "crm_customer_8842",
    "reason": "CRM migration — align ID with Salesforce Account Id"
  }'
```

Lookup by current external ID:

```json theme={null}
{
  "externalId": "legacy_key_001",
  "newExternalId": "unified_key_001",
  "reason": "Consolidating duplicate external keys after data cleanup"
}
```

Lookup by tax ID:

```json theme={null}
{
  "taxId": "20-12345678-9",
  "newExternalId": "ar_person_maria_01",
  "reason": "Standardize external IDs for Argentina retail onboarding"
}
```
