## Update a contact `POST /update-external-contact` Updates an existing contact's name, email, note, or custom metadata. The contact's phone number cannot be changed. Returns 404 if the contact does not belong to your account. At least one of `firstName`, `lastName`, `email`, `customFields`, or `note` must be present. A request carrying only `contactId` returns 400. The phone number cannot be changed. ### Request body - `contactId` (string, required) — The contact id, as returned by the create or list endpoints. - `firstName` (string) — New first name for the contact. - `lastName` (string) — New last name for the contact. - `email` (string) — New email address for the contact. - `note` (string) — Free-form note stored on the contact. - `customFields` (object) — Replaces the entire stored customFields object — fetch the current contact and merge client-side to preserve existing keys. Plain object only; max 10,000 characters when JSON-serialized. > **How customFields is validated** > > Three distinct `400` bodies come out of the same check, on every endpoint that accepts `customFields`: `customFields must be a JSON object of key/value pairs` when the value is not a plain object, `customFields must be a JSON-serializable object` when it contains something that cannot be stringified, and `customFields JSON exceeds maximum length of 10000 characters` past the size cap. That cap counts characters of serialized JSON, not bytes — non-ASCII values reach it later than their byte size suggests. > **customFields is replaced, not merged** > > Sending `customFields` on an update overwrites the entire stored object. To add or change one key, fetch the contact first, merge on your side, and send the full object back. **Request — cURL** ```bash curl -X POST https://api.tryprojectblue.com/update-external-contact \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contactId": "cmm4k2p1z0001s6ry9x8u7q3v", "note": "VIP customer — prefers texts over calls", "customFields": { "orderId": "ord_18342", "plan": "enterprise" } }' ``` **Response — 200 OK** ```json { "contact": { "id": "cmm4k2p1z0001s6ry9x8u7q3v", "firstName": "Jamie", "lastName": "Rivera", "phoneNumber": "+15551234567", "email": "jamie@example.com", "customFields": { "orderId": "ord_18342", "plan": "enterprise" }, "note": "VIP customer — prefers texts over calls", "createdAt": "2026-08-14T17:22:05.118Z", "updatedAt": "2026-08-16T09:03:41.760Z" } } ``` **Response — 404** ```json { "error": "Contact not found" } ``` **Response — 400 — no fields** ```json { "error": "At least one updatable field is required (firstName, lastName, email, customFields, note). phoneNumber cannot be updated." } ``` **Response — 400 — customFields** ```json { "error": "customFields JSON exceeds maximum length of 10000 characters" } ```