Platforms

Microsoft 365

Connect a Microsoft 365 or Outlook.com account to use Outlook mail, Outlook Calendar with Teams meetings, OneDrive files and Outlook contacts.

One Microsoft connection gives Pozy a person's Outlook mail, Outlook Calendar, OneDrive and Outlook contacts. It works for Microsoft 365 work or school logins and for personal Outlook.com or Hotmail logins alike. Each account stands for one mailbox, and you pick the areas it covers when you connect. The calls are shared with Google mailboxes: see Email, Calendar and Files.

#What you can do

Area Value in scopes Microsoft Graph permissions What it unlocks
Email email Mail.ReadWrite, Mail.Send List, search, read, send, reply, flag, move and trash Outlook mail
Calendar calendar Calendars.ReadWrite Events with Teams meetings, RSVP, free-busy and availability
Files files Files.ReadWrite Every OneDrive file the user can reach, no picker needed
Contacts contacts Contacts.Read Outlook contacts copied into /v1/contacts once a day, read-only

Each connection adds openid, profile, email, offline_access and User.Read as well: they identify the mailbox and let Pozy keep access over time.

Property Value
Platform id microsoft
Mailboxes Exchange Online and Outlook.com. On-premises Exchange is not supported
Organizations Some tenants need an administrator to approve the app once (admin consent)
Inbox New mail and API sends appear as inbox conversations, one per Outlook conversation
List the accounts GET /v1/accounts?platform=microsoft

#Connect an account

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

The user signs in, approves the permissions behind the areas, and returns to your redirect_url with connected=microsoft, profileId, accountId and username. Pozy reads the granted areas from the token Microsoft returns.

To add areas later, connect the same account again with the longer list and reconnectAccountId. The account id stays the same. loginHint preselects the mailbox in Microsoft's account picker. Areas only add up; to drop one, disconnect and connect again.

Many work and school tenants let only an administrator approve apps that read mail, calendars, files or contacts. Users then see "Need admin approval" while connecting, or later calls return 412 admin_consent_required with a ready-made link in details.adminConsentUrl (valid for one hour). Personal Outlook.com accounts never need this.

Request a fresh link for an account in that organization and send it to an administrator (Global Administrator, Cloud Application Administrator or Application Administrator):

curl "https://api.pozy.ai/v1/connect/microsoft/admin-consent?accountId=6710c50ce4b0d2f1a8c95e82&redirectUrl=https://app.example.com/admin-done" \
  -H "Authorization: Bearer $POZY_API_KEY"

The administrator signs in, reviews the permissions and approves them for the whole tenant. Microsoft sends them to redirectUrl with adminConsent=granted and tenant, or adminConsent=denied and error. Calls that returned 412 then work without a reconnect. An administrator can also approve while connecting their own mailbox by ticking "Consent on behalf of your organization".

Approval is per organization and covers all four areas. Each user still chooses what their own connection grants. An administrator can withdraw it in Microsoft Entra under Enterprise applications, after which accounts in that tenant fail until it is approved again.

#Outlook limits

Limit Value
Sends a day 1,000 per mailbox, reset at midnight UTC
Same body to more than 50 recipients within an hour The mailbox pauses: 10 minutes, doubling up to 24 hours, and account.rate_limited fires
Addresses per field 100 in to, 100 in cc, 100 in bcc
Attachments 20 files, none over 3 MB, 25 MB combined
Custom headers Only names that start with X-. A List-Unsubscribe header is removed, and metadata.droppedHeaders on the result says so

Each send response includes the X-Pozy-Send-Limit, X-Pozy-Send-Remaining and X-Pozy-Send-Reset headers. For repeating events Outlook takes a single RRULE, with no EXDATE or RDATE, and it stores just one reminder per event. Upload conversion with convertTo and picker sessions belong to Google; on Microsoft they answer 400.

#Push notifications

Pozy creates Microsoft Graph subscriptions for the granted areas and renews them before they expire (about three days for mail and calendar, about 29 days for OneDrive). Subscribe your own webhook to the events you need:

Event Area Fires when
message.received, message.sent, conversation.started email Mail arrives in the Inbox folder, is sent through the API, or starts a thread
calendar.event.created, .updated, .deleted calendar An event in the user's calendar is added, edited or removed
file.created, file.updated, file.deleted files A file in OneDrive is added, edited or removed
contact.updated, contact.deleted contacts The once-a-day contact sync finds a changed or removed contact
account.rate_limited email Sending from the mailbox is paused for a while

If the push subscription is down, mail received in that time produces no webhooks; catch up with GET /v1/email/messages. The subscription's state is the push field of GET /v1/accounts/{accountId}/health.

#Errors

Error Cause Fix
400 invalid_field_value scopes missing, or a Google-only option such as google_meet Fix the field named in param
error=oauth_denied on the redirect The user said no, or their organization does not allow the app Try again, or ask for admin consent
401 reconnect_required Microsoft no longer accepts the account's access Have the user reconnect
412 admin_consent_required The tenant needs an administrator's approval Send details.adminConsentUrl to an administrator
412 account_scope_missing The account lacks the area Reconnect with the area added
429 email_send_cap_reached, 429 rate_limited Daily cap used, cooldown, or Graph throttling Wait for resetsAt or Retry-After

#Endpoints

Endpoint What it does
GET /v1/connect/{platform} Get OAuth connect URL
GET /v1/connect/microsoft/admin-consent Admin-consent link for a Microsoft tenant
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