Introduction
# Google Contacts
Access the Google People API with managed OAuth authentication. Manage contacts, contact groups, and search your address book.
## Quick Start
```bash # List contacts python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/google-contacts/v1/people/me/connections?personFields=names,emailAddresses,phoneNumbers&pageSize=10') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
## Base URL
``` https://gateway.maton.ai/google-contacts/{native-api-path} ```
Replace `{native-api-path}` with the actual Google People API endpoint path. The gateway proxies requests to `people.googleapis.com` and automatically injects your OAuth token.
## Authentication
All requests require the Maton API key in the Authorization header:
``` Authorization: Bearer $MATON_API_KEY ```
**Environment Variable:** Set your API key as `MATON_API_KEY`:
```bash export MATON_API_KEY="YOUR_API_KEY" ```
### Getting Your API Key
1. Sign in or create an account at [maton.ai](https://maton.ai) 2. Go to [maton.ai/settings](https://maton.ai/settings) 3. Copy your API key
## Connection Management
Manage your Google Contacts OAuth connections at `https://ctrl.maton.ai`.
### List Connections
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=google-contacts&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Create Connection
```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'google-contacts'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Get Connection
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
**Response:** ```json { "connection": { "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80", "status": "ACTIVE", "creation_time": "2025-12-08T07:20:53.488460Z", "last_updated_time": "2026-01-31T20:03:32.593153Z", "url": "https://connect.maton.ai/?session_token=...", "app": "google-contacts", "metadata": {} } } ```
Open the returned `url` in a browser to complete OAuth authorization.
### Delete Connection
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Specifying Connection
If you have multiple Google Contacts connections, specify which one to use with the `Maton-Connection` header:
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/google-contacts/v1/people/me/connections?personFields=names&pageSize=10') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
If omitted, the gateway uses the default (oldest) active connection.
## API Reference
### Contact Operations
#### List Contacts
```bash GET /google-contacts/v1/people/me/connections?personFields=names,emailAddresses,phoneNumbers&pageSize=100 ```
**Query Parameters:** - `personFields` (required): Comma-separated list of fields to return (see Person Fields section) - `pageSize`: Number of contacts to return (max 1000, default 100) - `pageToken`: Token for pagination - `sortOrder`: `LAST_MODIFIED_ASCENDING`, `LAST_MODIFIED_DESCENDING`, `FIRST_NAME_ASCENDING`, or `LAST_NAME_ASCENDING`
**Response:** ```json { "connections": [ { "resourceName": "people/c1234567890", "names": [{"displayName": "John Doe", "givenName": "John", "familyName": "Doe"}], "emailAddresses": [{"value": "[email protected]"}], "phoneNumbers": [{"value": "+1-555-0123"}] } ], "totalPeople": 1, "totalItems": 1, "nextPageToken": "..." } ```
#### Get Contact
```bash GET /google-contacts/v1/people/{resourceName}?personFields=names,emailAddresses,phoneNumbers ```
Use the resource name from list or create operations (e.g., `people/c1234567890`).
#### Create Contact
```bash POST /google-contacts/v1/people:createContact Content-Type: application/json
{ "names": [{"givenName": "John", "familyName": "Doe"}], "emailAddresses": [{"value": "[email protected]"}], "phoneNumbers": [{"value": "+1-555-0123"}], "organizations": [{"name": "Acme Corp", "title": "Engineer"}] } ```
#### Update Contact
```bash PATCH /google-contacts/v1/people/{resourceName}:updateContact?updatePersonFields=names,emailAddresses Content-Type: application/json
{ "etag": "%EgcBAgkLLjc9...", "names": [{"givenName": "John", "familyName": "Smith"}], "emailAddresses": [{"value": "[email protected]"}] } ```
**Note:** Include the `etag` from the get/list response to ensure you're updating the latest version.
#### Delete Contact
```bash DELETE /google-contacts/v1/people/{resourceName}:deleteContact ```
#### Batch Get Contacts
```bash GET /google-contacts/v1/people:batchGet?resourceNames=people/c123&resourceNames=people/c456&personFields=names,emailAddresses ```
#### Batch Create Contacts
```bash POST /google-contacts/v1/people:batchCreateContacts Content-Type: application/json
{ "contacts": [ { "contactPerson": { "names": [{"givenName": "Alice", "familyName": "Smith"}], "emailAddresses": [{"value": "[email protected]"}] } }, { "contactPerson": { "names": [{"givenName": "Bob", "familyName": "Jones"}], "emailAddresses": [{"value": "[email protected]"}] } } ], "readMask": "names,emailAddresses" } ```
#### Batch Delete Contacts
```bash POST /google-contacts/v1/people:batchDeleteContacts Content-Type: application/json
{ "resourceNames": ["people/c123", "people/c456"] } ```
#### Search Contacts
```bash GET /google-contacts/v1/people:searchContacts?query=John&readMask=names,emailAddresses ```
**Note:** Search results may have a slight delay for newly created contacts due to indexing.
### Contact Group Operations
#### List Contact Groups
```bash GET /google-contacts/v1/contactGroups?pageSize=100 ```
**Response:** ```json { "contactGroups": [ { "resourceName": "contactGroups/starred", "groupType": "SYSTEM_CONTACT_GROUP", "name": "starred", "formattedName": "Starred" }, { "resourceName": "contactGroups/abc123", "groupType": "USER_CONTACT_GROUP", "name": "Work", "formattedName": "Work", "memberCount": 5 } ], "totalItems": 2 } ```
#### Get Contact Group
```bash GET /google-contacts/v1/contactGroups/{resourceName}?maxMembers=100 ```
Use `contactGroups/starred`, `contactGroups/family`, etc. for system groups, or the resource name for user groups.
#### Create Contact Group
```bash POST /google-contacts/v1/contactGroups Content-Type: application/json
{ "contactGroup": { "name": "Work Contacts" } } ```
#### Delete Contact Group
```bash DELETE /google-contacts/v1/contactGroups/{resourceName}?deleteContacts=false ```
Set `deleteContacts=true` to also delete the contacts in the group.
#### Batch Get Contact Groups
```bash GET /google-contacts/v1/contactGroups:batchGet?resourceNames=contactGroups/starred&resourceNames=contactGroups/family ```
#### Modify Group Members
Add or remove contacts from a group:
```bash POST /google-contacts/v1/contactGroups/{resourceName}/members:modify Content-Type: application/json
{ "resourceNamesToAdd": ["people/c123", "people/c456"], "resourceNamesToRemove": ["people/c789"] } ```
### Other Contacts
Other contacts are people you've interacted with (e.g., via email) but haven't explicitly added to your contacts.
#### List Other Contacts
```bash GET /google-contacts/v1/otherContacts?readMask=names,emailAddresses&pageSize=100 ```
#### Copy Other Contact to My Contacts
```bash POST /google-contacts/v1/{resourceName}:copyOtherContactToMyContactsGroup Content-Type: application/json
{ "copyMask": "names,emailAddresses,phoneNumbers" } ```
## Person Fields
Use these fields with `personFields` or `readMask` parameters:
| Field | Description | |-------|-------------| | `names` | Display name, given name, family name | | `emailAddresses` | Email addresses with type | | `phoneNumbers` | Phone numbers with type | | `addresses` | Postal addresses | | `organizations` | Company, title, department | | `biographies` | Bio/notes about the person | | `birthdays` | Birthday information | | `urls` | Website URLs | | `photos` | Profile photos | | `memberships` | Contact group memberships | | `metadata` | Source and update information |
Multiple fields: `personFields=names,emailAddresses,phoneNumbers,organizations`
## Pagination
Use `pageSize` and `pageToken` for pagination:
```bash GET /google-contacts/v1/people/me/connections?personFields=names&pageSize=100&pageToken=NEXT_PAGE_TOKEN ```
Response includes pagination info:
```json { "connections": [...], "totalPeople": 500, "nextPageToken": "...", "nextSyncToken": "..." } ```
Continue fetching with `pageToken` until `nextPageToken` is not returned.
## Code Examples
### JavaScript
```javascript const response = await fetch( 'https://gateway.maton.ai/google-contacts/v1/people/me/connections?personFields=names,emailAddresses&pageSize=50', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json(); ```
### Python
```python import os import requests
response = requests.get( 'https://gateway.maton.ai/google-contacts/v1/people/me/connections', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, params={ 'personFields': 'names,emailAddresses,phoneNumbers', 'pageSize': 50 } ) data = response.json() ```
## Notes
- Resource names for contacts follow the pattern `people/c{id}` (e.g., `people/c1234567890`) - Resource names for contact groups follow the pattern `contactGroups/{id}` (e.g., `contactGroups/abc123`) - System contact groups include: `starred`, `friends`, `family`, `coworkers`, `myContacts`, `all`, `blocked` - The `personFields` parameter is required for most read operations - When updating contacts, include the `etag` to prevent overwriting concurrent changes - Mutate requests for the same user should be sent sequentially to avoid increased latency and failures - IMPORTANT: When using curl commands, use `curl -g` when URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may not expand correctly in some shell environments
## Error Handling
| Status | Meaning | |--------|---------| | 400 | Missing Google Contacts connection or invalid request | | 401 | Invalid or missing Maton API key | | 403 | Permission denied (check OAuth scopes) | | 404 | Contact or group not found | | 429 | Rate limited | | 4xx/5xx | Passthrough error from Google People API |
### Troubleshooting: API Key Issues
1. Check that the `MATON_API_KEY` environment variable is set:
```bash echo $MATON_API_KEY ```
2. Verify the API key is valid by listing connections:
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Troubleshooting: Invalid App Name
1. Ensure your URL path starts with `google-contacts`. For example:
- Correct: `https://gateway.maton.ai/google-contacts/v1/people/me/connections` - Incorrect: `https://gateway.maton.ai/v1/people/me/connections`
## Resources
- [Google People API Overview](https://developers.google.com/people/api/rest) - [People Resource](https://developers.google.com/people/api/rest/v1/people) - [Contact Groups Resource](https://developers.google.com/people/api/rest/v1/contactGroups) - [Person Fields Reference](https://developers.google.com/people/api/rest/v1/people#Person) - [Maton Community](https://discord.com/invite/dBfFAcefs2) - [Maton Support](mailto:[email protected])