Skip to main content
Edits a stored contact by delta, never by replacement. You name the fields that change; everything else keeps its stored value, so you never have to read the record and re-send it. This is the same shape update_calendar_event uses for attendees, and for the same reason: a full-replacement object forces a caller to read the whole record first and silently drops anything it did not know to re-send. Here that would mean an agent correcting a postal code wiping a phone number a CardDAV client added an hour earlier. Find the contact_id and the [a0]-style handles with search_contacts — the id appears in both response formats, the handles in detailed.
The edit syncs to every device connected over CardDAV.

Parameters

string
required
The contact id, as printed by search_contacts under contact_id.
string
New display name. Omit to keep the stored one.
string
New organization; "" clears it. Omit to keep the stored one.
string
New note, replacing every note stored on the contact; "" clears them. Omit to keep them. (A contact edited in a CardDAV client can carry more than one note — search_contacts shows them joined, and this field replaces the whole thing rather than writing beside them.)
object[]
Email addresses to add, each { address, context? }. Re-adding an address already on the card is a no-op; an address that belongs to a different contact is rejected, the same way create_contact rejects it.
string[]
Email addresses to remove, case-insensitive.
object[]
Phone numbers to add, each { number, label? }.
string[]
Phone numbers to remove, each given either as its [p0] handle or as the number itself.
object[]
Postal addresses to add — same components as create_contact.
object[]
Corrections to stored postal addresses: each entry names a key (the [a0] handle) plus only the components that change. Everything left out keeps its stored value — including parts of an imported address this API has no field for, such as a separately stored house number, apartment, or floor. Correcting street replaces the whole street line, which is what search_contacts showed you.
string[]
Postal addresses to remove, each given either as its [a0] handle or as its label (home, work).
At least one field beyond contactId is required.

Example — correcting one component

Call
Result
The street, city, country, organization, email, phone, and note were never sent — and are all still there.

Errors

  • No contact with id <id>. — the id does not resolve. Find it with search_contacts.
  • <address> already belongs to a different contact (contact_id: …) — remove it there first, or edit that record instead.
  • This contact has no postal address <key>. Stored handles: … — a correction was addressed to a handle the card does not carry. Nothing is written; read the handles back with search_contacts in detailed format.
  • update_contact needs at least one field to change. — only contactId was passed.

What this tool does not do

It does not merge two contacts, and it does not change a record’s source. A derived record you correct stays derived — the correction is protected regardless, because collection only ever fills blanks and never overwrites a field that already has a value.