# Update an account

> Changes an account's details: name or company, email, phone, address, your reference (crmkey), tags, metadata, locale and timezone. Callers that render Shuttle'

Changes an account's details: name or company, email, phone, address, your reference (crm_key), tags, metadata, locale and timezone. Callers that render Shuttle's dynamic form can send the form's values instead. When the account is a linked duplicate the edit is applied to the head of its group, and on a CRM-linked account the changed values are pushed to the CRM and read back, so the CRM's copy is what Shuttle stores.

### Where you can do this

- Merchant View: [Create or edit an account](/platforms/user-guides/admin-account-form/) (Save)
- Merchant View: Save
- API: [Update an account](/platforms/reference/operations/updateaccount/) (`PUT /accounts/{account_id}`)

### Before you start

- The account exists. Any status is accepted; there is no lock or version check, so two edits at once are applied in arrival order.
- The account may be a linked duplicate: the edit lands on the head of its group (the parent-most account), and the response carries that account, whose id may differ from the one in the path.
- The account's CRM determines how values are stored: a disconnected (temporary) account keeps Shuttle's own copy; a CRM-linked account (`disconnected_account` false) is pushed to and re-read from its CRM on every change to its details.

### Inputs

| Input | Required | Meaning and constraints |
|---|---|---|
| first_name | no | The account holder's first name; trimmed. Ignored when `values` is sent |
| last_name | no | The account holder's last name; trimmed. Ignored when `values` is sent |
| company | no | Company name; trimmed. Ignored when `values` is sent |
| email | no | Email address; trimmed. Shuttle applies no format check; an external CRM may refuse it (see Rules). Ignored when `values` is sent |
| phone | no | Phone number, any format. Ignored when `values` is sent |
| address | no | Object read for `line1` to `line6` and `country` (ISO code) only; any other key in it is dropped. On a CRM-linked account only the lines sent are changed; on a disconnected account see the replace-all rule. Ignored when `values` is sent |
| tags | no | Comma-separated references for searching, sent as one string; replaces the existing tags. Read whether or not `values` is sent. An array is not what the server reads (not traced to an error) |
| metadata | no | Custom key-value object; replaces the existing metadata as a whole. Read whether or not `values` is sent |
| locale | no | The customer's language, used for communications. Ignored when `values` is sent |
| timezone | no | The customer's timezone in IANA format, used for scheduling. Kept by Shuttle only; never sent to the CRM. Ignored when `values` is sent |

### Rules

*Checked by* **the API** means Shuttle refuses the request however it is sent; a screen name means only that screen refuses it, and a direct API call would be accepted.

| Rule | Checked by | What you see |
|---|---|---|
| The account must exist | The API | NOT_FOUND: "Account not found" |
| Editing a linked duplicate edits the head of its group; the response is the head account | The API | (behaviour) |
| On a CRM-linked account the details are pushed to the CRM only when the merged values actually differ from what is stored; the account is then re-read from the CRM and the CRM's copy is what Shuttle keeps. Shuttle's own CRM echoes the values back unchanged; an external CRM's answer wins over what was sent | The API | (behaviour) |
| A CRM that refuses or fails the push fails the edit; tags, metadata and crm_key changes made in the same call are not saved either | The API | INVALID_REQUEST or VALIDATION_ERROR with the CRM's message (BOLT-3031 / BOLT-3036); other integration failures surface as INVALID with a "BOLT-2xxx" message |
| If the CRM push succeeds but the re-read fails, the failure is logged and the edit is reported as successful | The API | (behaviour) |
| `timezone` is applied last, saved only when it changed, and never sent to the CRM | The API | (behaviour) |
| `tags`, `metadata` and `crm_key` replace the stored value only when present in the request; `null` or absent leaves them alone. Shuttle applies no uniqueness check on crm_key of its own | The API | (behaviour) |
| Sending `crm_key` to a disconnected account records the key but leaves the account disconnected; it does not connect it to the CRM. Registering a disconnected account with the CRM is a separate Shuttle operation not exposed through this route | The API | (behaviour) |
| A legacy address shape `country.<code>.line1` (country code inside the key) is accepted and flattened to `country.line1` | The API | (behaviour) |
| Merchant View sends only the form's `values` and `tags`; the fixed fields, `crm_key` and `metadata` are never sent from a screen (a CRM key can only be changed from a screen if the CRM's form carries it) | Merchant View screen | (behaviour) |
| Which fields are mandatory on the screen is the CRM's form definition; Shuttle's own CRM marks none mandatory and validates no formats | Merchant View screen (inline validation); Shuttle's own CRM | inline validation |

### What happens

- The account's details are updated and the response carries the account as it now stands (the head of the group when the account is a linked duplicate, so its id may differ from the one requested). `expand` on the request is honoured on the response.
- On a CRM-linked account the changed values are pushed to the CRM and the account re-read from it, so what is shown afterwards is the CRM's version; Shuttle's own CRM stores exactly what was sent.
- ACCOUNT.UPDATE goes to the client's webhook subscribers when the details changed (see Rules for the tags/metadata/crm_key/timezone-only exception).
- The account is searchable by its new name, email, phone, address, tags and crm_key straight away.

### Who can do this

- Roles: Admin and Support.
- Permission keys (for clients managing permissions directly): `account`, `checkout` or `*` on the client or on one of the account's divisions, checked at the API before the request goes any further; without it UNAUTHORIZED: "Unauthorized". An account (customer) session may only edit its own account; another id gives NO_PERMISSION: "No permissions".

### Related

- [Create an account](/platforms/user-guides/rules-account-create/)