The Contacts API normalizes explicit provider-backed groups so your application can list them, filter contacts by membership, and update a contact’s group IDs through one contract.
List a user’s Contact Groups
Section titled “List a user’s Contact Groups”Send GET /v3/grants/{grant_id}/contacts/groups. Each result includes the provider-scoped id that you use in a Contact filter or write.
curl --compressed --request GET \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/contacts/groups' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --header 'Content-Type: application/json'{ "request_id": "1", "data": [ { "grant_id": "<NYLAS_GRANT_ID>", "group_type": "system", "id": "starred", "name": "starred", "object": "contact_group", "path": "parentId/starred" }, { "grant_id": "<NYLAS_GRANT_ID>", "group_type": "user", "id": "friends", "name": "friends", "object": "contact_group", "path": "parentId/friends" } ], "next_cursor": "2"}import Nylas from "nylas";
const nylas = new Nylas({ apiKey: "<NYLAS_API_KEY>", apiUri: "<NYLAS_API_URI>",});
async function listContactGroups() { try { const groups = await nylas.contacts.groups({ identifier: "<NYLAS_GRANT_ID>", });
console.log("Contact groups:", groups); } catch (error) { console.error("Error listing contact groups:", error); }}
listContactGroups();from nylas import Client
nylas = Client( "<NYLAS_API_KEY>", "<NYLAS_API_URI>")
grant_id = "<NYLAS_GRANT_ID>"
contact_groups = nylas.contacts.list_groups( grant_id,)
print(contact_groups)For native iCloud and Yahoo grants, Nylas returns explicit group vCard records only. CardDAV address-book collections are containers, not Contact Groups. Combined views such as iCloud All Contacts are also excluded because users can’t manage them as groups.
Native CardDAV group IDs start with carddav_group_v1_ and encode the canonical provider href. Treat them as opaque, untrusted, and grant-bound. Nylas validates each href against the address books discovered for that grant. A provider-side move can change a group href and ID, and Nylas doesn’t keep an old-to-new mapping.
Filter contacts by group
Section titled “Filter contacts by group”Pass a returned group ID as the group parameter on GET /contacts:
curl --request GET \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/contacts?group=<CONTACT_GROUP_ID>' \ --header 'Authorization: Bearer <NYLAS_API_KEY>'The response returns Contact objects whose groups array includes that explicit group. This filter is unsupported for EWS.
For iCloud, Nylas uses a filtered CardDAV addressbook-query for group vCard records. The response can take longer than a small address-book list because Nylas also resolves member href values.
Yahoo returns 400 for that filtered query, so Nylas uses a bounded address-book inventory followed by CardDAV addressbook-multiget requests. Nylas reads Yahoo membership from legacy member reference properties. The vCard CATEGORIES property doesn’t represent group membership. Large address books or group cards can exceed safety bounds and return a provider error instead of an unbounded scan.
Update Contact Group membership
Section titled “Update Contact Group membership”There are no Contacts API endpoints to create, rename, or delete Contact Group resources. Manage membership through the Contact groups field and reference only group IDs already returned for the same grant.
curl --request PUT \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/contacts/<CONTACT_ID>' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{ "groups": [ { "id": "<CONTACT_GROUP_ID>" }, { "id": "<ANOTHER_CONTACT_GROUP_ID>" } ] }'const contact = await nylas.contacts.update({ identifier: "<NYLAS_GRANT_ID>", contactId: "<CONTACT_ID>", requestBody: { groups: [ { id: "<CONTACT_GROUP_ID>" }, { id: "<ANOTHER_CONTACT_GROUP_ID>" }, ], },});contact = nylas.contacts.update( "<NYLAS_GRANT_ID>", "<CONTACT_ID>", request_body={ "groups": [ {"id": "<CONTACT_GROUP_ID>"}, {"id": "<ANOTHER_CONTACT_GROUP_ID>"}, ] },)Creating a Contact with groups adds the new provider contact to those groups. Updating groups replaces its membership list. Deleting a Contact also removes the provider’s membership references.
Native CardDAV membership writes use ETag values for conditional updates. If a contact or group changes during the operation, Nylas can return a conflict or partial-failure error after some provider resources have changed. Fetch the Contact and Contact Groups again before retrying so your application reconciles current provider state.
Native Yahoo Contact mutations don’t emit contact.updated or contact.deleted notifications. Native iCloud mutations can emit those triggers, but the iCloud change feed is polled and best effort. See iCloud contact notifications.
List Contact Groups from the terminal
Section titled “List Contact Groups from the terminal”The Nylas CLI uses the same provider IDs as the API:
nylas contacts groups listnylas contacts search --group <contact-group-id>See the contacts groups list and contacts search command references.
What’s next
Section titled “What’s next”- Using the Contacts API for the Contact schema and CardDAV ID contract
- Create and update contacts for provider write behavior
- List iCloud contacts for native iCloud CardDAV behavior
- List Yahoo contacts for the Yahoo query fallback and notification limitation
- Contacts API scopes for provider permissions