# Manage contacts with the CardDAV protocol

You can view and manage your contacts using Google's CardDAV protocol.

Contacts are stored in the user's Google Account; most Google services have
access to the contact list. Your client application can use the CardDAV API to
create new contacts, edit or delete existing contacts, and query for contacts
that match particular criteria.

## Specifications

The full specification is not implemented, but many clients such as
[Apple iOS™ Contacts](https://support.google.com/contacts/answer/2753077?co=GENIE.Platform%3DiOS)
and macOS should interoperate correctly.

For each relevant specification, Google's CardDAV support is as follows:

- [rfc2518: HTTP Extensions for Distributed Authoring (WebDAV)](https://tools.ietf.org/html/rfc2518)
  - Supports the HTTP methods `GET`, `PUT`, `DELETE`, `OPTIONS`, and `PROPFIND`.
  - Does *not* support the HTTP methods `LOCK`, `UNLOCK`, `COPY`, `MOVE`, or `MKCOL`.
  - Does *not* support arbitrary (user-defined) WebDAV properties.
  - Does *not* support WebDAV Access Control (rfc3744).
- [rfc5995: Using POST to Add Members to WebDAV Collections](https://tools.ietf.org/html/rfc5995)
  - Supports creating new contacts without specifying an ID.
- [rfc6352: CardDAV: vCard Extensions to Web Distributed Authoring and
  Versioning (WebDAV)](https://tools.ietf.org/html/rfc6352)
  - Supports the HTTP method `REPORT`, but not all defined reports are implemented.
  - Supports providing a principal collection and a contacts collection.
- [rfc6578: Collection Synchronization for WebDAV](https://tools.ietf.org/html/rfc6578)
  - Client applications must switch to this mode of operation after the initial sync.
- [rfc6749: The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749) and [rfc6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750)
  - Supports authenticating CardDAV client programs using OAuth 2.0 HTTP Authentication. Google does not support any other authentication method. For security of contact data, we require CardDAV connections to use [HTTPS](https://en.wikipedia.org/wiki/HTTPS).
- [rfc6764: Locating Services for Calendaring Extensions to WebDAV (CalDAV) and vCard Extensions to WebDAV (CardDAV)](https://tools.ietf.org/html/rfc6764)
  - Bootstrapping of CardDAV URLs must take place according to section 6 of rfc6764.
- Supports [caldav-ctag-02: Calendar Collection Entity Tag (CTag) in CalDAV](https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-ctag.txt), which is shared between the CardDAV and CalDAV specifications. The contacts `ctag` is like a resource `ETag`; it changes when anything in the contact address book has changed. This allows the client program to quickly determine that it does not need to synchronize any changed contacts.
- Google uses VCard 3.0 as the contact encoding format. See: [rfc6350: VCard 3.0](https://tools.ietf.org/html/rfc6350).

## Google's CardDAV requires OAuth 2.0

Google's CardDAV interface requires OAuth 2.0. Refer to the linked
documentation below for information on using OAuth 2.0 to access Google APIs:

- [Using OAuth 2.0 to Access Google APIs](https://developers.google.com/identity/protocols/oauth2)
- [Using OAuth 2.0 for Installed Applications](https://developers.google.com/identity/protocols/oauth2/native-app)

## Connecting to Google's CardDAV server

The CardDAV protocol allows discovery of the address book and contact resources
URIs. You must not hardcode any URI as they could change at any time.

Client applications must use HTTPS, and `OAuth 2.0` authentication must be
provided for the user's Google account. The CardDAV server will not
authenticate a request unless it arrives over HTTPS with OAuth 2.0
authentication of a Google account, and your application is registered on
DevConsole. Any attempt to connect over HTTP with Basic authentication or with
an email/password that doesn't match a Google account results in an HTTP
`401 Unauthorized` response code.

To use CardDAV, your client program must initially connect to the canonical
discovery path by performing an HTTP `PROPFIND` on:

    https://www.googleapis.com/.well-known/carddav

Once redirected (`HTTP 301`) to an Address Book Resource, your client program
can then perform a `PROPFIND` on it to discover the
`DAV:current-user-principal`, `DAV:principal-URL`, and `addressbook-home-set`
properties. Your client program can then discover the principal address book by
performing a `PROPFIND` on the `addressbook-home-set` and looking for the
`addressbook` and `collection` resources. A full description of this process
is beyond the scope of this document. See
[rfc6352](https://tools.ietf.org/html/rfc6352) for more details.

The redirect path returned in the `HTTP 301` response through a `PROPFIND` on
the well-known URI must **not** be permanently cached (as per
[rfc6764](https://tools.ietf.org/html/rfc6764)). Devices should retry well-known
URI discovery periodically to verify if the cached path is still up to date and
resync if the path ever changes. Google recommends a rate of every 2-4 weeks.

## Resources

CardDAV uses REST concepts. Client applications act on resources that are
designated by their URIs. The current URI structure is specified here to help
developers understand the concepts in the following section. The structure may
change and must not be hardcoded. Rather, the resources should be discovered
according to the RFC.

1. **Principal**
   - https://www.googleapis.com/carddav/v1/principals/`userEmail`
2. **Home Set**
   - https://www.googleapis.com/carddav/v1/principals/`userEmail`/lists
3. **Address Book**
   - https://www.googleapis.com/carddav/v1/principals/`userEmail`/lists/default
4. **Contact**
   - https://www.googleapis.com/carddav/v1/principals/`userEmail`/lists/default/`contactId`

## Synchronizing Contacts

The following is a general description of the operations supported. Developers
should look for the details in the relevant RFC. Requests and responses are
mostly encoded in XML. These are the main operations used by client
applications for synchronization:

- **Using CTag**
  - Client programs use the `getctag` `PROPFIND` request on the Address Book resource to determine if any contact has changed on the server and therefore whether a synchronization is needed. The value of this property is guaranteed to change if any contact changes. Client applications should store this value and use it only on the initial sync and as a fallback when a `sync-token` is invalidated. Periodically polling for the `getctag` property will result in throttling.
- **Using sync-token**
  - Client programs use the `sync-token` `PROPFIND` request on the Address Book to obtain the `sync-token` representing its current state. Client applications must store this value and issue periodic `sync-collection` `REPORT` requests to determine changes since the last issued `sync-token`. Issued tokens are valid for 29 days, and the `REPORT` response will contain a new `sync-token`.
- **Using ETags**
  - Client applications issue a `getetag` `PROPFIND` request on the Address Book resource (with `DEPTH` header equal to `DEPTH_1`). By maintaining the `ETag` value of each contact, a client program can request the value of contacts that had their `ETag` changed.
- **Retrieving contacts**
  - Client applications retrieve contacts by issuing an `addressbook-multiget` `REPORT` request. Given a list of contact URIs, the report returns all the requested contacts as VCard 3.0 values. Each entry includes an `ETag` for the contact.
- **Inserting a contact**
  - Client applications issue a `POST` request with the new contact in VCard 3.0 format. The response will contain the ID of the new contact.
- **Updating a contact**
  - Client applications issue a `PUT` request with the updated contact in VCard 3.0 format. The contact is updated if the contact already exists in the address book.
  - Client applications should include an `If-Match` header with the contact's currently known `ETag`. The server will then reject the `PUT` request (with `HTTP 412`) if the current `ETag` on the server is different from the `ETag` sent by the client program. This allows for optimistic serialization of updates.
- **Deleting a contact**
  - Client applications delete a contact by issuing a `DELETE` request against the contact URI.