Platforms

Google Workspace

Connect a Google account to read and send Gmail, manage Google Calendar events, work with Drive files and sync Google Contacts.

A single Google connection gives Pozy access to one person's Gmail, Google Calendar, Google Drive and Google Contacts, as one account per mailbox. At connect time you decide which of those four areas to ask for. Ask for more later and the account id stays the same. The calls themselves are the same for Google and Microsoft mailboxes: see Email, Calendar and Files.

#What you can do

Area Value in scopes Google permission What it unlocks
Email email gmail.modify List, search, read, send, reply, label, archive and trash Gmail
Calendar calendar calendar Events with Google Meet links, RSVP, free-busy and availability
Files files drive.file Only files created through Pozy or picked by the user
Contacts contacts contacts.readonly Google Contacts copied into /v1/contacts once a day, read-only

On top of those, each connection requests openid, userinfo.email and userinfo.profile, which tell Pozy whose mailbox it is.

Property Value
Platform id google
Accounts One per Google account and profile. Reconnecting widens the same account
Inbox New mail and API sends appear as inbox conversations, one per Gmail thread
Posting and analytics No
List the accounts GET /v1/accounts?platform=google

#Connect an account

scopes is required. Ask only for what your product uses: Google lists every permission on the consent screen, and Workspace admins review apps by what they request.

curl "https://api.pozy.ai/v1/connect/google?profileId=6710c3a9e4b0d2f1a8c95e21&scopes=email,calendar&redirect_url=https://app.example.com/connected" \
  -H "Authorization: Bearer $POZY_API_KEY"

The user picks a Google account and approves. They return to your redirect_url with connected=google, profileId, accountId and username (the mailbox address). From the API there is no Pozy screen in between: your app picks the areas and the user sees only Google.

What counts is what Google grants, not what you asked for. A permission the user unchecks on Google's screen leaves its area out, and calls in that area answer 412 account_scope_missing. If the user unchecks all of them, Pozy saves no account and sends your redirect error=no_access_granted.

#Add areas later

Connect the same Google account again with the longer list. Google keeps what it granted before and Pozy updates the same account. Pass reconnectAccountId to make sure the reconnect lands on that account, and loginHint to preselect the mailbox:

cURL
curl "https://api.pozy.ai/v1/connect/google?profileId=6710c3a9e4b0d2f1a8c95e21&scopes=email,calendar,files&reconnectAccountId=6710c501e4b0d2f1a8c95e77&loginHint=ana@example.com" \
  -H "Authorization: Bearer $POZY_API_KEY"

A reconnect can add areas but never takes one away, even if you leave it out. To remove an area, disconnect the account, then connect it again asking only for the areas you still need.

#Gmail limits

What Limit
Daily sends from a personal Gmail mailbox 200
Daily sends from a Google Workspace mailbox 500
When the daily count restarts 00:00 UTC
One body sent to over 50 recipients in an hour A pause of 10 minutes, twice as long on each repeat up to 24 hours, with an account.rate_limited event
Addresses per field 100 in to, 100 in cc, 100 in bcc
Attachments 20 files, 25 MB combined

A reply uses up a send, and so does a message Gmail refuses. Read your remaining budget from the X-Pozy-Send-Limit, X-Pozy-Send-Remaining and X-Pozy-Send-Reset headers on each send, or from sendCap in GET /v1/accounts/{accountId}/health. Use the mailbox for personal mail; newsletters belong elsewhere.

#Drive access

Pozy connects Drive with drive.file, never full Drive access. It sees two kinds of files: files created through Pozy (POST /v1/files, POST /v1/files/folders) and files the user picked in Google Picker. Everything else stays invisible and returns 404 with details.reason: "file_not_granted". Picker sessions, which let the user grant an existing file, are not available yet, so for now Pozy works with the files it created. Once they open, a pick is a lasting grant until the user removes the app from their Google account.

Google's own formats are not stored as files, so Pozy exports them on download: Docs and Slides become PDF, Sheets become XLSX and Drawings become PNG. Forms and Sites cannot be downloaded at all and say downloadable: false. Going the other way, convertTo on an upload turns the file into a Google format.

#Contacts sync

With the contacts area, Pozy copies Google Contacts into the profile's contacts right after connecting, then once a day for changes only. There is no on-demand trigger. List them with GET /v1/contacts?profileId=...&platform=google.

  • People without an email address are skipped. Only the first address is used.
  • A person already known from another channel (WhatsApp, SMS...) with the same email gets a Google email channel instead of a second contact.
  • The sync writes name, company, photo and email, and never touches tags, custom fields or other channels.
  • Nothing is written back to Google. Deleting a contact in Google removes its Google channel and fires contact.deleted; the contact itself stays.

#Push notifications

When the account connects, Pozy subscribes to Google's push notifications for the granted areas and keeps them renewed (Google channels expire within seven days; Pozy renews any that expire within 24 hours). You only subscribe your own webhook to the events you want.

Event Area Fires when
message.received, message.sent, conversation.started email Mail arrives in the inbox, is sent through the API, or starts a new thread
calendar.event.created, .updated, .deleted calendar Someone adds, edits or removes an event in the primary calendar
file.created, file.updated, file.deleted files A Drive file Pozy has access to is added, edited or removed
file.picked files The user is done choosing files in the picker
contact.updated, contact.deleted contacts The daily sync changes a contact (up to a day after the change)
account.rate_limited email The mailbox enters a sending cooldown

The push field of GET /v1/accounts/{accountId}/health is active; pending, which Pozy retries within six hours; failed, after three failed renewals, retried once a day; or not_applicable. Expect Google to repeat a change now and then, and deduplicate on the object's id. When Gmail has lost the history between two notifications, Pozy picks up from the present, so fetch anything you missed with GET /v1/email/messages.

#Errors

Error Cause Fix
400 invalid_field_value, param: scopes scopes missing, empty or unknown Pass a subset of email, calendar, files, contacts
error=oauth_denied on the redirect The user said no, or Google turned the app down. With admin_policy_enforced, a Workspace admin has blocked it Try the connect again, or have the admin allow the app
401 reconnect_required Google no longer accepts the account's access Have the user reconnect
412 account_scope_missing The account lacks the area. details has grantedAreas and missingArea Reconnect with the area added
429 email_send_cap_reached Today's cap is used. details.cap has limit, used, resetsAt Wait for resetsAt
429 rate_limited A sending cooldown, or Google throttled the mailbox Wait for Retry-After
502 platform_api_error Google returned an unmapped error Retry. The message carries Google's

If Google will not renew access, for instance because the user removed the app in their Google account settings, Pozy marks the account disconnected and sends account.disconnected.

#Endpoints

Endpoint What it does
GET /v1/connect/{platform} Get OAuth connect URL
GET /v1/accounts/{accountId}/health Check account health
Endpoint What it does
GET /v1/calendar/calendars List calendars
GET /v1/calendar/events List events in a window
POST /v1/calendar/events Create an event
GET /v1/calendar/events/{eventId} Get an event
PATCH /v1/calendar/events/{eventId} Update an event
DELETE /v1/calendar/events/{eventId} Delete an event
POST /v1/calendar/events/{eventId}/rsvp Respond to an invitation
POST /v1/calendar/free-busy Busy blocks for one or more accounts
POST /v1/calendar/availability Find meeting slots across accounts
GET /v1/email/threads List email threads
GET /v1/email/threads/{threadId} Get an email thread with its messages
PATCH /v1/email/threads/{threadId} Update every message in a thread
GET /v1/email/messages List email messages
POST /v1/email/messages Send an email
GET /v1/email/messages/{messageId} Get an email message
PATCH /v1/email/messages/{messageId} Mark read or starred, or move a message
DELETE /v1/email/messages/{messageId} Move a message to trash
POST /v1/email/messages/{messageId}/reply Reply to a message
GET /v1/email/folders List mailbox folders
GET /v1/email/attachments/{attachmentId} Download an attachment
GET /v1/files List files in a folder or search the drive
POST /v1/files Upload a file
POST /v1/files/folders Create a folder
POST /v1/files/picker-sessions Create a hosted Google Picker session (not available yet)
GET /v1/files/{fileId} Get a file or folder
PATCH /v1/files/{fileId} Rename or move a file
DELETE /v1/files/{fileId} Move a file to the trash
GET /v1/files/{fileId}/download Download a file
GET /v1/files/{fileId}/share-link Get an anyone-with-the-link share link