Skip to content
Skip to main content

How to create and update contacts

Last updated:

A sales rep finishes a call and you want to write the new lead straight into their Gmail address book, or a meeting wraps and you need to push an attendee into their Outlook contacts so it shows up everywhere they read mail. Writing to each provider natively means juggling Google’s People API and Microsoft Graph, with two auth models and two field schemas. The Nylas Contacts API gives you one create, update, and delete flow that writes to a Gmail or Outlook address book through the same request.

This recipe walks through the three write operations and the provider rules that decide whether a write sticks.

Create a contact with a single POST to /v3/grants/{grant_id}/contacts. The body accepts 17 contact fields, and only given_name is required. Nylas writes the record into the user’s address book and returns the full contact with its new id, so you can store that ID and update or delete the contact later.

The request below sends a complete contact: name parts, two emails, two phone numbers, a birthday, groups, and a source of address_book. Every field except given_name is optional, so a minimal create can be just a name plus one email. The response echoes the stored object with a server-assigned id.

Writes land in the address book on Google, Microsoft, iCloud, IMAP, and EWS accounts. Set source to address_book so the contact is saved and editable; you can’t create a contact with source set to inbox, since those are read-only auto-generated records. The full field list lives in the Contacts API reference.

Update a contact with a PUT to /v3/grants/{grant_id}/contacts/{contact_id}, using the id you got back from the create call. One detail trips people up: PUT replaces the whole contact object, it doesn’t patch single fields. Send the complete contact you want stored, because any field you leave out gets cleared on the provider.

The SDK examples below send a small body to keep them readable, but treat that as a pattern, not a partial update. To change one phone number, read the contact first, change that field in the object you got back, then send the entire object. The response returns the updated contact with the same id.

Updates need the same write scope as create, and they only work on contacts whose source is address_book. Trying to edit an auto-generated inbox contact returns an error, so check the source field before you offer an edit action in your UI.

Delete a contact with a DELETE to /v3/grants/{grant_id}/contacts/{contact_id}. This is a single call with no request body, and it removes the contact from the user’s actual provider account, not just from a Nylas cache. The contact disappears from Gmail or Outlook too, so treat it as a destructive action and confirm with the user first.

The examples below delete one contact by ID. A successful delete returns a request_id so you can correlate the call in logs. There’s no soft-delete or trash step here, so once the call succeeds the record is gone from the provider.

Like update, delete only applies to address_book contacts. Auto-generated inbox contacts aren’t deletable through the API, because the provider regenerates them from message participants.

Writes behave differently from reads, and a handful of provider rules decide whether a POST or PUT actually sticks. The most important one is the source field, which Nylas recognizes in three values: address_book, domain, and inbox. Only address_book contacts are writable. The inbox source holds auto-created records built from message participants, and domain holds the organization directory, so both are read-only and reject create, update, and delete calls.

Write scopes are stricter than read scopes. Create, update, and delete all require Google’s https://www.googleapis.com/auth/contacts scope or Microsoft’s Contacts.ReadWrite. The read-only contacts.readonly or Contacts.Read scopes won’t authorize a write, so request the read-write scope at OAuth time if your app edits contacts. The Contacts API scopes page lists the exact strings per provider.

Field support varies by provider, and you’ll hit these limits in practice:

FieldGoogleMicrosoft / EWSiCloud / IMAP
groupsMultipleAt most one group per contactAt most one
web_pagesMultipleOne, and type must be workAt most one
suffixSupportedDropped on EWSSupported

Groups also work differently on write. You pass groups as an array of { "id": "..." } objects, and the group has to already exist on the provider before you reference it. Microsoft, iCloud, and IMAP cap a contact at one group, so don’t send several group IDs to those accounts. To find valid group IDs first, see Organize contacts with groups. For the per-provider write rules straight from the source, Google documents its contact model in the People API documentation.