Access the Google People API with managed OAuth authentication. Manage contacts, contact groups, and search your address book.
# List contacts
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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
https://api.maton.ai/google-contacts/{native-api-path}
Maton proxies requests to people.googleapis.com and automatically injects your OAuth token.
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:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Google Contacts OAuth connections at https://api.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'google-contacts'}).encode()
req = urllib.request.Request('https://api.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
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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:
{
"connection": {
"connection_id": "{connection_id}",
"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.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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
If you have multiple Google Contacts connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
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 paginationsortOrder: LAST_MODIFIED_ASCENDING, LAST_MODIFIED_DESCENDING, FIRST_NAME_ASCENDING, or LAST_NAME_ASCENDINGResponse:
{
"connections": [
{
"resourceName": "people/c1234567890",
"names": [{"displayName": "John Doe", "givenName": "John", "familyName": "Doe"}],
"emailAddresses": [{"value": "john@example.com"}],
"phoneNumbers": [{"value": "+1-555-0123"}]
}
],
"totalPeople": 1,
"totalItems": 1,
"nextPageToken": "..."
}
GET /google-contacts/v1/people/{resourceName}?personFields=names,emailAddresses,phoneNumbers
Use the resource name from list or create operations (e.g., people/c1234567890).
POST /google-contacts/v1/people:createContact
Content-Type: application/json
{
"names": [{"givenName": "John", "familyName": "Doe"}],
"emailAddresses": [{"value": "john@example.com"}],
"phoneNumbers": [{"value": "+1-555-0123"}],
"organizations": [{"name": "Acme Corp", "title": "Engineer"}]
}
PATCH /google-contacts/v1/people/{resourceName}:updateContact?updatePersonFields=names,emailAddresses
Content-Type: application/json
{
"etag": "%EgcBAgkLLjc9...",
"names": [{"givenName": "John", "familyName": "Smith"}],
"emailAddresses": [{"value": "john.smith@example.com"}]
}
Note: Include the etag from the get/list response to ensure you're updating the latest version.
DELETE /google-contacts/v1/people/{resourceName}:deleteContact
GET /google-contacts/v1/people:batchGet?resourceNames=people/c123&resourceNames=people/c456&personFields=names,emailAddresses
POST /google-contacts/v1/people:batchCreateContacts
Content-Type: application/json
{
"contacts": [
{
"contactPerson": {
"names": [{"givenName": "Alice", "familyName": "Smith"}],
"emailAddresses": [{"value": "alice@example.com"}]
}
},
{
"contactPerson": {
"names": [{"givenName": "Bob", "familyName": "Jones"}],
"emailAddresses": [{"value": "bob@example.com"}]
}
}
],
"readMask": "names,emailAddresses"
}
POST /google-contacts/v1/people:batchDeleteContacts
Content-Type: application/json
{
"resourceNames": ["people/c123", "people/c456"]
}
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.
GET /google-contacts/v1/contactGroups?pageSize=100
Response:
{
"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 /google-contacts/v1/contactGroups/{resourceName}?maxMembers=100
Use contactGroups/starred, contactGroups/family, etc. for system groups, or the resource name for user groups.
POST /google-contacts/v1/contactGroups
Content-Type: application/json
{
"contactGroup": {
"name": "Work Contacts"
}
}
DELETE /google-contacts/v1/contactGroups/{resourceName}?deleteContacts=false
Set deleteContacts=true to also delete the contacts in the group.
GET /google-contacts/v1/contactGroups:batchGet?resourceNames=contactGroups/starred&resourceNames=contactGroups/family
Add or remove contacts from a group:
POST /google-contacts/v1/contactGroups/{resourceName}/members:modify
Content-Type: application/json
{
"resourceNamesToAdd": ["people/c123", "people/c456"],
"resourceNamesToRemove": ["people/c789"]
}
Other contacts are people you've interacted with (e.g., via email) but haven't explicitly added to your contacts.
GET /google-contacts/v1/otherContacts?readMask=names,emailAddresses&pageSize=100
POST /google-contacts/v1/{resourceName}:copyOtherContactToMyContactsGroup
Content-Type: application/json
{
"copyMask": "names,emailAddresses,phoneNumbers"
}
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
Use pageSize and pageToken for pagination:
GET /google-contacts/v1/people/me/connections?personFields=names&pageSize=100&pageToken=NEXT_PAGE_TOKEN
Response includes pagination info:
{
"connections": [...],
"totalPeople": 500,
"nextPageToken": "...",
"nextSyncToken": "..."
}
Continue fetching with pageToken until nextPageToken is not returned.
const response = await fetch(
'https://api.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();
import os
import requests
response = requests.get(
'https://api.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()
people/c{id} (e.g., people/c1234567890)contactGroups/{id} (e.g., contactGroups/abc123)starred, friends, family, coworkers, myContacts, all, blockedpersonFields parameter is required for most read operationsetag to prevent overwriting concurrent changescurl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| 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 |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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
google-contacts. For example:https://api.maton.ai/google-contacts/v1/people/me/connectionshttps://api.maton.ai/v1/people/me/connections共 2 个版本