{"openapi":"3.1.0","info":{"title":"Pyas API","version":"2.0.0","description":"One API for Google Calendar, Microsoft Outlook, Zoom and virtual calendars. Every request must include an `x-api-key` header. Test keys (`pyas_sk_test_`) work only in the sandbox.\n\n## Test requests in your sandbox\n\nYou can send any request to your sandbox from the API reference in the docs. When you're signed in to the dashboard, each operation's **Try it** button sends the request with a key created for you. That key works only in your sandbox, so your live data is never affected.\n\nPlaceholders in double braces, such as `{{account.avery}}` or `{{event.avery.design}}`, stand for the people, calendars and events in your sandbox. `{{in.1d.14:00}}` stands for tomorrow at 14:00 UTC. When you're signed in, the placeholders are replaced with your sandbox's own values.\n\nIn addition to its virtual accounts, the sandbox includes simulated Google, Microsoft Outlook and Zoom accounts: `{{account.google}}` (Avery), `{{account.outlook}}` (Sam) and `{{account.zoom}}` (Avery). They respond as those providers do, with the same features and the same errors, but never contact the providers. Google Meet and Microsoft Teams links, Zoom meetings, sharing roles, labels and categories, calendar groups, invitations to respond to, files, reminders and working locations all work in the sandbox. In a sandbox, Google and Outlook accounts are always simulated.\n\n## Scenarios\n\n### Find a time when two people are free and book it\n\nFind meeting times across both calendars, then create an event in the first free slot and invite the other person.\n\n1. Find 30-minute slots in the next week: `POST /v2/meeting-times`\n\n```json\n{\n  \"accountIds\": [\n    \"{{account.avery}}\",\n    \"{{account.sam}}\"\n  ],\n  \"from\": \"{{in.1d}}\",\n  \"to\": \"{{in.8d}}\",\n  \"durationMinutes\": 30,\n  \"timezone\": \"America/New_York\"\n}\n```\n\n   Save `data.0.startsAt` as `{{slot.startsAt}}`, `data.0.endsAt` as `{{slot.endsAt}}`.\n\n2. Book the first slot: `POST /v2/events`\n\n```json\n{\n  \"accountId\": \"{{account.avery}}\",\n  \"title\": \"Catch-up with Sam\",\n  \"startsAt\": \"{{slot.startsAt}}\",\n  \"endsAt\": \"{{slot.endsAt}}\",\n  \"attendees\": [\n    {\n      \"email\": \"sam@example.com\",\n      \"name\": \"Sam Patel\"\n    }\n  ]\n}\n```\n\n   Save `data.id` as `{{booked.id}}`.\n\n3. Retrieve the event: `GET /v2/events/{{booked.id}}?accountId={{account.avery}}`\n\n### Move one occurrence of a recurring meeting\n\nCreate a weekly meeting, list its occurrences, and move one of them without changing the rest.\n\n1. Create a weekly meeting: `POST /v2/events`\n\n```json\n{\n  \"accountId\": \"{{account.avery}}\",\n  \"title\": \"Weekly review\",\n  \"startsAt\": \"{{in.1d.15:00}}\",\n  \"endsAt\": \"{{in.1d.15:30}}\",\n  \"recurrence\": \"FREQ=WEEKLY;COUNT=6\"\n}\n```\n\n   Save `data.id` as `{{series.id}}`.\n\n2. List its occurrences for the next 3 weeks: `GET /v2/events/{{series.id}}/instances?accountId={{account.avery}}&from={{in.0d}}&to={{in.21d}}`\n\n   Save `data.1.id` as `{{occurrence.id}}`.\n\n3. Move the second occurrence 1 hour later: `PATCH /v2/events/{{occurrence.id}}?accountId={{account.avery}}`\n\n```json\n{\n  \"startsAt\": \"{{in.8d.16:00}}\",\n  \"endsAt\": \"{{in.8d.16:30}}\"\n}\n```\n\n### Store your own data on events and search by it\n\nPyas stores your metadata with the event on every provider, and you can search events by their metadata.\n\n1. Create an event with your deal ID: `POST /v2/events`\n\n```json\n{\n  \"accountId\": \"{{account.avery}}\",\n  \"title\": \"Pricing call\",\n  \"startsAt\": \"{{in.4d.16:00}}\",\n  \"endsAt\": \"{{in.4d.16:30}}\",\n  \"metadata\": {\n    \"dealId\": \"deal_1007\",\n    \"stage\": \"proposal\"\n  }\n}\n```\n\n2. Find the event by its deal ID: `GET /v2/events?metadata.dealId=deal_1007`\n\n### Keep a copy in sync by reading only changes\n\nStart a sync of a time window, save the `syncToken`, create an event, and then read only that change.\n\n1. Start a sync of the next month: `GET /v2/events?accountId={{account.avery}}&from={{in.0d}}&to={{in.30d}}&sync=true&limit=250`\n\n   Save `meta.syncToken` as `{{sync.token}}`.\n\n2. Create an event: `POST /v2/events`\n\n```json\n{\n  \"accountId\": \"{{account.avery}}\",\n  \"title\": \"New this afternoon\",\n  \"startsAt\": \"{{in.1d.19:00}}\",\n  \"endsAt\": \"{{in.1d.19:30}}\"\n}\n```\n\n3. Read only the changes: `GET /v2/events?accountId={{account.avery}}&syncToken={{sync.token}}`\n\n### Publish a calendar people can subscribe to\n\nPublish a virtual calendar as an iCalendar feed that shows only busy times, then get its link.\n\n1. Enable the feed, showing only busy times: `PUT /v2/calendars/primary/feed?accountId={{account.yuki}}`\n\n```json\n{\n  \"details\": \"busy\"\n}\n```\n\n2. Get the feed link: `GET /v2/calendars/primary/feed?accountId={{account.yuki}}`\n\n### Attach a document to an event\n\nAttach a link to an event, list the attachments, and delete the link.\n\n1. Attach the agenda: `POST /v2/events/{{event.yuki.design}}/attachments?accountId={{account.yuki}}`\n\n```json\n{\n  \"url\": \"https://example.com/design-agenda.pdf\",\n  \"name\": \"Design agenda.pdf\"\n}\n```\n\n   Save `data.id` as `{{attachment.id}}`.\n\n2. List the attachments: `GET /v2/events/{{event.yuki.design}}/attachments?accountId={{account.yuki}}`\n\n3. Delete the attachment: `DELETE /v2/events/{{event.yuki.design}}/attachments/{{attachment.id}}?accountId={{account.yuki}}`\n\n### Add a Google Meet, Microsoft Teams or Zoom link with meeting settings\n\nEach calendar provider creates its own meetings, Google Meet on Google and Microsoft Teams on Outlook. A Zoom account adds Zoom meetings to any calendar. Meeting settings use one set of options for all three services. A setting that a service doesn't support is rejected, and you can read the settings back after you write them.\n\n1. Create a Google event with a Meet link that only invited people can join without asking: `POST /v2/events`\n\n```json\n{\n  \"accountId\": \"{{account.google}}\",\n  \"title\": \"Design critique\",\n  \"startsAt\": \"{{in.2d.16:00}}\",\n  \"endsAt\": \"{{in.2d.17:00}}\",\n  \"conferencing\": {\n    \"provider\": \"meet\",\n    \"options\": {\n      \"admission\": \"invited\",\n      \"recording\": \"cloud\"\n    }\n  }\n}\n```\n\n   Save `data.id` as `{{meet.id}}`.\n\n2. Read the meeting settings back: `GET /v2/events/{{meet.id}}?accountId={{account.google}}&include=conferencingSettings`\n\n3. Create an Outlook event with a Teams meeting where everyone waits in the lobby: `POST /v2/events`\n\n```json\n{\n  \"accountId\": \"{{account.outlook}}\",\n  \"title\": \"Supplier call\",\n  \"startsAt\": \"{{in.3d.10:00}}\",\n  \"endsAt\": \"{{in.3d.10:30}}\",\n  \"conferencing\": {\n    \"provider\": \"teams\",\n    \"options\": {\n      \"admission\": \"organizer\"\n    }\n  }\n}\n```\n\n4. Create a Zoom meeting on a virtual calendar with the Zoom account: `POST /v2/events`\n\n```json\n{\n  \"accountId\": \"{{account.avery}}\",\n  \"title\": \"Customer onboarding\",\n  \"startsAt\": \"{{in.4d.15:00}}\",\n  \"endsAt\": \"{{in.4d.16:00}}\",\n  \"conferencing\": {\n    \"provider\": \"zoom\",\n    \"accountId\": \"{{account.zoom}}\",\n    \"options\": {\n      \"admission\": \"organizer\",\n      \"muteOnEntry\": true\n    }\n  }\n}\n```\n\n   Save `data.id` as `{{zoom.id}}`.\n\n5. Reschedule the event and its Zoom meeting: `PATCH /v2/events/{{zoom.id}}?accountId={{account.avery}}`\n\n```json\n{\n  \"startsAt\": \"{{in.5d.15:00}}\",\n  \"endsAt\": \"{{in.5d.16:00}}\"\n}\n```\n\n### Respond to an invitation and propose another time\n\nRespond tentatively to an invitation from someone else on an Outlook calendar and propose a new time. On Google, the response is recorded without a proposed time.\n\n1. Read the invitation: `GET /v2/events/{{event.outlook.invite}}?accountId={{account.outlook}}`\n\n2. Respond tentatively and propose a time 1 hour later: `POST /v2/events/{{event.outlook.invite}}/respond?accountId={{account.outlook}}`\n\n```json\n{\n  \"response\": \"tentative\",\n  \"comment\": \"Could we start an hour later?\",\n  \"proposedTime\": {\n    \"startsAt\": \"{{in.2d.16:00}}\",\n    \"endsAt\": \"{{in.2d.17:00}}\"\n  }\n}\n```\n\n3. Accept an invitation on Google: `POST /v2/events/{{event.google.invite}}/respond?accountId={{account.google}}`\n\n```json\n{\n  \"response\": \"accepted\"\n}\n```\n\n### Import data another app stored on events\n\nRead the extended properties another app wrote on Google events, preview what an import would copy, then copy them into metadata.\n\n1. Read the extended properties on an event: `GET /v2/events/{{event.google.trip}}?accountId={{account.google}}&include=extendedProperties`\n\n2. Preview what an import would copy: `POST /v2/metadata/import`\n\n```json\n{\n  \"accountIds\": [\n    \"{{account.google}}\"\n  ],\n  \"dryRun\": true\n}\n```\n\n3. Copy them into metadata: `POST /v2/metadata/import`\n\n```json\n{\n  \"accountIds\": [\n    \"{{account.google}}\"\n  ]\n}\n```\n\n   Save `data.importId` as `{{import.id}}`.\n\n4. Check the import's progress: `GET /v2/metadata/imports/{{import.id}}`\n\n### Test webhooks before you write a handler\n\nEvery sandbox has an inbox, hosted by Pyas, that receives every sandbox event. Send it sample events and see exactly what arrives and how it is signed. Then point a test endpoint of your own at your handler.\n\n1. Send a sample event.updated delivery, signed like a real one: `POST /v2/webhooks/{{webhook.inbox}}/test`\n\n```json\n{\n  \"type\": \"event.updated\"\n}\n```\n\n2. List the deliveries and their attempts: `GET /v2/webhooks/deliveries?webhookId={{webhook.inbox}}`\n\n3. Retrieve the signing secret: `GET /v2/webhooks/{{webhook.inbox}}/secret`\n\n4. List every event type with a sample: `GET /v2/webhooks/event-types`","x-pyas-responses-recorded-on":"2026-11-08"},"servers":[{"url":"https://api.pyas.io"}],"tags":[{"name":"Accounts","description":"List connected calendar accounts and manage their status, settings and imports, including virtual accounts."},{"name":"Connect","description":"Connect and reconnect calendar accounts with connect sessions, including the steps that run in the user's browser."},{"name":"Calendars","description":"Manage calendars, calendar sharing, categories, feeds and calendar groups."},{"name":"Events","description":"Manage events across Google Calendar, Microsoft Outlook and virtual calendars, including metadata, attachments and conferencing."},{"name":"Availability","description":"Check free/busy information, find meeting times and find rooms."},{"name":"Meetings","description":"Meetings on their own, with no calendar event: Zoom meetings (list, get, create, change, delete), Microsoft Teams meetings (get, create, change, delete) and Google Meet links (get, create, change settings). To add a meeting to an event, use conferencing on the event."},{"name":"Invitations","description":"Invitations sent for virtual calendars."},{"name":"Webhooks","description":"Receive events at your own endpoints through signed, retried and recorded deliveries. Includes replays, test deliveries and a relay for sandbox events."},{"name":"Metadata","description":"Import the extended properties stored at the provider into Pyas metadata."},{"name":"Keys","description":"List API keys, and rotate a key with a grace period during which both the old and new keys work."},{"name":"Sandbox","description":"The sandbox environment that test keys work in."},{"name":"Usage","description":"Retrieve API usage by day."},{"name":"Logs","description":"Look up any v2 request by its trace ID to see what was requested, what the API responded and why, and what happened while the request was processed."}],"x-pyas-scenarios":[{"id":"find-a-time-and-book-it","title":"Find a time when two people are free and book it","summary":"Find meeting times across both calendars, then create an event in the first free slot and invite the other person.","steps":[{"title":"Find 30-minute slots in the next week","operationId":"meetingTimes.find","body":{"accountIds":["{{account.avery}}","{{account.sam}}"],"from":"{{in.1d}}","to":"{{in.8d}}","durationMinutes":30,"timezone":"America/New_York"},"status":200,"capture":{"slot.startsAt":"data.0.startsAt","slot.endsAt":"data.0.endsAt"}},{"title":"Book the first slot","operationId":"events.create","body":{"accountId":"{{account.avery}}","title":"Catch-up with Sam","startsAt":"{{slot.startsAt}}","endsAt":"{{slot.endsAt}}","attendees":[{"email":"sam@example.com","name":"Sam Patel"}]},"status":201,"capture":{"booked.id":"data.id"}},{"title":"Retrieve the event","operationId":"events.get","params":{"eventId":"{{booked.id}}"},"query":{"accountId":"{{account.avery}}"},"status":200}]},{"id":"move-one-occurrence","title":"Move one occurrence of a recurring meeting","summary":"Create a weekly meeting, list its occurrences, and move one of them without changing the rest.","steps":[{"title":"Create a weekly meeting","operationId":"events.create","body":{"accountId":"{{account.avery}}","title":"Weekly review","startsAt":"{{in.1d.15:00}}","endsAt":"{{in.1d.15:30}}","recurrence":"FREQ=WEEKLY;COUNT=6"},"status":201,"capture":{"series.id":"data.id"}},{"title":"List its occurrences for the next 3 weeks","operationId":"events.instances","params":{"eventId":"{{series.id}}"},"query":{"accountId":"{{account.avery}}","from":"{{in.0d}}","to":"{{in.21d}}"},"status":200,"capture":{"occurrence.id":"data.1.id"}},{"title":"Move the second occurrence 1 hour later","operationId":"events.update","params":{"eventId":"{{occurrence.id}}"},"query":{"accountId":"{{account.avery}}"},"body":{"startsAt":"{{in.8d.16:00}}","endsAt":"{{in.8d.16:30}}"},"status":200}]},{"id":"your-own-data-on-events","title":"Store your own data on events and search by it","summary":"Pyas stores your metadata with the event on every provider, and you can search events by their metadata.","steps":[{"title":"Create an event with your deal ID","operationId":"events.create","body":{"accountId":"{{account.avery}}","title":"Pricing call","startsAt":"{{in.4d.16:00}}","endsAt":"{{in.4d.16:30}}","metadata":{"dealId":"deal_1007","stage":"proposal"}},"status":201},{"title":"Find the event by its deal ID","operationId":"events.list","query":{"metadata.dealId":"deal_1007"},"status":200}]},{"id":"only-what-changed","title":"Keep a copy in sync by reading only changes","summary":"Start a sync of a time window, save the `syncToken`, create an event, and then read only that change.","steps":[{"title":"Start a sync of the next month","operationId":"events.list","query":{"accountId":"{{account.avery}}","from":"{{in.0d}}","to":"{{in.30d}}","sync":"true","limit":"250"},"status":200,"capture":{"sync.token":"meta.syncToken"}},{"title":"Create an event","operationId":"events.create","body":{"accountId":"{{account.avery}}","title":"New this afternoon","startsAt":"{{in.1d.19:00}}","endsAt":"{{in.1d.19:30}}"},"status":201},{"title":"Read only the changes","operationId":"events.list","query":{"accountId":"{{account.avery}}","syncToken":"{{sync.token}}"},"status":200}]},{"id":"publish-a-calendar","title":"Publish a calendar people can subscribe to","summary":"Publish a virtual calendar as an iCalendar feed that shows only busy times, then get its link.","steps":[{"title":"Enable the feed, showing only busy times","operationId":"calendars.feed.enable","params":{"calendarRef":"primary"},"query":{"accountId":"{{account.yuki}}"},"body":{"details":"busy"},"status":200},{"title":"Get the feed link","operationId":"calendars.feed.get","params":{"calendarRef":"primary"},"query":{"accountId":"{{account.yuki}}"},"status":200}]},{"id":"attach-a-link","title":"Attach a document to an event","summary":"Attach a link to an event, list the attachments, and delete the link.","steps":[{"title":"Attach the agenda","operationId":"events.attachments.addLink","params":{"eventId":"{{event.yuki.design}}"},"query":{"accountId":"{{account.yuki}}"},"body":{"url":"https://example.com/design-agenda.pdf","name":"Design agenda.pdf"},"status":201,"capture":{"attachment.id":"data.id"}},{"title":"List the attachments","operationId":"events.attachments.list","params":{"eventId":"{{event.yuki.design}}"},"query":{"accountId":"{{account.yuki}}"},"status":200},{"title":"Delete the attachment","operationId":"events.attachments.delete","params":{"eventId":"{{event.yuki.design}}","attachmentId":"{{attachment.id}}"},"query":{"accountId":"{{account.yuki}}"},"status":200}]},{"id":"meeting-links","title":"Add a Google Meet, Microsoft Teams or Zoom link with meeting settings","summary":"Each calendar provider creates its own meetings, Google Meet on Google and Microsoft Teams on Outlook. A Zoom account adds Zoom meetings to any calendar. Meeting settings use one set of options for all three services. A setting that a service doesn't support is rejected, and you can read the settings back after you write them.","steps":[{"title":"Create a Google event with a Meet link that only invited people can join without asking","operationId":"events.create","body":{"accountId":"{{account.google}}","title":"Design critique","startsAt":"{{in.2d.16:00}}","endsAt":"{{in.2d.17:00}}","conferencing":{"provider":"meet","options":{"admission":"invited","recording":"cloud"}}},"status":201,"capture":{"meet.id":"data.id"}},{"title":"Read the meeting settings back","operationId":"events.get","params":{"eventId":"{{meet.id}}"},"query":{"accountId":"{{account.google}}","include":"conferencingSettings"},"status":200},{"title":"Create an Outlook event with a Teams meeting where everyone waits in the lobby","operationId":"events.create","body":{"accountId":"{{account.outlook}}","title":"Supplier call","startsAt":"{{in.3d.10:00}}","endsAt":"{{in.3d.10:30}}","conferencing":{"provider":"teams","options":{"admission":"organizer"}}},"status":201},{"title":"Create a Zoom meeting on a virtual calendar with the Zoom account","operationId":"events.create","body":{"accountId":"{{account.avery}}","title":"Customer onboarding","startsAt":"{{in.4d.15:00}}","endsAt":"{{in.4d.16:00}}","conferencing":{"provider":"zoom","accountId":"{{account.zoom}}","options":{"admission":"organizer","muteOnEntry":true}}},"status":201,"capture":{"zoom.id":"data.id"}},{"title":"Reschedule the event and its Zoom meeting","operationId":"events.update","params":{"eventId":"{{zoom.id}}"},"query":{"accountId":"{{account.avery}}"},"body":{"startsAt":"{{in.5d.15:00}}","endsAt":"{{in.5d.16:00}}"},"status":200}]},{"id":"answer-an-invitation","title":"Respond to an invitation and propose another time","summary":"Respond tentatively to an invitation from someone else on an Outlook calendar and propose a new time. On Google, the response is recorded without a proposed time.","steps":[{"title":"Read the invitation","operationId":"events.get","params":{"eventId":"{{event.outlook.invite}}"},"query":{"accountId":"{{account.outlook}}"},"status":200},{"title":"Respond tentatively and propose a time 1 hour later","operationId":"events.respond","params":{"eventId":"{{event.outlook.invite}}"},"query":{"accountId":"{{account.outlook}}"},"body":{"response":"tentative","comment":"Could we start an hour later?","proposedTime":{"startsAt":"{{in.2d.16:00}}","endsAt":"{{in.2d.17:00}}"}},"status":200},{"title":"Accept an invitation on Google","operationId":"events.respond","params":{"eventId":"{{event.google.invite}}"},"query":{"accountId":"{{account.google}}"},"body":{"response":"accepted"},"status":200}]},{"id":"bring-in-another-apps-data","title":"Import data another app stored on events","summary":"Read the extended properties another app wrote on Google events, preview what an import would copy, then copy them into metadata.","steps":[{"title":"Read the extended properties on an event","operationId":"events.get","params":{"eventId":"{{event.google.trip}}"},"query":{"accountId":"{{account.google}}","include":"extendedProperties"},"status":200},{"title":"Preview what an import would copy","operationId":"metadata.import","body":{"accountIds":["{{account.google}}"],"dryRun":true},"status":200},{"title":"Copy them into metadata","operationId":"metadata.import","body":{"accountIds":["{{account.google}}"]},"status":202,"capture":{"import.id":"data.importId"}},{"title":"Check the import's progress","operationId":"metadata.imports.get","params":{"importId":"{{import.id}}"},"status":200}]},{"id":"test-your-webhooks","title":"Test webhooks before you write a handler","summary":"Every sandbox has an inbox, hosted by Pyas, that receives every sandbox event. Send it sample events and see exactly what arrives and how it is signed. Then point a test endpoint of your own at your handler.","steps":[{"title":"Send a sample event.updated delivery, signed like a real one","operationId":"webhooks.test","params":{"webhookId":"{{webhook.inbox}}"},"body":{"type":"event.updated"},"status":200},{"title":"List the deliveries and their attempts","operationId":"webhooks.deliveries.list","query":{"webhookId":"{{webhook.inbox}}"},"status":200},{"title":"Retrieve the signing secret","operationId":"webhooks.secret.get","params":{"webhookId":"{{webhook.inbox}}"},"status":200},{"title":"List every event type with a sample","operationId":"webhooks.eventTypes","status":200}]}],"paths":{"/v2/accounts":{"get":{"operationId":"accounts.list","summary":"List accounts","description":"Returns the app's connected accounts and virtual accounts, in the order they were added.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"subjectId","in":"query","required":false,"description":"Returns only accounts with this `subjectId`.","schema":{"type":"string","minLength":1,"maxLength":255},"example":"{{subject.avery}}"},{"name":"provider","in":"query","required":false,"schema":{"type":"string","enum":["google","microsoft","zoom","icloud","pyas"]}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","inactive"]}},{"name":"limit","in":"query","required":false,"description":"The maximum number of results per page, up to 200.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` value from the previous page.","schema":{"type":"string","minLength":1,"maxLength":2048}}],"responses":{"200":{"description":"A page of accounts.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"description":"Pass it as `cursor` to get the next page. `null` on the last page.","type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[{"accountId":"{{account.avery}}","provider":"pyas","email":"{{account.avery}}@cal.pyas.io","name":"Avery Brooks","status":"active","subjectId":"{{subject.avery}}","scopes":[],"createdAt":"2026-11-08T20:00:23.536Z","updatedAt":"2026-11-08T20:00:23.536Z"},{"accountId":"{{account.google}}","provider":"google","email":"{{calendar.google.primary}}","name":"Avery Brooks","status":"active","subjectId":"{{subject.avery}}","scopes":["https://www.googleapis.com/auth/calendar","https://www.googleapis.com/auth/calendar.events","https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/meetings.space.created","https://www.googleapis.com/auth/admin.directory.resource.calendar.readonly"],"createdAt":"2026-11-08T20:00:24.196Z","updatedAt":"2026-11-08T20:00:24.196Z"},{"accountId":"{{account.zoom}}","provider":"zoom","email":"{{calendar.google.primary}}","name":"Avery Brooks","status":"active","subjectId":"{{subject.avery}}","scopes":["meeting:write:meeting","meeting:read:meeting","user:read:user"],"createdAt":"2026-11-08T20:00:24.196Z","updatedAt":"2026-11-08T20:00:24.196Z"}],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"accounts.createVirtual","summary":"Create a virtual account","description":"Creates a calendar account that Pyas hosts itself (`provider: pyas`), with a primary calendar. Use virtual accounts for people who don't use Google or Outlook, and for testing. Google and Outlook accounts are connected with connect sessions instead.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","const":"pyas"},"name":{"type":"string","minLength":1,"maxLength":200,"description":"A virtual account's name (1 to 200 characters)."},"subjectId":{"type":"string","minLength":1,"maxLength":255,"description":"Your own identifier for the account."},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"An IANA time zone name. Defaults to `UTC`."}},"required":["provider","name"],"additionalProperties":false},"example":{"provider":"pyas","name":"Taylor Morgan","subjectId":"user_123","timezone":"America/Chicago"}}}},"responses":{"201":{"description":"The account, including the ID of its primary calendar.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"accountId":{"type":"string","description":"The ID Pyas assigns to the account. Use it as `accountId` in other requests."},"provider":{"$ref":"#/components/schemas/Provider"},"email":{"type":["string","null"]},"name":{"type":["string","null"]},"status":{"type":"string","enum":["active","inactive"],"description":"`inactive` means the account is disabled because the user revoked access or the account was disconnected."},"subjectId":{"description":"Your own identifier for the account, such as your user or organization ID, if set.","type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"createdAt":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"primaryCalendarId":{"type":"string"}},"required":["accountId","provider","email","name","status","subjectId","scopes","createdAt","updatedAt","primaryCalendarId"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"accountId":"ed449ba9-6b5e-461d-9252-0415a35fddb2","provider":"pyas","email":"ed449ba9-6b5e-461d-9252-0415a35fddb2@cal.pyas.io","name":"Taylor Morgan","status":"active","subjectId":"user_123","scopes":[],"createdAt":"2026-11-08T20:00:24.652Z","updatedAt":"2026-11-08T20:00:24.652Z","primaryCalendarId":"calm5p8d0crjk4bdjh6bdts"},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`BILLING_CONNECTION_LIMIT`: The plan's connected account limit has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_LIMIT_REACHED`: The limit for this resource has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/{accountId}":{"delete":{"operationId":"accounts.delete","summary":"Delete an account","description":"Deletes an account from your app and sends a `connection.deleted` webhook.\n\nFor a Google, Outlook or Zoom account, Pyas deletes the credentials it stores for the account and stops watching it for changes. The user's calendars at the provider are not changed, and the user can connect the account again later. With a live key, the account no longer counts toward your plan.\n\nA virtual account is deleted with all of its calendars and events.\n\nFor every account, the metadata you stored on its events and calendars is deleted too. In the sandbox, resetting the sandbox restores deleted accounts.\n\n**In the sandbox:** This example deletes the simulated Google account in the sandbox. Virtual accounts are deleted the same way. Resetting the sandbox with `POST /v2/sandbox/reset` restores deleted sandbox accounts.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"accounts.get","summary":"Get an account","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"}],"responses":{"200":{"description":"The account. Its tokens are never returned.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Account"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"accountId":"{{account.avery}}","provider":"pyas","email":"{{account.avery}}@cal.pyas.io","name":"Avery Brooks","status":"active","subjectId":"{{subject.avery}}","scopes":[],"createdAt":"2026-11-08T20:00:23.536Z","updatedAt":"2026-11-08T20:00:23.536Z"},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"accounts.update","summary":"Update an account","description":"Sets or clears `subjectId`, your own identifier for the account's user. For a virtual account, you can also update `name`.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.sam}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"subjectId":{"description":"A string to set the identifier, or `null` to clear it.","type":["string","null"]},"name":{"type":"string","minLength":1,"maxLength":200,"description":"A virtual account's name (1 to 200 characters)."}},"additionalProperties":false},"example":{"subjectId":"crm_contact_88"}}}},"responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Account"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"accountId":"{{account.sam}}","provider":"pyas","email":"{{account.sam}}@cal.pyas.io","name":"Sam Patel","status":"active","subjectId":"crm_contact_88","scopes":[],"createdAt":"2026-11-08T20:00:24.847Z","updatedAt":"2026-11-08T20:00:25.728Z"},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/{accountId}/settings":{"get":{"operationId":"accounts.settings.get","summary":"Get calendar settings","description":"Returns the person's time zone, locale, week start, time and date format, default event length (Google) and working hours (Outlook). A setting is `null` when the provider doesn't support it.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"}],"responses":{"200":{"description":"The settings.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/AccountSettings"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"timezone":"America/New_York","locale":"en","weekStart":"sunday","timeFormat":"12h","dateOrder":"MDY","defaultEventMinutes":60,"workingHours":null},"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"accounts.settings.update","summary":"Update calendar settings","description":"Updates the time zone, time format and working hours (Outlook). The Google Calendar API doesn't support updating settings, so requests for Google accounts return `VALIDATION_UNSUPPORTED_OPERATION`.\n\n**In the sandbox:** You can update settings on Outlook accounts. The Google Calendar API supports only reading settings.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"An IANA time zone name, such as America/New_York."},"timeFormat":{"type":"string","enum":["12h","24h"]},"workingHours":{"type":"object","properties":{"days":{"minItems":1,"type":"array","items":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]}},"start":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"end":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"timezone":{"type":"string"}},"required":["days","start","end","timezone"],"additionalProperties":false}},"additionalProperties":false},"example":{"timezone":"Europe/Paris","timeFormat":"24h"}}}},"responses":{"200":{"description":"The updated settings.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/AccountSettings"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"timezone":"Europe/Paris","locale":"en-GB","weekStart":null,"timeFormat":"24h","dateOrder":null,"defaultEventMinutes":null,"workingHours":{"days":["monday","tuesday","wednesday","thursday","friday"],"start":"09:00","end":"17:30","timezone":"Europe/London"}},"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/{accountId}/status":{"get":{"operationId":"accounts.status.get","summary":"Get the status of an account","description":"Returns the status of the account. `state` shows whether the account is connected, and `health` is based on its recent provider requests. The response also shows whether each feature is available, which permissions are missing and what the provider supports, and includes a message for the account's owner when they need to take action.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"check","in":"query","required":false,"description":"Sends one request to the provider immediately, bypassing the cache, and includes the result.","schema":{"type":"boolean"},"example":"true"}],"responses":{"200":{"description":"The account's status.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/AccountStatus"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"accountId":"{{account.avery}}","provider":"pyas","name":"Avery Brooks","email":"{{account.avery}}@cal.pyas.io","subjectId":"{{subject.avery}}","state":"connected","health":{"status":"unknown","lastSuccessAt":null,"lastFailure":null},"scopes":{"recorded":[],"source":"requestedAtConnect"},"features":{"readEvents":{"available":true},"writeEvents":{"available":true},"manageCalendars":{"available":true},"freeBusy":{"available":true},"sync":{"available":true},"sharing":{"available":false,"reason":"Virtual calendars are shared through their subscription feed, not with individual people."},"settings":{"available":true},"changeSettings":{"available":true},"categories":{"available":true},"meetingSettings":{"available":false,"reason":"Virtual calendars use Zoom links created through a connected Zoom account. They have no meeting settings of their own."},"attachmentUploads":{"available":false,"reason":"Virtual calendars store links, not files."},"rooms":{"available":false,"reason":"Virtual accounts have no room directory."}},"capabilities":{"incrementalSync":true,"freeBusy":true,"batch":false,"nativeMetadata":false,"calendarWrite":true,"maxAttachmentBytes":0,"push":{"supported":false,"maxTtlSeconds":0}},"userMessage":null,"fixUrl":null,"overall":{"status":"healthy","reason":null,"fix":null},"check":{"ok":true,"at":"2026-11-08T20:00:24.415Z"}},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/{accountId}/working-locations":{"get":{"operationId":"accounts.workingLocations.list","summary":"List working locations","description":"Returns where the person works each day, from Google's working location events (home, office or elsewhere). The window can span at most 92 days.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"from","in":"query","required":false,"description":"An ISO 8601 time with a zone.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"},"example":"{{in.0d}}"},{"name":"to","in":"query","required":false,"description":"An ISO 8601 time with a zone.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"},"example":"{{in.14d}}"}],"responses":{"200":{"description":"Each day's working location.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkingLocationEntry"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[{"eventId":"{{event.google.office}}","startsAt":"2026-11-09T05:00:00Z","endsAt":"2026-11-10T05:00:00Z","isAllDay":true,"location":{"type":"office","label":"HQ"}},{"eventId":"{{event.google.home}}","startsAt":"2026-11-10T05:00:00Z","endsAt":"2026-11-11T05:00:00Z","isAllDay":true,"location":{"type":"home","label":null}}],"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/import":{"post":{"operationId":"accounts.import","summary":"Import accounts","description":"Imports accounts from another calendar API or from your own integration, so your users don't have to connect their calendars again. Send up to 100 refresh tokens issued to your app's own Google, Microsoft or Zoom OAuth app (Native Auth). Pyas verifies each token with the provider and saves the account. If the account already exists, Pyas updates it with the new tokens. The import runs in the background.\n\n**In the sandbox:** An import connects real accounts, so it requires a live key. In the sandbox, this request returns `AUTH_SANDBOX_MISMATCH`.","tags":["Accounts"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":403,"code":"AUTH_SANDBOX_MISMATCH"},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accounts":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["google","microsoft","zoom"]},"refreshToken":{"type":"string","minLength":1,"maxLength":4096,"description":"A refresh token issued to your app's own OAuth client for that provider. After the import, Pyas refreshes the token, so stop using it in your own code."},"subjectId":{"type":"string","minLength":1,"maxLength":255,"description":"Your own identifier for the account's user. It is returned in responses and can be used as a filter."}},"required":["provider","refreshToken"],"additionalProperties":false}}},"required":["accounts"],"additionalProperties":false},"example":{"accounts":[{"provider":"google","refreshToken":"1//0g-your-refresh-token","subjectId":"user_123"}]}}}},"responses":{"202":{"description":"The import, queued.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/AccountImport"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"aimp_36c11c55818fa0cad686b7d8","status":"queued","total":1,"counts":{"pending":1,"created":0,"updated":0,"failed":0},"items":[{"index":0,"provider":"google","subjectId":"user_123","status":"pending","accountId":null,"email":null,"error":null}],"createdAt":"2026-11-08T20:00:32.783Z","finishedAt":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_PROVIDER_NOT_CONFIGURED`: The app is not configured to connect accounts from this provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/imports":{"get":{"operationId":"accounts.imports.list","summary":"List account imports","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"The number of imports to return, newest first. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Recent imports, without their per-account results.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","done"]},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"counts":{"type":"object","properties":{"pending":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["pending","created","updated","failed"],"additionalProperties":false},"createdAt":{"type":"string"},"finishedAt":{"type":["string","null"]}},"required":["id","status","total","counts","createdAt","finishedAt"],"additionalProperties":false}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/imports/{importId}":{"get":{"operationId":"accounts.imports.get","summary":"Get an account import","description":"**In the sandbox:** Use the ID returned by `POST /v2/accounts/import`.","tags":["Accounts"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND"},"parameters":[{"name":"importId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"example":"aimp_0123456789abcdef01234567"}],"responses":{"200":{"description":"The import's progress and the result for each account.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/AccountImport"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"aimp_36c11c55818fa0cad686b7d8","status":"done","total":1,"counts":{"pending":0,"created":1,"updated":0,"failed":0},"items":[{"index":0,"provider":"google","subjectId":"user_123","status":"created","accountId":"00d34c15-3251-490a-a8ff-01c8ce8de35d","email":"refresh@example.test","error":null}],"createdAt":"2026-11-08T20:00:32.783Z","finishedAt":"2026-11-08T20:00:32.879Z"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/imports/{importId}/retry":{"post":{"operationId":"accounts.imports.retry","summary":"Retry an account import","description":"Retries the accounts that failed with an error that may since have been resolved, such as an unavailable provider or a plan that had reached its connected account limit.\n\n**In the sandbox:** Use the ID returned by `POST /v2/accounts/import`.","tags":["Accounts"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND"},"parameters":[{"name":"importId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"example":"aimp_0123456789abcdef01234567"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"202":{"description":"The import, queued again.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/AccountImport"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"aimp_36766aa0cea9fddd52b0fb7d","status":"queued","total":1,"counts":{"pending":1,"created":0,"updated":0,"failed":0},"items":[{"index":0,"provider":"google","subjectId":"user_456","status":"pending","accountId":null,"email":null,"error":null}],"createdAt":"2026-11-08T20:00:32.884Z","finishedAt":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/accounts/status":{"get":{"operationId":"accounts.status.list","summary":"Get the status of several accounts","description":"Returns the status of each account. `overall.status` is `healthy`, `attention` or `broken`, and `overall` includes the reason and the fix. The response also shows which features are available, and includes a message for the account's owner when they need to take action. `meta.needsAttention` is the number of accounts in the response whose `overall.status` is not `healthy`.\n\nWith `accountIds` or `subjectId`, returns those accounts. Without them, returns every account of the app in the order they were added, one page at a time. To find every account that needs fixing, send `overall=attention,broken`. A page can include fewer than `limit` accounts even when `meta.nextCursor` is set, so keep requesting pages until `meta.nextCursor` is `null`. `check` works only with `accountIds` or `subjectId`.\n\n**In the sandbox:** Lists every account in the app that needs action. In a new sandbox, every account works, so the list is empty. To check particular accounts instead, send `accountIds` or `subjectId`.","tags":["Accounts"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountIds","in":"query","required":false,"description":"The Pyas `accountId` values of up to 20 connected accounts. Send a comma-separated list or repeat the parameter.","schema":{"type":"string"}},{"name":"subjectId","in":"query","required":false,"description":"Selects every connected account labeled with this `subjectId`.","schema":{"type":"string","minLength":1,"maxLength":255}},{"name":"provider","in":"query","required":false,"description":"Limits `accountIds` or `subjectId` to accounts on this provider.","schema":{"type":"string","enum":["google","microsoft","pyas"]}},{"name":"overall","in":"query","required":false,"description":"Returns only accounts whose `overall.status` is one of these values, for example `attention,broken`. Works only without `accountIds` or `subjectId`. Accepts a comma-separated list of any of these values: healthy, attention, broken.","schema":{"type":"string","maxLength":512},"example":"attention,broken"},{"name":"limit","in":"query","required":false,"description":"The maximum number of accounts in one page, from 1 to 200. Defaults to 50. Works only without `accountIds` or `subjectId`.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","minLength":1,"maxLength":2048}},{"name":"check","in":"query","required":false,"description":"Sends one request to the provider immediately, bypassing the cache, and includes the result.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Each account's status.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/AccountStatus"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"notFound":{"description":"Requested IDs that do not match an account.","type":"array","items":{"type":"string"}},"needsAttention":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"nextCursor":{"description":"Send it as `cursor` to get the next page. It is `null` on the last page, and is included only when the request doesn't include `accountIds` or `subjectId`.","type":["string","null"]}},"required":["needsAttention"],"additionalProperties":false}}},"example":{"success":true,"data":[],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"needsAttention":0,"nextCursor":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendar-groups":{"get":{"operationId":"calendarGroups.list","summary":"List calendar groups","description":"Calendar groups are Outlook folders that contain calendars. Google Calendar doesn't have calendar groups, so requests for Google accounts are rejected.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"}],"responses":{"200":{"description":"The groups, with their calendars.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/CalendarGroup"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[{"id":"{{group.outlook.mine}}","name":"My Calendars","calendarIds":["{{calendar.outlook.primary}}"]},{"id":"{{group.outlook.others}}","name":"Other calendars","calendarIds":["{{calendar.outlook.morgan}}"]},{"id":"{{group.outlook.clients}}","name":"Clients","calendarIds":["{{calendar.outlook.acme}}"]},{"id":"{{group.outlook.projects}}","name":"Projects","calendarIds":[]}],"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"calendarGroups.create","summary":"Create a calendar group","description":"Calendar groups are Outlook folders that contain calendars. Google Calendar doesn't have calendar groups, so requests for Google accounts are rejected.\n\n**In the sandbox:** Calendar groups are an Outlook feature. For Google accounts, the API returns an error explaining that Google doesn't support them.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of the connected account. You can send it here or in the query.","type":"string"},"name":{"type":"string","minLength":1,"maxLength":255}},"required":["name"],"additionalProperties":false},"example":{"name":"Partners"}}}},"responses":{"201":{"description":"The group.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarGroup"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"AAMkAkhQyt3s2NcmZzvgLwdE68IZ07bC7gBnR6Qr6TyKO3qYAAA=","name":"Partners","calendarIds":[]},"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.\n\n`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendar-groups/{groupId}":{"delete":{"operationId":"calendarGroups.delete","summary":"Delete a calendar group","description":"Calendar groups are Outlook folders that contain calendars. Google Calendar doesn't have calendar groups, so requests for Google accounts are rejected.\n\n**In the sandbox:** Outlook doesn't delete a group that still contains calendars, and the API returns an error explaining why.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{group.outlook.projects}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"calendarGroups.rename","summary":"Rename a calendar group","description":"Calendar groups are Outlook folders that contain calendars. Google Calendar doesn't have calendar groups, so requests for Google accounts are rejected.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{group.outlook.projects}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of the connected account. You can send it here or in the query.","type":"string"},"name":{"type":"string","minLength":1,"maxLength":255}},"required":["name"],"additionalProperties":false},"example":{"name":"Key projects"}}}},"responses":{"200":{"description":"The group.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarGroup"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{group.outlook.projects}}","name":"Key projects","calendarIds":[]},"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.\n\n`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars":{"get":{"operationId":"calendars.list","summary":"List calendars","description":"Returns the calendars of one connected account, one page at a time. With `accountIds` or `subjectId`, returns every calendar of each account in one response, grouped by account.","tags":["Calendars"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /google/calendars","GET /microsoft/calendars"]},"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"limit","in":"query","required":false,"description":"The maximum number of results in one page.","schema":{"type":"integer","minimum":1,"maximum":250}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","maxLength":4096}},{"name":"accountIds","in":"query","required":false,"description":"The Pyas `accountId` values of up to 20 connected accounts. Send a comma-separated list or repeat the parameter.","schema":{"type":"string"}},{"name":"subjectId","in":"query","required":false,"description":"Selects every connected account labeled with this `subjectId`.","schema":{"type":"string","minLength":1,"maxLength":255}},{"name":"provider","in":"query","required":false,"description":"Limits `accountIds` or `subjectId` to accounts on this provider.","schema":{"type":"string","enum":["google","microsoft","pyas"]}}],"responses":{"200":{"description":"The calendars. With several accounts, the calendars are grouped by account.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Calendar"}},{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"provider":{"anyOf":[{"$ref":"#/components/schemas/Provider"},{"type":"null"}]},"subjectId":{"type":["string","null"]},"calendars":{"type":"array","items":{"$ref":"#/components/schemas/Calendar"}},"truncated":{"description":"The account has more calendars than one response can include.","type":"boolean","const":true},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["accountId","provider","subjectId","calendars"],"additionalProperties":false}}]},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"anyOf":[{"type":"object","properties":{"nextCursor":{"description":"Pass it as `cursor` to get the next page. `null` on the last page.","type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false},{"type":"object","properties":{"partial":{"type":"boolean"}},"required":["partial"],"additionalProperties":false}]}}},"example":{"success":true,"data":[{"id":"{{calendar.avery.primary}}","name":"Avery Brooks","description":null,"timezone":"America/New_York","isPrimary":true,"color":null,"accessRole":"owner","location":null,"conferencing":{"default":null,"allowed":["zoom"]},"tallyResponses":null,"hidden":false,"provider":"pyas","providerRefs":{"calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{calendar.avery.work}}","name":"Work","description":null,"timezone":"America/New_York","isPrimary":false,"color":"#039be5","accessRole":"owner","location":null,"conferencing":{"default":null,"allowed":["zoom"]},"tallyResponses":null,"hidden":false,"provider":"pyas","providerRefs":{"calendarId":"{{calendar.avery.work}}","accountId":"{{account.avery}}"},"metadata":null}],"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"calendars.create","summary":"Create a calendar","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarWrite"},"example":{"accountId":"{{account.avery}}","name":"Client meetings","timezone":"America/New_York","color":"#33b679","metadata":{"team":"sales"}}}}},"responses":{"201":{"description":"The calendar.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Calendar"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"calba3nh0btrcap9js6fcfv","name":"Client meetings","description":null,"timezone":"America/New_York","isPrimary":false,"color":"#33b679","accessRole":"owner","location":null,"conferencing":{"default":null,"allowed":["zoom"]},"tallyResponses":null,"hidden":false,"provider":"pyas","providerRefs":{"calendarId":"calba3nh0btrcap9js6fcfv","accountId":"{{account.avery}}"},"metadata":{"team":"sales"}},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.\n\n`VALIDATION_INVALID_TIMEZONE`: The time zone is not an IANA time zone name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}":{"delete":{"operationId":"calendars.delete","summary":"Delete a calendar","description":"Deletes the calendar and its events at the provider. A primary calendar cannot be deleted.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{calendar.jordan.work}}"},{"name":"accountId","in":"query","required":true,"description":"The `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.jordan}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"calendars.get","summary":"Get a calendar","tags":["Calendars"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /google/calendars/:id","GET /microsoft/calendars/:id"]},"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{calendar.avery.work}}"},{"name":"accountId","in":"query","required":true,"description":"The `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"}],"responses":{"200":{"description":"The calendar.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Calendar"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{calendar.avery.work}}","name":"Work","description":null,"timezone":"America/New_York","isPrimary":false,"color":"#039be5","accessRole":"owner","location":null,"conferencing":{"default":null,"allowed":["zoom"]},"tallyResponses":null,"hidden":false,"provider":"pyas","providerRefs":{"calendarId":"{{calendar.avery.work}}","accountId":"{{account.avery}}"},"metadata":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"calendars.update","summary":"Update a calendar","description":"Updates the calendar. Send only the fields to update. Set `description`, `timezone`, `color` or `location` to `null` to clear it.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{calendar.avery.work}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","description":"The `accountId` of the connected account. You can send it here or in the query."},"name":{"type":"string","maxLength":256},"description":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}]},"timezone":{"type":["string","null"]},"color":{"description":"The color, as `#rrggbb`.","type":["string","null"]},"location":{"description":"Google Calendar only.","type":["string","null"]},"conferencing":{"type":"object","properties":{"default":{"type":["string","null"]},"allowed":{"type":"array","items":{"type":"string"}}},"additionalProperties":false},"tallyResponses":{"description":"Outlook only.","type":"boolean"},"hidden":{"description":"Google Calendar only. Whether to hide the calendar from the calendar list.","type":"boolean"},"groupId":{"description":"Outlook only, when creating a calendar. The calendar group to create it in.","type":"string"},"metadata":{"$ref":"#/components/schemas/Metadata"},"providerOptions":{"$ref":"#/components/schemas/ProviderOptions"}},"additionalProperties":false},"example":{"name":"Work (team)"}}}},"responses":{"200":{"description":"The calendar.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Calendar"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{calendar.avery.work}}","name":"Work (team)","description":null,"timezone":"America/New_York","isPrimary":false,"color":"#039be5","accessRole":"owner","location":null,"conferencing":{"default":null,"allowed":["zoom"]},"tallyResponses":null,"hidden":false,"provider":"pyas","providerRefs":{"calendarId":"{{calendar.avery.work}}","accountId":"{{account.avery}}"},"metadata":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.\n\n`VALIDATION_INVALID_TIMEZONE`: The time zone is not an IANA time zone name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}/categories":{"get":{"operationId":"calendars.categories.list","summary":"List categories","description":"Lists the values that events accept in `categories`. On Outlook, there is one list for the whole mailbox. On Google Calendar, these are the calendar's event labels.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"}],"responses":{"200":{"description":"The categories.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Category"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[{"id":"{{category.outlook.red}}","name":"Red category","color":"#e74856"},{"id":"{{category.outlook.orange}}","name":"Orange category","color":"#f7630c"},{"id":"{{category.outlook.yellow}}","name":"Yellow category","color":"#fce100"},{"id":"{{category.outlook.green}}","name":"Green category","color":"#16c60c"},{"id":"{{category.outlook.blue}}","name":"Blue category","color":"#0078d7"},{"id":"{{category.outlook.purple}}","name":"Purple category","color":"#8764b8"}],"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"calendars.categories.create","summary":"Create a category","description":"**In the sandbox:** Outlook categories belong to the mailbox, so they are the same for every calendar, and they use Outlook's own colors (the nearest color is used). Google categories are per-calendar labels and accept any color.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of the connected account. You can send it here or in the query.","type":"string"},"name":{"type":"string","minLength":1,"maxLength":255},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$","examples":["#33b679"]}},"required":["name"],"additionalProperties":false},"example":{"name":"Client work","color":"#33b679"}}}},"responses":{"201":{"description":"The category.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Category"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"ee111d87-0428-40cf-875f-2f0f2b7c5d4a","name":"Client work","color":"#16c60c"},"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.\n\n`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}/categories/{categoryId}":{"delete":{"operationId":"calendars.categories.delete","summary":"Delete a category","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"categoryId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{category.outlook.yellow}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"calendars.categories.update","summary":"Update a category","description":"**In the sandbox:** On Outlook, you can update a category's color but not its name. On Google, you can also rename labels.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"categoryId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{category.outlook.blue}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of the connected account. You can send it here or in the query.","type":"string"},"name":{"type":"string","minLength":1,"maxLength":255},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$","examples":["#33b679"]}},"additionalProperties":false},"example":{"color":"#f6bf26"}}}},"responses":{"200":{"description":"The category.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Category"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{category.outlook.blue}}","name":"Blue category","color":"#fce100"},"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.\n\n`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}/feed":{"delete":{"operationId":"calendars.feed.disable","summary":"Disable a calendar's feed","description":"Disables the feed. The feed link stops working, and subscribers stop receiving updates.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the virtual calendar account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.sam}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The feed.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarFeed"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"enabled":false,"url":null,"webcalUrl":null,"details":null,"createdAt":null,"expiresAt":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"calendars.feed.get","summary":"Get a calendar's feed","description":"Returns the state and link of a virtual calendar's iCalendar subscription feed, which calendar apps can subscribe to.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the virtual calendar account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.sam}}"}],"responses":{"200":{"description":"The feed.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarFeed"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"enabled":false,"url":null,"webcalUrl":null,"details":null,"createdAt":null,"expiresAt":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"calendars.feed.enable","summary":"Enable a calendar's feed","description":"Publishes a virtual calendar as an iCalendar feed that people can subscribe to. If the feed is already enabled, only `details` is updated, and the link stays the same.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the virtual calendar account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.sam}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":128,"description":"The `accountId` of the virtual calendar account. You can also send it as a query parameter."},"details":{"description":"`full` (the default) includes titles, locations and notes. `busy` shows only when the calendar is busy.","type":"string","enum":["full","busy"]}},"additionalProperties":false},"example":{"details":"busy"}}}},"responses":{"200":{"description":"The feed.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarFeed"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"enabled":true,"url":"https://cal.pyas.io/feeds/D_Gflr0xO2HNSXG26-HC1jZIOauvvfJyBo_S7MbS8IA.ics","webcalUrl":"webcal://cal.pyas.io/feeds/D_Gflr0xO2HNSXG26-HC1jZIOauvvfJyBo_S7MbS8IA.ics","details":"busy","createdAt":"2026-11-08T20:00:25.503Z","expiresAt":"2026-11-15T20:00:25.503Z"},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.\n\n`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}/feed/rotate":{"post":{"operationId":"calendars.feed.rotate","summary":"Rotate a feed's link","description":"Creates a new link for the feed. The old link stops working immediately. Use this when a link was shared too widely.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the virtual calendar account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.sam}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The feed.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarFeed"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"enabled":true,"url":"https://cal.pyas.io/feeds/lWpiTMfSX4Gl5H8tvoNz966qj6jeZuWGltO0U_1tdYw.ics","webcalUrl":"webcal://cal.pyas.io/feeds/lWpiTMfSX4Gl5H8tvoNz966qj6jeZuWGltO0U_1tdYw.ics","details":"busy","createdAt":"2026-11-08T20:00:25.510Z","expiresAt":"2026-11-15T20:00:25.510Z"},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}/permissions":{"get":{"operationId":"calendars.permissions.list","summary":"List calendar permissions","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"}],"responses":{"200":{"description":"The calendar's permissions, in the same format for Google Calendar and Outlook.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/CalendarPermission"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[{"id":"user:{{calendar.google.primary}}","grantee":{"type":"user","email":"{{calendar.google.primary}}","domain":null,"name":null},"role":"owner","removable":false},{"id":"user:sam.patel@example.org","grantee":{"type":"user","email":"sam.patel@example.org","domain":null,"name":null},"role":"read","removable":true}],"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"calendars.permissions.create","summary":"Share a calendar","description":"**In the sandbox:** Each provider supports its own set of roles. Google supports `freeBusy`, `read`, `write` and `owner`. Outlook also supports `limitedRead`, and has delegate roles instead of `owner`. If a provider doesn't support a role, the request is rejected with an error that explains why.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of the connected account. You can send it here or in the query.","type":"string"},"grantee":{"type":"object","properties":{"type":{"type":"string","enum":["user","group","domain","public","organization"]},"email":{"description":"The email address. Required for a `user` or `group`.","type":"string"},"domain":{"description":"The domain, such as `example.com`. Required for a `domain`.","type":"string"},"name":{"type":"string"}},"required":["type"],"description":"Who to share the calendar with."},"role":{"$ref":"#/components/schemas/PermissionRole"},"notify":{"description":"Whether to email the grantee about the new permission. Google Calendar only, because Outlook decides whether to send the email.","type":"boolean"}},"required":["grantee","role"],"additionalProperties":false},"example":{"grantee":{"type":"user","email":"assistant@example.com"},"role":"read"}}}},"responses":{"201":{"description":"The new permission.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarPermission"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"user:assistant@example.com","grantee":{"type":"user","email":"assistant@example.com","domain":null,"name":null},"role":"read","removable":true},"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.\n\n`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}/permissions/{permissionId}":{"delete":{"operationId":"calendars.permissions.delete","summary":"Delete a calendar permission","description":"**In the sandbox:** Deleting a share that no longer exists also returns `200`, on every provider.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"permissionId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024},"example":"user:assistant@example.com"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"calendars.permissions.update","summary":"Update a calendar permission","description":"**In the sandbox:** Google identifies a share by its grantee (`user:email`), and Outlook uses its own ID. Use an ID from the list.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"primary"},{"name":"permissionId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024},"example":"user:sam.patel@example.org"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of the connected account. You can send it here or in the query.","type":"string"},"role":{"$ref":"#/components/schemas/PermissionRole"}},"required":["role"],"additionalProperties":false},"example":{"role":"write"}}}},"responses":{"200":{"description":"The permission.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/CalendarPermission"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"user:sam.patel@example.org","grantee":{"type":"user","email":"sam.patel@example.org","domain":null,"name":null},"role":"write","removable":true},"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.\n\n`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/{calendarRef}/subscription":{"delete":{"operationId":"calendars.unsubscribe","summary":"Unsubscribe from a calendar","description":"Removes the calendar from the account's calendar list. The calendar itself isn't deleted.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"calendarRef","in":"path","required":true,"description":"The calendar ID returned by the provider, or `primary` for the account's primary calendar.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{calendar.google.holidays}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/calendars/subscribe":{"post":{"operationId":"calendars.subscribe","summary":"Subscribe to a calendar","description":"Adds a calendar that the account has access to, such as a colleague's calendar or a shared calendar, to the account's calendar list.\n\n**In the sandbox:** Google adds any calendar the account has access to. The sandbox accepts any calendar ID, but a live account must have access to the calendar. Outlook adds a shared calendar only when the person accepts the invitation, so for Outlook accounts the API returns an error explaining that it can't add the calendar.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of the connected account. You can send it here or in the query.","type":"string"},"calendarId":{"type":"string","minLength":1,"description":"The ID of the calendar to add, such as a colleague's email address."}},"required":["calendarId"],"additionalProperties":false},"example":{"accountId":"{{account.google}}","calendarId":"team-calendar@example.com"}}}},"responses":{"201":{"description":"The calendar, now in the account's calendar list.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Calendar"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"team-calendar@example.com","name":"team-calendar@example.com","description":null,"timezone":"America/New_York","isPrimary":false,"color":"#9fc6e7","accessRole":"reader","location":null,"conferencing":{"default":null,"allowed":[]},"tallyResponses":null,"hidden":false,"provider":"google","providerRefs":{"calendarId":"team-calendar@example.com","accountId":"{{account.google}}"}},"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.\n\n`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/colors":{"get":{"operationId":"colors.get","summary":"Get color palettes","description":"Returns the calendar and event colors that the account's provider offers, as `#rrggbb` values.","tags":["Calendars"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"}],"responses":{"200":{"description":"The palettes.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Palette"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"calendarColors":[{"id":"1","color":"#ac725e"},{"id":"2","color":"#d06b64"},{"id":"3","color":"#f83a22"},{"id":"4","color":"#fa573c"},{"id":"5","color":"#ff7537"},{"id":"6","color":"#ffad46"},{"id":"7","color":"#42d692"},{"id":"8","color":"#16a765"},{"id":"9","color":"#7bd148"},{"id":"10","color":"#b3dc6c"},{"id":"11","color":"#fbe983"},{"id":"12","color":"#fad165"},{"id":"13","color":"#92e1c0"},{"id":"14","color":"#9fe1e7"},{"id":"15","color":"#9fc6e7"},{"id":"16","color":"#4986e7"},{"id":"17","color":"#9a9cff"},{"id":"18","color":"#b99aff"},{"id":"19","color":"#c2c2c2"},{"id":"20","color":"#cabdbf"},{"id":"21","color":"#cca6ac"},{"id":"22","color":"#f691b2"},{"id":"23","color":"#cd74e6"},{"id":"24","color":"#a47ae2"}],"eventColors":[{"id":"1","color":"#a4bdfc"},{"id":"2","color":"#7ae7bf"},{"id":"3","color":"#dbadff"},{"id":"4","color":"#ff887c"},{"id":"5","color":"#fbd75b"},{"id":"6","color":"#ffb878"},{"id":"7","color":"#46d6db"},{"id":"8","color":"#e1e1e1"},{"id":"9","color":"#5484ed"},{"id":"10","color":"#51b749"},{"id":"11","color":"#dc2127"}]},"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/accounts":{"post":{"operationId":"connect.accounts.create","summary":"Connect an account with a code","description":"Exchanges the code for tokens, saves the account and returns it. This is the second step of connecting an account from your server without PyasConnect, and it replaces v1's `POST /{provider}/connect`. Send the `code` that the provider returned. If the same person connects an account that is already connected, Pyas reconnects it and the account keeps its `accountId`.\n\n**In the sandbox:** Send the `code` that your Redirect URL (Pyas Auth) or your own callback URL (Native Auth) received after `GET /v2/connect/oauth`. This request requires a live key.","tags":["Connect"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":403,"code":"AUTH_SANDBOX_MISMATCH"},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","enum":["google","microsoft","zoom"],"description":"The provider in `GET /v2/connect/oauth`."},"code":{"type":"string","minLength":1,"maxLength":4096,"description":"The `code` that the provider returned to your Redirect URL or callback URL."},"subjectId":{"type":"string","minLength":1,"maxLength":255,"description":"Your own identifier for the user, stored on the account."},"features":{"description":"The same features as in `GET /v2/connect/oauth`.","type":"array","items":{"type":"string","enum":["manageCalendars","sharing","meetingSettings","attachmentUploads","rooms"]}},"redirectUrl":{"type":"string","minLength":1,"maxLength":2048,"description":"The same `redirectUrl` as in `GET /v2/connect/oauth`, if you sent one."}},"required":["provider","code"],"additionalProperties":false},"example":{"provider":"google","code":"4/0AeanS0Z...","subjectId":"user_123"}}}},"responses":{"200":{"description":"The connected account.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/ConnectedAccount"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"accountId":"ef66ec55-7f3c-44f8-8e6d-3e8bc2fafc4b","provider":"google","email":"{{calendar.google.primary}}","name":"Avery Brooks","subjectId":"user_123","existing":true,"grantedScopes":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`BILLING_CONNECTION_LIMIT`: The plan's connected account limit has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_PROVIDER_NOT_CONFIGURED`: The app is not configured to connect accounts from this provider.\n\n`CONNECTION_CONSENT_FAILED`: The provider did not complete the connection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/authorize":{"post":{"operationId":"connect.authorize","summary":"Get the consent URL (popup mode)","description":"Returns the provider's consent URL to open in a popup. This is the second step. Call it from your page with the session's token, from one of the app's allowed origins. For a session created with a test key, the URL is a Pyas sandbox page instead of the provider's. Requesting a new URL, for example after the user switches provider, invalidates the previous one.\n\n**In the sandbox:** Call this from your page with a session's token. Create the session on your server with `POST /v2/connect/sessions`.","tags":["Connect"],"security":[],"x-pyas-sandbox":{"status":401,"code":"AUTH_INVALID_CONNECT_SESSION"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"The session's token."},"provider":{"type":"string","description":"`google`, `microsoft` or `zoom`. Must be one of the session's providers. Optional when the session offers only one provider."}},"required":["token"]},"example":{"token":"pcs_your-session-token","provider":"google"}}}},"responses":{"200":{"description":"The consent URL to send the user to.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"provider":{"type":"string","enum":["google","microsoft","zoom"]},"url":{"type":"string"},"expiresAt":{"type":"string"}},"required":["provider","url","expiresAt"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"provider":"google","url":"https://accounts.google.com/o/oauth2/v2/auth?client_id=1234567890-pyas.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fapi.pyas.io%2Foauth%2Fgoogle%2Fcallback&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.events+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.freebusy+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.events.freebusy+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.calendarlist.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.calendars.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.settings.readonly&access_type=offline&prompt=consent&include_granted_scopes=true&state=app_id%3D5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365_rest%3Dpcs1.cs_99bec7442c4db29a8539d679.9Z_srW0El4rA9gop9VssvA","expiresAt":"2026-11-08T20:10:32.621Z"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_CONNECT_SESSION`: The connect session is missing, invalid, expired or already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_ORIGIN_NOT_ALLOWED`: The request's origin is not in the app's allowed origins.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_PROVIDER_NOT_CONFIGURED`: The app is not configured to connect accounts from this provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/complete":{"post":{"operationId":"connect.complete","summary":"Complete a connection","description":"Exchanges the code that the provider returned and saves the account. This is the third step. Send the `code` and `state` that the provider returned. For a session created with a test key, the code comes from the Pyas sandbox page and the account is a simulated one in your sandbox. Each session can be completed only once.\n\n**In the sandbox:** Send the `code` and `state` that the provider returns after sign-in.","tags":["Connect"],"security":[],"x-pyas-sandbox":{"status":401,"code":"AUTH_INVALID_CONNECT_SESSION"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"The session's token."},"code":{"type":"string","description":"The `code` that the provider returned."},"state":{"type":"string","description":"The `state` that the provider returned."}},"required":["token","code","state"]},"example":{"token":"pcs_your-session-token","code":"the-code-from-the-provider","state":"the-state-from-the-provider"}}}},"responses":{"200":{"description":"The connected account.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/ConnectedAccount"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"accountId":"ef66ec55-7f3c-44f8-8e6d-3e8bc2fafc4b","provider":"google","email":"{{calendar.google.primary}}","name":"Avery Brooks","subjectId":"user_123","existing":false,"grantedScopes":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_CONNECT_SESSION`: The connect session is missing, invalid, expired or already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"`BILLING_CONNECTION_LIMIT`: The plan's connected account limit has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_ORIGIN_NOT_ALLOWED`: The request's origin is not in the app's allowed origins.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_LIMIT_REACHED`: The limit for this resource has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_CONSENT_FAILED`: The provider did not complete the connection.\n\n`CONNECTION_PROVIDER_NOT_CONFIGURED`: The app is not configured to connect accounts from this provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/go":{"get":{"operationId":"connect.go","summary":"Start a connection (redirect mode)","description":"The `url` of a redirect-mode session. It redirects the user to the provider's consent page, after showing a provider chooser when the session offers more than one provider. For a session created with a test key, it redirects to a Pyas sandbox page instead. This is a page for browsers, not an API endpoint.\n\n**In the sandbox:** The `url` of a redirect-mode session, opened in a browser.","tags":["Connect"],"security":[],"x-pyas-sandbox":{"status":410},"parameters":[{"name":"token","in":"query","required":true,"description":"The session's token, included in its `url`.","schema":{"type":"string"},"example":"pcs_your-session-token"},{"name":"provider","in":"query","required":false,"description":"The provider to use: `google`, `microsoft` or `zoom`. Sending it skips the provider chooser.","schema":{"type":"string"}},{"name":"locale","in":"query","required":false,"description":"The language of the pages: `en`, `nb`, `sv`, `da`, `de`, `fr`, `es`, `nl` or `pt-BR`. If you leave it out, the browser's language is used, then English.","schema":{"type":"string"}}],"responses":{"200":{"description":"The provider chooser.","content":{"text/html":{"schema":{"type":"string"}}}},"302":{"description":"Redirects to the provider's consent page."},"410":{"description":"The session has expired or was already used.","content":{"text/html":{"schema":{"type":"string"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/info":{"post":{"operationId":"connect.info","summary":"Get connect widget details","description":"Returns the details that the connect widget displays before the user signs in. These include your app's name and icon from the dashboard, the providers the session offers and, for a reconnect, the account to reconnect. Call it from your page with the session's token, from one of the app's allowed origins. This request has no side effects.\n\n**In the sandbox:** Call this from your page with a session's token, before the user signs in. Create the session on your server with `POST /v2/connect/sessions`.","tags":["Connect"],"security":[],"x-pyas-sandbox":{"status":401,"code":"AUTH_INVALID_CONNECT_SESSION"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"The session's token."}},"required":["token"]},"example":{"token":"pcs_your-session-token"}}}},"responses":{"200":{"description":"The details to display.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"app":{"type":"object","properties":{"name":{"type":"string"},"iconUrl":{"type":["string","null"]}},"required":["name","iconUrl"],"additionalProperties":false},"providers":{"type":"array","items":{"type":"string","enum":["google","microsoft","zoom"]}},"reconnect":{"anyOf":[{"type":"object","properties":{"email":{"type":["string","null"]},"provider":{"type":"string","enum":["google","microsoft","zoom"]}},"required":["email","provider"],"additionalProperties":false},{"type":"null"}]},"loginHint":{"type":["string","null"]},"expiresAt":{"type":"string"}},"required":["app","providers","reconnect","loginHint","expiresAt"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"app":{"name":"Acme Scheduler","iconUrl":null},"providers":["google","microsoft"],"reconnect":null,"loginHint":null,"expiresAt":"2026-11-08T20:10:32.621Z"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_CONNECT_SESSION`: The connect session is missing, invalid, expired or already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_ORIGIN_NOT_ALLOWED`: The request's origin is not in the app's allowed origins.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/oauth":{"get":{"operationId":"connect.oauth","summary":"Get a sign-in URL","description":"Returns the provider's sign-in URL. This is the first step of connecting an account from your server without PyasConnect, and it replaces v1's `GET /{provider}/oauth`. Send the user to `url`. With Pyas Auth, the user returns to the Redirect URL you set for this provider under Provider setup, with `code` and your `state`. With Native Auth, the user returns to your own callback URL. Then send the code to `POST /v2/connect/accounts`.\n\n**In the sandbox:** Connecting signs a real person in to Google, Outlook or Zoom, so it requires a live key. To test connecting in the sandbox, use PyasConnect with a session from `POST /v2/connect/sessions`, or create virtual accounts with `POST /v2/accounts`.","tags":["Connect"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":403,"code":"AUTH_SANDBOX_MISMATCH"},"parameters":[{"name":"provider","in":"query","required":true,"description":"`google`, `microsoft` or `zoom`.","schema":{"type":"string","enum":["google","microsoft","zoom"]},"example":"google"},{"name":"state","in":"query","required":false,"description":"Your own value, which is returned to you with the code. For example, use it to identify which of your users is signing in.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"user_123"},{"name":"loginHint","in":"query","required":false,"description":"The email address to suggest when the user signs in.","schema":{"type":"string","minLength":1,"maxLength":320},"example":"person@example.com"},{"name":"features","in":"query","required":false,"description":"Additional permissions to request. Accepts a comma-separated list of any of these values: manageCalendars, sharing, meetingSettings, attachmentUploads, rooms.","schema":{"type":"string","maxLength":512}},{"name":"redirectUrl","in":"query","required":false,"description":"The callback URL to return the user to, instead of the one under Provider setup. Works only with Native Auth, and your OAuth app must list this URL as a redirect URI.","schema":{"type":"string","minLength":1,"maxLength":2048}}],"responses":{"200":{"description":"The URL to send the user to.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"provider":{"type":"string","enum":["google","microsoft","zoom"]},"url":{"type":"string"}},"required":["provider","url"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"provider":"google","url":"https://accounts.google.com/o/oauth2/v2/auth?client_id=1234567890-pyas.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fapi.pyas.io%2Foauth%2Fgoogle%2Fcallback&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.events+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.freebusy+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.events.freebusy+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.calendarlist.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.calendars.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.settings.readonly&access_type=offline&prompt=consent&include_granted_scopes=true&state=app_id%3D5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365_rest%3Duser_123&login_hint=person%40example.com"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_PROVIDER_NOT_CONFIGURED`: The app is not configured to connect accounts from this provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/sessions":{"post":{"operationId":"connect.sessions.create","summary":"Create a connect session","description":"Creates a session for connecting a calendar account. This is the first step of connecting with PyasConnect. Call it from your server. With a live key, the user signs in to Google, Microsoft or Zoom and a real account is connected. With a test key, the user sees a Pyas sandbox page instead of the provider's sign-in, and a simulated account is connected in your sandbox, so you can build and test the whole flow before going live. In popup mode, pass the `token` to your page. In redirect mode, set a `returnUrl` and send the user to `url`. A session is valid for 10 minutes and connects one account.\n\n**In the sandbox:** Pass the `token` to PyasConnect on your page. With a test key, PyasConnect opens a Pyas sandbox page instead of Google or Microsoft, and connects a simulated account in your sandbox. For redirect mode, add a `returnUrl` on one of your app's allowed origins. To reconnect a broken account, send its `accountId` instead of `providers` and `subjectId`.","tags":["Connect"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"description":"The `accountId` of an existing account to reconnect. PyasConnect opens directly to the account's provider, and only the same person (with the same email address) can sign in. The account keeps its `accountId`. Leave out `providers`, `subjectId` and `loginHint`, because they are taken from the account.","type":"string"},"providers":{"description":"The providers to offer the user. Defaults to `google` and `microsoft`. Zoom is offered only when you include `zoom`.","type":"array","items":{"type":"string","enum":["google","microsoft","zoom"]}},"products":{"description":"What the connection is used for. Currently only `calendar` is supported.","type":"array","items":{"type":"string","const":"calendar"}},"features":{"description":"Additional permissions to request: `manageCalendars`, `sharing`, `meetingSettings`, `attachmentUploads` or `rooms`. With Pyas Auth, Google `manageCalendars`, `sharing`, `meetingSettings`, `attachmentUploads` and `rooms` need Native Auth for now.","type":"array","items":{"type":"string","enum":["manageCalendars","sharing","meetingSettings","attachmentUploads","rooms"]}},"subjectId":{"description":"Your own identifier for the connected account.","type":"string"},"loginHint":{"description":"The email address to suggest when the user signs in.","type":"string"},"returnUrl":{"description":"For redirect mode, the URL to send the user to when the flow ends. Must use HTTPS and be on one of the app's allowed origins.","type":"string"}},"additionalProperties":false},"example":{"providers":["google","microsoft"],"subjectId":"user_123"}}}},"responses":{"201":{"description":"The session. `token` is returned only in this response.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","authorizing","completing","completed","failed"]},"mode":{"type":"string","enum":["popup","redirect"]},"reconnectAccountId":{"type":["string","null"]},"providers":{"type":"array","items":{"type":"string","enum":["google","microsoft","zoom"]}},"products":{"type":"array","items":{"type":"string"}},"features":{"type":"array","items":{"type":"string","enum":["manageCalendars","sharing","meetingSettings","attachmentUploads","rooms"]}},"subjectId":{"type":["string","null"]},"returnUrl":{"type":["string","null"]},"provider":{"anyOf":[{"type":"string","enum":["google","microsoft","zoom"]},{"type":"null"}],"description":"The provider the user chose, once they have chosen one."},"expiresAt":{"type":"string"},"account":{"anyOf":[{"$ref":"#/components/schemas/ConnectedAccount"},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]},"token":{"type":"string","description":"The credential your page uses for the browser steps (`pcs_...`)."},"url":{"description":"For redirect mode, the URL to send the user to.","type":["string","null"]}},"required":["id","status","mode","reconnectAccountId","providers","products","features","subjectId","returnUrl","provider","expiresAt","account","error","token","url"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"cs_99bec7442c4db29a8539d679","status":"pending","mode":"popup","reconnectAccountId":null,"providers":["google","microsoft"],"products":["calendar"],"features":[],"subjectId":"user_123","returnUrl":null,"provider":null,"expiresAt":"2026-11-08T20:10:32.621Z","account":null,"error":null,"token":"pcs_example","url":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_ORIGIN_NOT_ALLOWED`: The request's origin is not in the app's allowed origins.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_PROVIDER_NOT_CONFIGURED`: The app is not configured to connect accounts from this provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/connect/sessions/{id}":{"get":{"operationId":"connect.sessions.get","summary":"Get a connect session","description":"Returns the session's status and the account it connected. In redirect mode, confirm the result with this endpoint rather than relying on the query string.\n\n**In the sandbox:** Use the ID returned by `POST /v2/connect/sessions`, with the same kind of key: a session created with a test key is in the sandbox.","tags":["Connect"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"cs_0123456789abcdef01234567"}],"responses":{"200":{"description":"The session.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/ConnectSession"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"cs_99bec7442c4db29a8539d679","status":"pending","mode":"popup","reconnectAccountId":null,"providers":["google","microsoft"],"products":["calendar"],"features":[],"subjectId":"user_123","returnUrl":null,"provider":null,"expiresAt":"2026-11-08T20:10:32.621Z","account":null,"error":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events":{"get":{"operationId":"events.list","summary":"List events","description":"Lists the events in one calendar of a connected account, within an optional time window and with optional filters.\n\nTo list several accounts as one timeline in start order, send `accountIds` or `subjectId` with `from` and `to`. To find events by your own metadata across the app, send up to 5 `metadata.<key>=<value>` parameters.\n\nA recurring series is returned as one event unless `expand=true`. `sync=true` starts an incremental sync of the window. To get only the changes since then, send the `syncToken` from the last page in a later request.\n\nThe v1 parameter names (`calendarId`, `timeMin`, `timeMax`, `maxResults`, `nextPageToken` and others) still work. Responses to requests that use them include a `Pyas-Deprecated-Fields` header.","tags":["Events"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /google/events","GET /microsoft/events","GET /microsoft/events/calendarView"],"query":{"rename":{"calendarId":"calendarRef","startDate":"from","startTime":"from","timeMin":"from","endDate":"to","endTime":"to","timeMax":"to","search":"q","maxResults":"limit","singleEvents":"expand","nextPageToken":"cursor","updatedMin":"updatedSince","eventTypes":"eventType"},"times":["from","to","updatedSince"],"ignore":["timeZone","maxAttendees"],"keep":{"privateExtendedProperty":"metadata.<key>","sharedExtendedProperty":"metadata.<key>"},"refuse":{"iCalUID":"retrieve the event by its ID instead.","$filter":"v2 does not pass Outlook query filters through. Use v2's own filters, and read extended properties with include=extendedProperties and extendedPropertyIds.","$expand":"read extended properties with include=extendedProperties and extendedPropertyIds, or the provider's whole event with include=raw.","showHiddenInvitations":"v2 doesn't return hidden invitations."}},"notes":["A `maxResults` above 250 is capped. The remaining events are returned on the next page.","`orderBy=updated` maps to `sort=updated`. `orderBy=startTime` is the order of an expanded window (`expand=true`).","`showDeleted=true` also returns cancelled events. On an incremental sync, deleted events are listed in `meta.deletedIds`.","For `calendarView`, send `from`, `to` and `expand=true`. This returns the window with recurring series expanded.","`privateExtendedProperty` and `sharedExtendedProperty` (`key=value`, repeatable) still search Google events by extended property, to help you move. Search by `metadata.<key>` instead.","Outlook's `$filter` and `$expand` are refused. Use v2's own filters, and read extended properties with `include=extendedProperties` and `extendedPropertyIds`."]},"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"from","in":"query","required":false,"description":"The start of the time window.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"},"example":"{{in.-7d}}"},{"name":"to","in":"query","required":false,"description":"The end of the time window.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"},"example":"{{in.14d}}"},{"name":"expand","in":"query","required":false,"description":"Returns each occurrence of a recurring series as a separate event. Required for `sort=start`.","schema":{"type":"boolean"},"example":"true"},{"name":"limit","in":"query","required":false,"description":"The maximum number of results in one page. Defaults to 100.","schema":{"type":"integer","minimum":1,"maximum":250}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","maxLength":4096}},{"name":"syncToken","in":"query","required":false,"description":"The `syncToken` from the last page of a sync. Returns only the changes since that sync.","schema":{"type":"string","maxLength":4096}},{"name":"sync","in":"query","required":false,"description":"Starts a sync of the time window. Returns every event in the window, with a `syncToken` on the last page.","schema":{"type":"boolean"}},{"name":"sort","in":"query","required":false,"description":"The sort order: `start` (requires `expand=true`) or `updated`.","schema":{"type":"string","maxLength":16}},{"name":"include","in":"query","required":false,"description":"Additional fields to include, as a comma-separated list. `raw` is the provider's original payload. `extendedProperties` is the provider's extended properties. `conferencingSettings` is available only when you retrieve one event.","schema":{"type":"string","maxLength":64}},{"name":"extendedPropertyIds","in":"query","required":false,"description":"Outlook only, with `include=extendedProperties`. The IDs of up to 10 extended properties to read, of any type, such as `String {guid} Name orderId`, `IntegerArray {guid} Name counts` or `Integer 0x8012`.","schema":{"type":"string","maxLength":2048}},{"name":"fields","in":"query","required":false,"description":"The top-level fields to return, comma-separated, such as `id,title,startsAt,endsAt`. The `id` field is always included.","schema":{"type":"string","maxLength":1024}},{"name":"duplicates","in":"query","required":false,"description":"With several accounts, how to handle the same event on more than one calendar. `flag` (the default) marks copies with `duplicateOf`. `collapse` keeps the first and lists the others in `alsoIn`.","schema":{"type":"string","maxLength":16}},{"name":"q","in":"query","required":false,"description":"Returns events whose title, description or location contains this text.","schema":{"type":"string","maxLength":256}},{"name":"title","in":"query","required":false,"description":"Returns events whose title contains this text.","schema":{"type":"string","maxLength":256}},{"name":"location","in":"query","required":false,"description":"Returns events whose location contains this text.","schema":{"type":"string","maxLength":256}},{"name":"attendee","in":"query","required":false,"description":"Returns events with any of these attendees, as a comma-separated list of email addresses.","schema":{"type":"string","maxLength":1024}},{"name":"organizer","in":"query","required":false,"description":"Returns events organized by any of these email addresses, comma-separated.","schema":{"type":"string","maxLength":1024}},{"name":"status","in":"query","required":false,"description":"Any of `confirmed`, `tentative` and `cancelled`, comma-separated. Defaults to `confirmed,tentative`.","schema":{"type":"string","maxLength":1024}},{"name":"recurring","in":"query","required":false,"description":"`true` returns only events in a recurring series. `false` returns only single events.","schema":{"type":"boolean"}},{"name":"isAllDay","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"hasConference","in":"query","required":false,"description":"`true` returns only events with a meeting link. `false` returns only events without one.","schema":{"type":"boolean"}},{"name":"conferenceType","in":"query","required":false,"description":"The conferencing service, such as `zoom`, `meet` or `teams`.","schema":{"type":"string","maxLength":1024}},{"name":"hasAttachments","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"showAs","in":"query","required":false,"description":"Any of `busy`, `free`, `tentative`, `outOfOffice` and `workingElsewhere`, comma-separated.","schema":{"type":"string","maxLength":1024}},{"name":"eventType","in":"query","required":false,"description":"Any of `default`, `focusTime`, `outOfOffice`, `workingLocation`, `birthday` and `fromGmail`, comma-separated.","schema":{"type":"string","maxLength":1024}},{"name":"category","in":"query","required":false,"description":"Returns events with any of these categories.","schema":{"type":"string","maxLength":1024}},{"name":"importance","in":"query","required":false,"description":"Any of `low`, `normal` and `high`, comma-separated.","schema":{"type":"string","maxLength":1024}},{"name":"visibility","in":"query","required":false,"schema":{"type":"string","maxLength":1024}},{"name":"updatedSince","in":"query","required":false,"description":"Returns events updated since this time.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"}},{"name":"accountIds","in":"query","required":false,"description":"The Pyas `accountId` values of up to 20 connected accounts. Send a comma-separated list or repeat the parameter.","schema":{"type":"string"}},{"name":"subjectId","in":"query","required":false,"description":"Selects every connected account labeled with this `subjectId`.","schema":{"type":"string","minLength":1,"maxLength":255}},{"name":"provider","in":"query","required":false,"description":"Limits `accountIds` or `subjectId` to accounts on this provider.","schema":{"type":"string","enum":["google","microsoft","pyas"]}},{"name":"calendarRefs","in":"query","required":false,"description":"With several accounts, up to 10 calendars to read on each account. Defaults to `primary`. Send a comma-separated list or repeat the parameter.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of events.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"type":["string","null"]},"syncToken":{"description":"Returned on the last page of a single-calendar listing. Pass it as `syncToken` to get only the changes since this listing.","type":["string","null"]},"deletedIds":{"description":"On an incremental sync, the IDs of events deleted since the sync token was issued.","type":"array","items":{"type":"string"}},"scanned":{"description":"On a filtered listing, the number of events read to fill the page.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"accounts":{"description":"On a multi-account listing, the accounts that were read.","type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"provider":{"type":["string","null"]},"subjectId":{"type":["string","null"]}},"required":["accountId","provider","subjectId"],"additionalProperties":false}},"errors":{"description":"On a multi-account listing, the calendars that couldn't be read.","type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"},"earlierPage":{"type":"boolean","const":true}},"required":["accountId","calendarRef","code","message"],"additionalProperties":false}},"partial":{"type":"boolean"},"unavailable":{"description":"On a metadata search, the events that couldn't be read at this time.","type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"eventId":{"type":"string"},"code":{"type":"string"}},"required":["accountId","eventId","code"],"additionalProperties":false}}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[{"id":"{{event.avery.standup}}_20261102T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-02T14:30:00Z","endsAt":"2026-11-02T14:45:00Z","startsAtLocal":"2026-11-02T09:30:00-05:00","endsAtLocal":"2026-11-02T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-02T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261102T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.oneonone}}_20261102T190000Z","iCalUID":"{{event.avery.oneonone}}@cal.pyas.io","title":"1:1 with Sarah","description":null,"location":null,"startsAt":"2026-11-02T19:00:00Z","endsAt":"2026-11-02T19:30:00Z","startsAtLocal":"2026-11-02T14:00:00-05:00","endsAtLocal":"2026-11-02T14:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"zoom","joinUrl":"https://zoom.us/j/9302336753","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://zoom.us/j/9302336753","recurrence":null,"series":{"masterEventId":"{{event.avery.oneonone}}","originalStartsAt":"2026-11-02T19:00:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.578Z","updatedAt":"2026-11-08T20:00:23.578Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.oneonone}}_20261102T190000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261103T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-03T14:30:00Z","endsAt":"2026-11-03T14:45:00Z","startsAtLocal":"2026-11-03T09:30:00-05:00","endsAtLocal":"2026-11-03T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-03T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261103T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261104T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-04T14:30:00Z","endsAt":"2026-11-04T14:45:00Z","startsAtLocal":"2026-11-04T09:30:00-05:00","endsAtLocal":"2026-11-04T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-04T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261104T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261105T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-05T14:30:00Z","endsAt":"2026-11-05T14:45:00Z","startsAtLocal":"2026-11-05T09:30:00-05:00","endsAtLocal":"2026-11-05T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-05T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261105T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.productsync}}","iCalUID":"{{event.avery.productsync}}@cal.pyas.io","title":"Product Sync","description":null,"location":null,"startsAt":"2026-11-05T16:00:00Z","endsAt":"2026-11-05T17:00:00Z","startsAtLocal":"2026-11-05T11:00:00-05:00","endsAtLocal":"2026-11-05T12:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.586Z","updatedAt":"2026-11-08T20:00:23.586Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.productsync}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":{"project":"atlas"}},{"id":"{{event.avery.standup}}_20261106T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-06T14:30:00Z","endsAt":"2026-11-06T14:45:00Z","startsAtLocal":"2026-11-06T09:30:00-05:00","endsAtLocal":"2026-11-06T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-06T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261106T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.sprint}}_20261108T150000Z","iCalUID":"{{event.avery.sprint}}@cal.pyas.io","title":"Sprint Planning","description":null,"location":null,"startsAt":"2026-11-08T15:00:00Z","endsAt":"2026-11-08T16:00:00Z","startsAtLocal":"2026-11-08T10:00:00-05:00","endsAtLocal":"2026-11-08T11:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"needsAction","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":{"masterEventId":"{{event.avery.sprint}}","originalStartsAt":"2026-11-08T15:00:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.569Z","updatedAt":"2026-11-08T20:00:23.569Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.sprint}}_20261108T150000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.lunch}}","iCalUID":"{{event.avery.lunch}}@cal.pyas.io","title":"Lunch with Alex","description":null,"location":"Corner Cafe","startsAt":"2026-11-08T17:30:00Z","endsAt":"2026-11-08T18:30:00Z","startsAtLocal":"2026-11-08T12:30:00-05:00","endsAtLocal":"2026-11-08T13:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"free","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.612Z","updatedAt":"2026-11-08T20:00:23.612Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.lunch}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261109T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-09T14:30:00Z","endsAt":"2026-11-09T14:45:00Z","startsAtLocal":"2026-11-09T09:30:00-05:00","endsAtLocal":"2026-11-09T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-09T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261109T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.zoomcall}}","iCalUID":"{{event.avery.zoomcall}}@cal.pyas.io","title":"Customer onboarding (Zoom)","description":null,"location":null,"startsAt":"2026-11-09T16:00:00Z","endsAt":"2026-11-09T17:00:00Z","startsAtLocal":"2026-11-09T11:00:00-05:00","endsAtLocal":"2026-11-09T12:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"zoom","joinUrl":"https://zoom.us/j/67556028668?pwd=k1NV6aHSXvDYLT96s3yhRedsmHRIroO0","meetingId":"67556028668","passcode":"1wWGDz58DC","dialIn":[{"label":"US New York","number":"+1 555 0100","pin":"604224"}]},"meetingUrl":"https://zoom.us/j/67556028668?pwd=k1NV6aHSXvDYLT96s3yhRedsmHRIroO0","recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:24.345Z","updatedAt":"2026-11-08T20:00:24.345Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.zoomcall}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.oneonone}}_20261109T190000Z","iCalUID":"{{event.avery.oneonone}}@cal.pyas.io","title":"1:1 with Sarah","description":null,"location":null,"startsAt":"2026-11-09T19:00:00Z","endsAt":"2026-11-09T19:30:00Z","startsAtLocal":"2026-11-09T14:00:00-05:00","endsAtLocal":"2026-11-09T14:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"zoom","joinUrl":"https://zoom.us/j/9302336753","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://zoom.us/j/9302336753","recurrence":null,"series":{"masterEventId":"{{event.avery.oneonone}}","originalStartsAt":"2026-11-09T19:00:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.578Z","updatedAt":"2026-11-08T20:00:23.578Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.oneonone}}_20261109T190000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.design}}","iCalUID":"{{event.avery.design}}@cal.pyas.io","title":"Design Review","description":null,"location":"Room 4B","startsAt":"2026-11-09T20:00:00Z","endsAt":"2026-11-09T21:00:00Z","startsAtLocal":"2026-11-09T15:00:00-05:00","endsAtLocal":"2026-11-09T16:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"needsAction","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.596Z","updatedAt":"2026-11-08T20:00:23.596Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.design}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261110T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","startsAtLocal":"2026-11-10T09:30:00-05:00","endsAtLocal":"2026-11-10T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-10T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261110T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.customer}}","iCalUID":"{{event.avery.customer}}@cal.pyas.io","title":"Customer Call: Acme","description":null,"location":null,"startsAt":"2026-11-10T21:00:00Z","endsAt":"2026-11-10T21:30:00Z","startsAtLocal":"2026-11-10T16:00:00-05:00","endsAtLocal":"2026-11-10T16:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"zoom","joinUrl":"https://zoom.us/j/9148612694","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://zoom.us/j/9148612694","recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.603Z","updatedAt":"2026-11-08T20:00:23.603Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.customer}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":{"dealId":"deal_42","stage":"discovery"}},{"id":"{{event.avery.standup}}_20261111T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-11T14:30:00Z","endsAt":"2026-11-11T14:45:00Z","startsAtLocal":"2026-11-11T09:30:00-05:00","endsAtLocal":"2026-11-11T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-11T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261111T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.focus}}","iCalUID":"{{event.avery.focus}}@cal.pyas.io","title":"Focus time","description":null,"location":null,"startsAt":"2026-11-11T18:00:00Z","endsAt":"2026-11-11T20:00:00Z","startsAtLocal":"2026-11-11T13:00:00-05:00","endsAtLocal":"2026-11-11T15:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"focusTime","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.627Z","updatedAt":"2026-11-08T20:00:23.627Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.focus}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261112T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","startsAtLocal":"2026-11-12T09:30:00-05:00","endsAtLocal":"2026-11-12T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-12T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261112T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.dentist}}","iCalUID":"{{event.avery.dentist}}@cal.pyas.io","title":"Dentist","description":null,"location":null,"startsAt":"2026-11-13T13:00:00Z","endsAt":"2026-11-13T14:00:00Z","startsAtLocal":"2026-11-13T08:00:00-05:00","endsAtLocal":"2026-11-13T09:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":"private","attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.619Z","updatedAt":"2026-11-08T20:00:23.619Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.dentist}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261113T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","startsAtLocal":"2026-11-13T09:30:00-05:00","endsAtLocal":"2026-11-13T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-13T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261113T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261116T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-16T14:30:00Z","endsAt":"2026-11-16T14:45:00Z","startsAtLocal":"2026-11-16T09:30:00-05:00","endsAtLocal":"2026-11-16T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-16T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261116T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.talk}}","iCalUID":"{{event.avery.talk}}@cal.pyas.io","title":"Conference talk prep","description":null,"location":null,"startsAt":"2026-11-16T15:00:00Z","endsAt":"2026-11-16T16:30:00Z","startsAtLocal":"2026-11-16T10:00:00-05:00","endsAtLocal":"2026-11-16T11:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"tentative","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.634Z","updatedAt":"2026-11-08T20:00:23.634Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.talk}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.oneonone}}_20261116T190000Z","iCalUID":"{{event.avery.oneonone}}@cal.pyas.io","title":"1:1 with Sarah","description":null,"location":null,"startsAt":"2026-11-16T19:00:00Z","endsAt":"2026-11-16T19:30:00Z","startsAtLocal":"2026-11-16T14:00:00-05:00","endsAtLocal":"2026-11-16T14:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"zoom","joinUrl":"https://zoom.us/j/9302336753","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://zoom.us/j/9302336753","recurrence":null,"series":{"masterEventId":"{{event.avery.oneonone}}","originalStartsAt":"2026-11-16T19:00:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.578Z","updatedAt":"2026-11-08T20:00:23.578Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.oneonone}}_20261116T190000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261117T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-17T14:30:00Z","endsAt":"2026-11-17T14:45:00Z","startsAtLocal":"2026-11-17T09:30:00-05:00","endsAtLocal":"2026-11-17T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-17T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261117T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.offsite}}","iCalUID":"{{event.avery.offsite}}@cal.pyas.io","title":"Company Offsite","description":null,"location":"Lake House","startsAt":"2026-11-18T05:00:00Z","endsAt":"2026-11-20T05:00:00Z","startsAtLocal":"2026-11-18T00:00:00-05:00","endsAtLocal":"2026-11-20T00:00:00-05:00","timezone":"America/New_York","isAllDay":true,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.643Z","updatedAt":"2026-11-08T20:00:23.643Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.offsite}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261118T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-18T14:30:00Z","endsAt":"2026-11-18T14:45:00Z","startsAtLocal":"2026-11-18T09:30:00-05:00","endsAtLocal":"2026-11-18T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-18T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261118T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261119T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-19T14:30:00Z","endsAt":"2026-11-19T14:45:00Z","startsAtLocal":"2026-11-19T09:30:00-05:00","endsAtLocal":"2026-11-19T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-19T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261119T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261120T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-20T14:30:00Z","endsAt":"2026-11-20T14:45:00Z","startsAtLocal":"2026-11-20T09:30:00-05:00","endsAtLocal":"2026-11-20T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-20T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261120T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null}],"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null,"syncToken":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"`RESOURCE_SYNC_TOKEN_EXPIRED`: The sync token has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"events.create","summary":"Create an event","description":"Creates an event on a Google Calendar, Microsoft Outlook or virtual calendar. The event can include attendees, a recurrence rule, a meeting link (Google Meet, Microsoft Teams or Zoom), rooms and your own metadata. The v1 request body (`{ accountId, calendarId, eventData }`) is also accepted.\n\n**In the sandbox:** `conferencing` creates the online meeting. Use `meet` on Google, `teams` on Outlook, or `zoom` with a Zoom account on any calendar ({ \"provider\": \"zoom\", \"accountId\": \"{{account.zoom}}\" }).","tags":["Events"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["POST /google/events","POST /microsoft/events"],"notes":["The v1 request body (`{ accountId, calendarId, eventData }`) is accepted and converted to the v2 format."]},"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and doesn't create the event twice.","schema":{"type":"string"},"example":"kickoff-0001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventCreate"},"example":{"accountId":"{{account.google}}","title":"Project kickoff","startsAt":"{{in.2d.15:00}}","endsAt":"{{in.2d.16:00}}","attendees":[{"email":"sam.patel@example.org","name":"Sam Patel"}],"reminders":[{"method":"popup","minutesBefore":10}],"conferencing":{"provider":"meet","options":{"admission":"invited"}},"metadata":{"crmId":"opp_981"}}}}},"responses":{"201":{"description":"The event.","headers":{"ETag":{"description":"The event's version. Send it in the `If-Match` header of a later update to apply the update only if the event hasn't changed.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Event"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"conferencing":{"type":"object","properties":{"notApplied":{"type":"array","items":{}}},"required":["notApplied"],"additionalProperties":false},"notifyAttendees":{"type":"object","properties":{"applied":{"type":"boolean","const":false},"reason":{"type":"string"}},"required":["applied","reason"],"additionalProperties":false,"description":"Present when `notifyAttendees` was `false` but the provider emails attendees anyway (Outlook)."}},"additionalProperties":false,"description":"`conferencing.notApplied` lists the meeting settings the conferencing service didn't apply, with the reason for each. `notifyAttendees` appears when attendees were emailed although the request asked not to (Outlook)."}}},"example":{"success":true,"data":{"id":"4904j5d3fo5d3gdr94nctoas1kht4b9r","iCalUID":"4904j5d3fo5d3gdr94nctoas1kht4b9r@google.com","title":"Project kickoff","description":null,"location":null,"startsAt":"2026-11-10T15:00:00Z","endsAt":"2026-11-10T16:00:00Z","startsAtLocal":"2026-11-10T10:00:00-05:00","endsAtLocal":"2026-11-10T11:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"sam.patel@example.org","name":"Sam Patel","response":"needsAction","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.google.primary}}","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/reo-kkbh-vib","meetingId":"reo-kkbh-vib","passcode":null,"dialIn":[{"label":"+1 555-0100","number":"+1-555-0100","pin":"603577298"}],"settings":{"admission":"invited","recording":"none","transcription":false}},"meetingUrl":"https://meet.google.com/reo-kkbh-vib","recurrence":null,"series":null,"reminders":[{"method":"popup","minutesBefore":10}],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:25.552Z","updatedAt":"2026-11-08T20:00:25.552Z","version":"\"1\"","provider":"google","providerRefs":{"eventId":"4904j5d3fo5d3gdr94nctoas1kht4b9r","calendarId":"{{calendar.google.primary}}","accountId":"{{account.google}}"},"metadata":{"crmId":"opp_981"}},"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.\n\n`VALIDATION_INVALID_TIMEZONE`: The time zone is not an IANA time zone name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`VALIDATION_REJECTED_BY_PROVIDER`: The calendar provider rejected this input.\n\n`VALIDATION_IDEMPOTENCY_CONFLICT`: This idempotency key was already used with a different request.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}":{"delete":{"operationId":"events.delete","summary":"Delete an event","description":"Deletes the event and cancels it for attendees. To delete it only if it hasn't changed since you read it, send its `version` in the `If-Match` header.","tags":["Events"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["DELETE /google/events/:id","DELETE /microsoft/events/:id"],"query":{"rename":{"calendarId":"calendarRef","sendUpdates":"notifyAttendees"}},"notes":["`sendUpdates=none` maps to `notifyAttendees=false`. `all` and `externalOnly` map to `notifyAttendees=true`."]},"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.avery.board}}"},{"name":"accountId","in":"query","required":true,"description":"The `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"notifyAttendees","in":"query","required":false,"description":"Whether attendees receive a cancellation notice.","schema":{"type":"boolean"},"example":"false"},{"name":"message","in":"query","required":false,"description":"A message to include with the cancellation. Outlook only, when the account is the organizer.","schema":{"type":"string","maxLength":2000}},{"name":"sendUpdates","in":"query","required":false,"description":"The v1 name for `notifyAttendees`: `all`, `externalOnly` or `none`.","deprecated":true,"schema":{"type":"string","maxLength":32}},{"name":"calendarId","in":"query","required":false,"description":"The v1 name for `calendarRef`.","deprecated":true,"schema":{"type":"string","maxLength":1024}},{"name":"If-Match","in":"header","required":false,"description":"The event's `version` (or `ETag`). The request succeeds only if the event hasn't changed since that version. A stale version returns `RESOURCE_CONFLICT`.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"notifyAttendees":{"type":"object","properties":{"applied":{"type":"boolean","const":false},"reason":{"type":"string"}},"required":["applied","reason"],"additionalProperties":false,"description":"Present when `notifyAttendees` was `false` but the provider emails attendees anyway (Outlook)."}},"additionalProperties":false}}},"example":{"success":true,"data":null,"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"events.get","summary":"Get an event","tags":["Events"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /google/events/:id","GET /microsoft/events/:id"],"query":{"rename":{"calendarId":"calendarRef"},"refuse":{"$expand":"read extended properties with include=extendedProperties and extendedPropertyIds, or the provider's whole event with include=raw."}}},"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.avery.zoomcall}}"},{"name":"accountId","in":"query","required":true,"description":"The `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"include","in":"query","required":false,"description":"Additional fields to include, as a comma-separated list. `raw` is the provider's original payload. `extendedProperties` is the provider's extended properties. `conferencingSettings` is available only when you retrieve one event.","schema":{"type":"string","maxLength":64}},{"name":"extendedPropertyIds","in":"query","required":false,"description":"Outlook only, with `include=extendedProperties`. The IDs of up to 10 extended properties to read, of any type, such as `String {guid} Name orderId`, `IntegerArray {guid} Name counts` or `Integer 0x8012`.","schema":{"type":"string","maxLength":2048}},{"name":"fields","in":"query","required":false,"description":"The top-level fields to return, comma-separated, such as `id,title,startsAt,endsAt`. The `id` field is always included.","schema":{"type":"string","maxLength":1024}}],"responses":{"200":{"description":"The event.","headers":{"ETag":{"description":"The event's version. Send it in the `If-Match` header of a later update to apply the update only if the event hasn't changed.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Event"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{event.avery.zoomcall}}","iCalUID":"{{event.avery.zoomcall}}@cal.pyas.io","title":"Customer onboarding (Zoom)","description":null,"location":null,"startsAt":"2026-11-09T16:00:00Z","endsAt":"2026-11-09T17:00:00Z","startsAtLocal":"2026-11-09T11:00:00-05:00","endsAtLocal":"2026-11-09T12:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"zoom","joinUrl":"https://zoom.us/j/67556028668?pwd=k1NV6aHSXvDYLT96s3yhRedsmHRIroO0","meetingId":"67556028668","passcode":"1wWGDz58DC","dialIn":[{"label":"US New York","number":"+1 555 0100","pin":"604224"}]},"meetingUrl":"https://zoom.us/j/67556028668?pwd=k1NV6aHSXvDYLT96s3yhRedsmHRIroO0","recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:24.345Z","updatedAt":"2026-11-08T20:00:24.345Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.zoomcall}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"events.update","summary":"Update an event","description":"Updates the event. Send only the fields to update. Setting a nullable field to `null` clears it. To update the event only if it hasn't changed since you read it, send its `version` in the `If-Match` header. The v1 request body is also accepted.","tags":["Events"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["PATCH /google/events/:id","PATCH /microsoft/events/:id"],"notes":["The v1 request body (`{ accountId, calendarId, eventData }`) is accepted and converted to the v2 format."]},"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.avery.productsync}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"If-Match","in":"header","required":false,"description":"The event's `version` (or `ETag`). The request succeeds only if the event hasn't changed since that version. A stale version returns `RESOURCE_CONFLICT`.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventPatch"},"example":{"title":"Product Sync (moved)","startsAt":"{{in.1d.17:00}}","endsAt":"{{in.1d.18:00}}"}}}},"responses":{"200":{"description":"The event.","headers":{"ETag":{"description":"The event's version. Send it in the `If-Match` header of a later update to apply the update only if the event hasn't changed.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Event"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"conferencing":{"type":"object","properties":{"notApplied":{"type":"array","items":{}}},"required":["notApplied"],"additionalProperties":false},"notifyAttendees":{"type":"object","properties":{"applied":{"type":"boolean","const":false},"reason":{"type":"string"}},"required":["applied","reason"],"additionalProperties":false,"description":"Present when `notifyAttendees` was `false` but the provider emails attendees anyway (Outlook)."}},"additionalProperties":false,"description":"`conferencing.notApplied` lists the meeting settings the conferencing service didn't apply, with the reason for each. `notifyAttendees` appears when attendees were emailed although the request asked not to (Outlook)."}}},"example":{"success":true,"data":{"id":"{{event.avery.productsync}}","iCalUID":"{{event.avery.productsync}}@cal.pyas.io","title":"Product Sync (moved)","description":null,"location":null,"startsAt":"2026-11-09T17:00:00Z","endsAt":"2026-11-09T18:00:00Z","startsAtLocal":"2026-11-09T12:00:00-05:00","endsAtLocal":"2026-11-09T13:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:24.751Z","updatedAt":"2026-11-08T20:00:25.757Z","version":"\"2\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.productsync}}","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":{"project":"atlas"}},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.\n\n`VALIDATION_INVALID_TIMEZONE`: The time zone is not an IANA time zone name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`VALIDATION_REJECTED_BY_PROVIDER`: The calendar provider rejected this input.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/attachments":{"get":{"operationId":"events.attachments.list","summary":"List an event's attachments","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.avery.design}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}}],"responses":{"200":{"description":"The files and links attached to the event.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[],"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"events.attachments.addLink","summary":"Attach a link","description":"Attaches a link to a file stored elsewhere. Google Calendar accepts links to Google Drive files. Outlook calendars do not support link attachments, so upload the file with `/attachments/file` instead.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.avery.design}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"url":{"type":"string","description":"The `https` URL of the file."},"name":{"type":"string","maxLength":255},"mimeType":{"type":"string","maxLength":255}},"required":["url"],"additionalProperties":false},"example":{"url":"https://example.com/agenda.pdf","name":"Agenda.pdf","mimeType":"application/pdf"}}}},"responses":{"201":{"description":"The attachment.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Attachment"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"att3j6jb64bbls3hsvo51vg","name":"Agenda.pdf","mimeType":"application/pdf","size":null,"url":"https://example.com/agenda.pdf","kind":"link"},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/attachments/{attachmentId}":{"delete":{"operationId":"events.attachments.delete","summary":"Delete an attachment","description":"**In the sandbox:** Use an ID from `GET /v2/events/{eventId}/attachments`. Deleting an attachment that no longer exists also returns `200`, on every provider.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.google.kickoff}}"},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":2048},"example":"{{attachment.google.agenda}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/attachments/{attachmentId}/content":{"get":{"operationId":"events.attachments.content","summary":"Download an attachment","description":"Returns the file contents of an Outlook attachment. For Google Drive files and links, responds with `303 See Other` and the file's location.\n\n**In the sandbox:** A file on an Outlook event is returned as its bytes. A link or a Google Drive file is returned as a redirect to its location.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.outlook.review}}"},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":2048},"example":"{{attachment.outlook.agenda}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}}],"responses":{"200":{"description":"The file contents.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"303":{"description":"A redirect to the file's location."},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/attachments/file":{"post":{"operationId":"events.attachments.upload","summary":"Upload a file to an event","description":"Uploads a file and attaches it to the event. Send the file as the request body with its own `Content-Type`. Send JSON files as `application/octet-stream` with `?contentType=`. With a `Content-Length` header, the file is streamed to the provider. On Google Calendar, the file is stored in Google Drive. Files can be up to 25 MB. The account status shows the limit in `capabilities.maxAttachmentBytes`. For a larger file, attach a link instead.\n\n**In the sandbox:** Outlook stores the file on the event. Google uploads it to the person's Google Drive and attaches it. The sandbox stores files up to 4 MB.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.outlook.review}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"name","in":"query","required":true,"description":"The file name.","schema":{"type":"string","minLength":1,"maxLength":255},"example":"notes.txt"},{"name":"contentType","in":"query","required":false,"description":"The file's media type, when the request's own `Content-Type` can't specify it.","schema":{"type":"string","maxLength":255}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"The raw file contents.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"The attachment.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Attachment"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"AAMkAdMhPAQjkB4bvKK-QcQsbZhkMIgklLZqpoVA-IeLqlhIAAA=","name":"notes.txt","mimeType":"application/octet-stream","size":28,"url":null,"kind":"file"},"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.\n\n`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"`VALIDATION_PAYLOAD_TOO_LARGE`: The request body exceeds the size limit for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/forward":{"post":{"operationId":"events.forward","summary":"Forward an invitation","description":"**In the sandbox:** On Google, forwarding invites the recipients, so they are added to the attendees. On Outlook, the event is emailed to the recipients, with your comment if you include one.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.google.kickoff}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"recipients":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}},"required":["email"],"additionalProperties":false}},"comment":{"description":"A message to include with the forwarded invitation. Outlook only.","type":"string"}},"required":["recipients"],"additionalProperties":false},"example":{"recipients":[{"email":"colleague@example.com"}]}}}},"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/instances":{"get":{"operationId":"events.instances","summary":"List occurrences of a recurring event","description":"Returns each occurrence of a recurring event within a time window as a separate event, with `series` set.","tags":["Events"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /google/events/:id/instances","GET /microsoft/events/:id/instances"],"query":{"rename":{"calendarId":"calendarRef","startDate":"from","endDate":"to","timeMin":"from","timeMax":"to"},"times":["from","to"]}},"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.avery.standup}}"},{"name":"accountId","in":"query","required":true,"description":"The `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"from","in":"query","required":false,"description":"The start of the time window. Required.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"},"example":"{{in.0d}}"},{"name":"to","in":"query","required":false,"description":"The end of the time window. Required.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"},"example":"{{in.7d}}"},{"name":"limit","in":"query","required":false,"description":"The maximum number of results in one page. Defaults to 100.","schema":{"type":"integer","minimum":1,"maximum":250}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","maxLength":4096}},{"name":"include","in":"query","required":false,"description":"Additional fields to include, as a comma-separated list. `raw` is the provider's original payload. `extendedProperties` is the provider's extended properties. `conferencingSettings` is available only when you retrieve one event.","schema":{"type":"string","maxLength":64}},{"name":"extendedPropertyIds","in":"query","required":false,"schema":{"type":"string","maxLength":2048}},{"name":"fields","in":"query","required":false,"description":"The top-level fields to return, comma-separated, such as `id,title,startsAt,endsAt`. The `id` field is always included.","schema":{"type":"string","maxLength":1024}}],"responses":{"200":{"description":"A page of occurrences.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"description":"Pass it as `cursor` to get the next page. `null` on the last page.","type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[{"id":"{{event.avery.standup}}_20261109T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-09T14:30:00Z","endsAt":"2026-11-09T14:45:00Z","startsAtLocal":"2026-11-09T09:30:00-05:00","endsAtLocal":"2026-11-09T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-09T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261109T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261110T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","startsAtLocal":"2026-11-10T09:30:00-05:00","endsAtLocal":"2026-11-10T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-10T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261110T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261111T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-11T14:30:00Z","endsAt":"2026-11-11T14:45:00Z","startsAtLocal":"2026-11-11T09:30:00-05:00","endsAtLocal":"2026-11-11T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-11T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261111T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261112T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","startsAtLocal":"2026-11-12T09:30:00-05:00","endsAtLocal":"2026-11-12T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-12T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261112T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},{"id":"{{event.avery.standup}}_20261113T143000Z","iCalUID":"{{event.avery.standup}}@cal.pyas.io","title":"Daily Standup","description":null,"location":null,"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","startsAtLocal":"2026-11-13T09:30:00-05:00","endsAtLocal":"2026-11-13T09:45:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"teammate1.1@example.com","name":"Morgan","response":"accepted","optional":false,"isOrganizer":false},{"email":"teammate2.1@example.com","name":"Casey","response":"tentative","optional":false,"isOrganizer":false},{"email":"teammate3.1@example.com","name":"Drew","response":"declined","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/sbx-4978-a3b1","meetingId":null,"passcode":null,"dialIn":[]},"meetingUrl":"https://meet.google.com/sbx-4978-a3b1","recurrence":null,"series":{"masterEventId":"{{event.avery.standup}}","originalStartsAt":"2026-11-13T14:30:00Z","isException":false},"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:23.554Z","updatedAt":"2026-11-08T20:00:23.554Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.standup}}_20261113T143000Z","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null}],"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/move":{"post":{"operationId":"events.move","summary":"Move an event to another calendar","description":"Moves an event to another calendar. Outlook has no move operation, so on Outlook the event is recreated with a new ID, and the response includes `meta.recreated` and `meta.previousId`. To move an Outlook event that has attendees, send `recreate: true`.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.avery.lunch}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"destinationCalendarRef":{"type":"string"},"notifyAttendees":{"type":"boolean"},"recreate":{"description":"Outlook only. Confirms that the event can be recreated. Attendees receive a cancellation and a new invitation.","type":"boolean"}},"required":["destinationCalendarRef"],"additionalProperties":false},"example":{"destinationCalendarRef":"{{calendar.avery.work}}"}}}},"responses":{"200":{"description":"The event in its new calendar.","headers":{"ETag":{"description":"The event's version. Send it in the `If-Match` header of a later update to apply the update only if the event hasn't changed.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Event"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"recreated":{"type":"boolean"},"previousId":{"type":"string"},"notifyAttendees":{"type":"object","properties":{"applied":{"type":"boolean","const":false},"reason":{"type":"string"}},"required":["applied","reason"],"additionalProperties":false,"description":"Present when `notifyAttendees` was `false` but the provider emails attendees anyway (Outlook)."}},"required":["recreated"],"additionalProperties":false}}},"example":{"success":true,"data":{"id":"{{event.avery.lunch}}","iCalUID":"{{event.avery.lunch}}@cal.pyas.io","title":"Lunch with Alex","description":null,"location":"Corner Cafe","startsAt":"2026-11-08T17:30:00Z","endsAt":"2026-11-08T18:30:00Z","startsAtLocal":"2026-11-08T12:30:00-05:00","endsAtLocal":"2026-11-08T13:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"free","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:24.771Z","updatedAt":"2026-11-08T20:00:25.616Z","version":"\"2\"","provider":"pyas","providerRefs":{"eventId":"{{event.avery.lunch}}","calendarId":"{{calendar.avery.work}}","accountId":"{{account.avery}}"},"metadata":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"recreated":false}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/reminder/dismiss":{"post":{"operationId":"events.reminder.dismiss","summary":"Dismiss a reminder","description":"Dismisses the event's reminder. Outlook only.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.outlook.review}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"}},"additionalProperties":false},"example":{}}}},"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/reminder/snooze":{"post":{"operationId":"events.reminder.snooze","summary":"Snooze a reminder","description":"Shows the reminder again at a later time. Outlook only.\n\n**In the sandbox:** Reminder state is available only on Outlook. For Google accounts, the API returns an error, because Google's API doesn't store reminder state.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.outlook.review}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"until":{"type":"string","description":"When to show the reminder again, as a future ISO 8601 time with a zone.","format":"date-time"}},"required":["until"],"additionalProperties":false},"example":{"until":"{{in.1d.09:55}}"}}}},"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/{eventId}/respond":{"post":{"operationId":"events.respond","summary":"Respond to an invitation","description":"Sets this account's response to an invitation: `accepted`, `declined` or `tentative`. You can include a comment and, on Outlook, propose a different time.\n\n**In the sandbox:** Outlook accepts a proposed time with `tentative` or `declined`. On Google, the response is recorded without a proposed time. The organizer can't respond to their own event.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"The ID of the event.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{event.outlook.invite}}"},{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.outlook}}"},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"response":{"type":"string","enum":["accepted","declined","tentative"]},"comment":{"type":"string"},"proposedTime":{"description":"A different time to propose. Outlook only, with `declined` or `tentative`.","type":"object","properties":{"startsAt":{"type":"string"},"endsAt":{"type":"string"}},"required":["startsAt","endsAt"],"additionalProperties":false},"notifyOrganizer":{"description":"Whether to notify the organizer. Defaults to `true`.","type":"boolean"}},"required":["response"],"additionalProperties":false},"example":{"response":"tentative","comment":"Could we do later in the day?","proposedTime":{"startsAt":"{{in.2d.16:00}}","endsAt":"{{in.2d.17:00}}"}}}}},"responses":{"200":{"description":"The event.","headers":{"ETag":{"description":"The event's version. Send it in the `If-Match` header of a later update to apply the update only if the event hasn't changed.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Event"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{event.outlook.invite}}","iCalUID":"040000008200E00074C5B7101A82E008692EB216F94CCB328CF8D509CF2E22779026B52F5F94CC7ACE760D0B","title":"Vendor demo","description":null,"location":null,"startsAt":"2026-11-10T15:00:00Z","endsAt":"2026-11-10T16:00:00Z","startsAtLocal":"2026-11-10T15:00:00+00:00","endsAtLocal":"2026-11-10T16:00:00+00:00","timezone":"Europe/London","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"sam.patel@example.org","name":"Sam Patel","response":"tentative","optional":false,"isOrganizer":false},{"email":"jordan.lee@example.org","name":"Jordan Lee","response":"tentative","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"riley.chen@example.org","name":"Riley Chen"},"conferencing":{"provider":"teams","joinUrl":"https://teams.microsoft.com/l/meetup-join/19%3ameeting_9PnbW93DKzErExDGHH4VYkdBB4uPoz6z%40thread.v2/0","meetingId":"354 292 634 861","passcode":"RMXPxx","dialIn":[{"label":"Toll","number":"+1 555-0101","pin":"769655823"}]},"meetingUrl":"https://teams.microsoft.com/l/meetup-join/19%3ameeting_9PnbW93DKzErExDGHH4VYkdBB4uPoz6z%40thread.v2/0","recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":true,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:25.447Z","updatedAt":"2026-11-08T20:00:25.604Z","version":"\"2\"","provider":"microsoft","providerRefs":{"eventId":"{{event.outlook.invite}}","calendarId":"{{calendar.outlook.primary}}","accountId":"{{account.outlook}}"},"metadata":null},"provider":"microsoft","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.\n\n`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/import":{"post":{"operationId":"events.import","summary":"Import an event","description":"Imports an event from another calendar system and keeps its iCalendar UID, organizer and sequence number. Available only on Google Calendar.","tags":["Events"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and doesn't create the event twice.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","description":"The `accountId` of the connected account. You can send it here or in the query."},"calendarRef":{"type":"string","description":"The calendar to use. Defaults to `primary`. You can send it here or in the query."},"title":{"type":"string","maxLength":1024},"description":{"type":"string","maxLength":65536},"location":{"type":"string","maxLength":1024},"startsAt":{"type":"string","description":"An ISO 8601 time with a zone, or a date such as `2026-03-15` for an all-day event.","examples":["2026-03-15T14:00:00Z"]},"endsAt":{"type":"string","description":"The end of the event. Must be later than `startsAt`.","examples":["2026-03-15T15:00:00Z"]},"timezone":{"type":"string","description":"The IANA time zone of the event. Defaults to the calendar's time zone."},"isAllDay":{"type":"boolean"},"attendees":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"},"optional":{"type":"boolean"}},"required":["email"],"additionalProperties":false}},"rooms":{"maxItems":20,"type":"array","items":{"type":"string"},"description":"The email addresses of the rooms to book (see `GET /v2/rooms`). On an update, send the complete list."},"recurrence":{"type":"string","description":"An RFC 5545 RRULE, such as `FREQ=WEEKLY;BYDAY=MO`.","examples":["FREQ=WEEKLY;BYDAY=MO,WE"]},"reminders":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"method":{"type":"string","enum":["popup","email"]},"minutesBefore":{"type":"integer","minimum":0,"maximum":40320}},"required":["method","minutesBefore"],"additionalProperties":false}},"visibility":{"type":"string","enum":["default","public","private","confidential"]},"notifyAttendees":{"type":"boolean","description":"Whether the provider emails attendees about this change. Outlook always emails them: there, `false` isn't applied, and the response's `meta.notifyAttendees` says so."},"metadata":{"$ref":"#/components/schemas/Metadata"},"showAs":{"type":"string","enum":["busy","free","tentative","outOfOffice","workingElsewhere"]},"color":{"type":"string","description":"The color, as `#rrggbb`. The provider uses the closest color it offers."},"guests":{"type":"object","properties":{"canModify":{"type":"boolean"},"canInviteOthers":{"type":"boolean"},"canSeeGuests":{"type":"boolean"},"canProposeTimes":{"type":"boolean"}},"additionalProperties":false},"importance":{"type":"string","enum":["low","normal","high"]},"categories":{"maxItems":25,"type":"array","items":{"type":"string"}},"responseRequested":{"type":"boolean"},"autoDecline":{"type":"object","properties":{"mode":{"type":"string","enum":["none","all","new"]},"message":{"type":["string","null"]}},"additionalProperties":false},"doNotDisturb":{"type":"boolean"},"workingLocation":{"$ref":"#/components/schemas/WorkingLocation"},"source":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"}},"required":["url"],"additionalProperties":false},"endTimeUnspecified":{"type":"boolean"},"privateCopy":{"type":"boolean"},"status":{"type":"string","enum":["confirmed","tentative"],"description":"To cancel an event, send a `DELETE` request instead."},"providerOptions":{"$ref":"#/components/schemas/ProviderOptions"},"eventType":{"description":"Can be set only when creating an event, because providers don't allow it to be updated.","type":"string","enum":["default","focusTime","outOfOffice","workingLocation","birthday"]},"id":{"description":"Google Calendar only. Your own event ID, 5 to 1024 characters from a-v and 0-9.","type":"string"},"birthday":{"type":"object","properties":{"type":{"type":"string","enum":["birthday","anniversary","custom","other","self"]}},"required":["type"],"additionalProperties":false},"iCalUID":{"type":"string","description":"The event's iCalendar UID, which the imported event keeps."},"organizer":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}},"required":["email"],"additionalProperties":false},"sequence":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["title","startsAt","endsAt","iCalUID"],"additionalProperties":false},"example":{"accountId":"{{account.avery}}","iCalUID":"planning-2026@other-calendar.example","title":"Planning (imported)","startsAt":"{{in.3d.10:00}}","endsAt":"{{in.3d.11:00}}"}}}},"responses":{"201":{"description":"The event.","headers":{"ETag":{"description":"The event's version. Send it in the `If-Match` header of a later update to apply the update only if the event hasn't changed.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Event"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"evt2cece5c6brq8a1b6k3ge","iCalUID":"planning-2026@other-calendar.example","title":"Planning (imported)","description":null,"location":null,"startsAt":"2026-11-11T10:00:00Z","endsAt":"2026-11-11T11:00:00Z","startsAtLocal":"2026-11-11T05:00:00-05:00","endsAtLocal":"2026-11-11T06:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:25.565Z","updatedAt":"2026-11-08T20:00:25.565Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"evt2cece5c6brq8a1b6k3ge","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/events/quick":{"post":{"operationId":"events.quickAdd","summary":"Create an event from text","description":"Creates an event from a short text description, such as \"Lunch with Sam Friday 1pm\". The API interprets the text the same way on every provider. With `dryRun`, the API returns how it interpreted the text without creating the event.","tags":["Events"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":201},"parameters":[{"name":"accountId","in":"query","required":false,"description":"The `accountId` of the connected account. Required here or in the request body of a write.","schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"calendarRef","in":"query","required":false,"description":"The calendar to use. Defaults to `primary`.","schema":{"type":"string","maxLength":1024}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and doesn't create the event twice.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"text":{"type":"string","maxLength":1024,"examples":["Lunch with Sam Friday 1pm"]},"timezone":{"description":"The IANA time zone used to interpret the text. Defaults to the calendar's time zone.","type":"string"},"durationMinutes":{"description":"The length of the event in minutes when the text doesn't include an end time. Defaults to 60.","type":"integer","minimum":1,"maximum":1440},"dryRun":{"type":"boolean"}},"required":["text"],"additionalProperties":false},"example":{"accountId":"{{account.avery}}","text":"Lunch with Sam Friday 1pm","timezone":"America/New_York"}}}},"responses":{"200":{"description":"With `dryRun`, how the text was interpreted. No event is created.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"parsed":{"type":"object","properties":{"title":{"type":"string"},"startsAt":{"type":"string"},"endsAt":{"type":"string"},"isAllDay":{"type":"boolean"},"timezone":{"type":"string"},"matched":{"type":"string","description":"The part of the text that was interpreted as the date or time."}},"required":["title","startsAt","endsAt","isAllDay","timezone","matched"],"additionalProperties":false}},"required":["parsed"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}}}}},"201":{"description":"The event. `meta.parsed` describes how the text was interpreted.","headers":{"ETag":{"description":"The event's version. Send it in the `If-Match` header of a later update to apply the update only if the event hasn't changed.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Event"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"parsed":{"type":"object","properties":{"title":{"type":"string"},"startsAt":{"type":"string"},"endsAt":{"type":"string"},"isAllDay":{"type":"boolean"},"timezone":{"type":"string"},"matched":{"type":"string","description":"The part of the text that was interpreted as the date or time."}},"required":["title","startsAt","endsAt","isAllDay","timezone","matched"],"additionalProperties":false}},"required":["parsed"],"additionalProperties":false}}},"example":{"success":true,"data":{"id":"evt0khtemav23djrva990ln","iCalUID":"evt0khtemav23djrva990ln@cal.pyas.io","title":"Lunch with Sam","description":null,"location":null,"startsAt":"2026-11-13T18:00:00Z","endsAt":"2026-11-13T19:00:00Z","startsAtLocal":"2026-11-13T13:00:00-05:00","endsAtLocal":"2026-11-13T14:00:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[],"rooms":[],"organizer":{"email":"{{calendar.avery.primary}}@cal.pyas.io","name":"Avery Brooks"},"conferencing":null,"meetingUrl":null,"recurrence":null,"series":null,"reminders":[],"attachments":[],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:25.590Z","updatedAt":"2026-11-08T20:00:25.590Z","version":"\"1\"","provider":"pyas","providerRefs":{"eventId":"evt0khtemav23djrva990ln","calendarId":"{{calendar.avery.primary}}","accountId":"{{account.avery}}"},"metadata":null},"provider":"pyas","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"parsed":{"title":"Lunch with Sam","startsAt":"2026-11-13T18:00:00Z","endsAt":"2026-11-13T19:00:00Z","isAllDay":false,"timezone":"America/New_York","matched":"Friday 1pm"}}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.\n\n`VALIDATION_INVALID_TIMEZONE`: The time zone is not an IANA time zone name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_TOKEN_EXPIRED`: The provider's access token expired and could not be refreshed.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"`PROVIDER_TIMEOUT`: The calendar provider did not respond in time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/free-busy":{"get":{"operationId":"freeBusy.get","summary":"Get free/busy for one account","description":"Returns the same response as `POST /v2/free-busy`, for one account. The v1 parameter names still work, and responses to requests that use them include a `Pyas-Deprecated-Fields` header.","tags":["Availability"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /google/freebusy","GET /microsoft/freebusy"],"query":{"rename":{"calendarIds":"calendarRefs","timeMin":"from","timeMax":"to"},"times":["from","to"]}},"parameters":[{"name":"accountId","in":"query","required":true,"description":"The `accountId` of the connected account.","schema":{"type":"string","maxLength":128},"example":"{{account.avery}}"},{"name":"calendarRefs","in":"query","required":false,"description":"The calendars to read, comma-separated. Defaults to `primary`.","schema":{"type":"string","maxLength":20480}},{"name":"from","in":"query","required":false,"description":"The start of the time window, as an ISO 8601 time with a zone.","schema":{"type":"string","maxLength":64},"example":"{{in.0d}}"},{"name":"to","in":"query","required":false,"description":"The end of the time window, at most 92 days after `from`.","schema":{"type":"string","maxLength":64},"example":"{{in.7d}}"},{"name":"calendarIds","in":"query","required":false,"description":"The v1 name for `calendarRefs`.","deprecated":true,"schema":{"type":"string","maxLength":20480}},{"name":"timeMin","in":"query","required":false,"description":"The v1 name for `from`.","deprecated":true,"schema":{"type":"string","maxLength":64}},{"name":"timeMax","in":"query","required":false,"description":"The v1 name for `to`.","deprecated":true,"schema":{"type":"string","maxLength":64}}],"responses":{"200":{"description":"Busy times for each calendar and each account, and merged across all of them.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/FreeBusy"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"partial":{"type":"boolean","description":"`true` when an account or calendar couldn't be read."}},"required":["from","to","partial"],"additionalProperties":false}}},"example":{"success":true,"data":{"busy":[{"startsAt":"2026-11-08T15:00:00Z","endsAt":"2026-11-08T16:00:00Z","status":"busy"},{"startsAt":"2026-11-09T14:30:00Z","endsAt":"2026-11-09T14:45:00Z","status":"busy"},{"startsAt":"2026-11-09T16:00:00Z","endsAt":"2026-11-09T17:00:00Z","status":"busy"},{"startsAt":"2026-11-09T19:00:00Z","endsAt":"2026-11-09T19:30:00Z","status":"busy"},{"startsAt":"2026-11-09T20:00:00Z","endsAt":"2026-11-09T21:00:00Z","status":"busy"},{"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","status":"busy"},{"startsAt":"2026-11-10T21:00:00Z","endsAt":"2026-11-10T21:30:00Z","status":"busy"},{"startsAt":"2026-11-11T14:30:00Z","endsAt":"2026-11-11T14:45:00Z","status":"busy"},{"startsAt":"2026-11-11T18:00:00Z","endsAt":"2026-11-11T20:00:00Z","status":"busy"},{"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T13:00:00Z","endsAt":"2026-11-13T14:00:00Z","status":"busy"},{"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","status":"busy"}],"accounts":[{"accountId":"{{account.avery}}","provider":"pyas","busy":[{"startsAt":"2026-11-08T15:00:00Z","endsAt":"2026-11-08T16:00:00Z","status":"busy"},{"startsAt":"2026-11-09T14:30:00Z","endsAt":"2026-11-09T14:45:00Z","status":"busy"},{"startsAt":"2026-11-09T16:00:00Z","endsAt":"2026-11-09T17:00:00Z","status":"busy"},{"startsAt":"2026-11-09T19:00:00Z","endsAt":"2026-11-09T19:30:00Z","status":"busy"},{"startsAt":"2026-11-09T20:00:00Z","endsAt":"2026-11-09T21:00:00Z","status":"busy"},{"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","status":"busy"},{"startsAt":"2026-11-10T21:00:00Z","endsAt":"2026-11-10T21:30:00Z","status":"busy"},{"startsAt":"2026-11-11T14:30:00Z","endsAt":"2026-11-11T14:45:00Z","status":"busy"},{"startsAt":"2026-11-11T18:00:00Z","endsAt":"2026-11-11T20:00:00Z","status":"busy"},{"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T13:00:00Z","endsAt":"2026-11-13T14:00:00Z","status":"busy"},{"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","status":"busy"}],"calendars":{"primary":[{"startsAt":"2026-11-08T15:00:00Z","endsAt":"2026-11-08T16:00:00Z","status":"busy"},{"startsAt":"2026-11-09T14:30:00Z","endsAt":"2026-11-09T14:45:00Z","status":"busy"},{"startsAt":"2026-11-09T16:00:00Z","endsAt":"2026-11-09T17:00:00Z","status":"busy"},{"startsAt":"2026-11-09T19:00:00Z","endsAt":"2026-11-09T19:30:00Z","status":"busy"},{"startsAt":"2026-11-09T20:00:00Z","endsAt":"2026-11-09T21:00:00Z","status":"busy"},{"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","status":"busy"},{"startsAt":"2026-11-10T21:00:00Z","endsAt":"2026-11-10T21:30:00Z","status":"busy"},{"startsAt":"2026-11-11T14:30:00Z","endsAt":"2026-11-11T14:45:00Z","status":"busy"},{"startsAt":"2026-11-11T18:00:00Z","endsAt":"2026-11-11T20:00:00Z","status":"busy"},{"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T13:00:00Z","endsAt":"2026-11-13T14:00:00Z","status":"busy"},{"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","status":"busy"}]}}]},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"from":"2026-11-08T00:00:00Z","to":"2026-11-15T00:00:00Z","partial":false}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"freeBusy.query","summary":"Get free/busy for several accounts","description":"Returns when each account is busy on the requested calendars, merged per account and across all accounts, so you can find when anyone is busy in one request. If one account fails, the error is reported on that account and `meta.partial` is `true`.","tags":["Availability"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /google/freebusy","GET /microsoft/freebusy"],"notes":["Accepts several accounts in one request. For one account with the v1 query parameter names, use `GET /v2/free-busy`."]},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountIds":{"description":"Up to 20 account IDs. Each account is read on the calendars in `calendarRefs`. Send exactly one of `accountIds`, `subjectId` or `accounts`.","type":"array","items":{"type":"string"}},"subjectId":{"description":"Selects every Google Calendar, Outlook or virtual calendar account labeled with this `subjectId`.","type":"string"},"accounts":{"description":"Accounts, each with its own list of calendars.","type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRefs":{"type":"array","items":{"type":"string"},"description":"Up to 20 calendars to read, as `calendarRef` values. Defaults to `primary`."}},"required":["accountId"],"additionalProperties":false}},"calendarRefs":{"type":"array","items":{"type":"string"},"description":"Up to 20 calendars to read, as `calendarRef` values. Defaults to `primary`."},"from":{"type":"string","description":"The start of the time window, as an ISO 8601 time with a zone.","format":"date-time"},"to":{"type":"string","description":"The end of the time window, at most 92 days after `from`.","format":"date-time"}},"required":["from","to"],"additionalProperties":false},"example":{"accountIds":["{{account.avery}}","{{account.sam}}"],"from":"{{in.0d}}","to":"{{in.7d}}"}}}},"responses":{"200":{"description":"Busy times for each calendar and each account, and merged across all of them.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/FreeBusy"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"partial":{"type":"boolean","description":"`true` when an account or calendar couldn't be read."}},"required":["from","to","partial"],"additionalProperties":false}}},"example":{"success":true,"data":{"busy":[{"startsAt":"2026-11-08T10:00:00Z","endsAt":"2026-11-08T11:00:00Z","status":"busy"},{"startsAt":"2026-11-08T15:00:00Z","endsAt":"2026-11-08T16:00:00Z","status":"busy"},{"startsAt":"2026-11-09T09:30:00Z","endsAt":"2026-11-09T09:45:00Z","status":"busy"},{"startsAt":"2026-11-09T14:00:00Z","endsAt":"2026-11-09T14:45:00Z","status":"busy"},{"startsAt":"2026-11-09T15:00:00Z","endsAt":"2026-11-09T17:00:00Z","status":"busy"},{"startsAt":"2026-11-09T19:00:00Z","endsAt":"2026-11-09T19:30:00Z","status":"busy"},{"startsAt":"2026-11-09T20:00:00Z","endsAt":"2026-11-09T21:00:00Z","status":"busy"},{"startsAt":"2026-11-10T09:30:00Z","endsAt":"2026-11-10T09:45:00Z","status":"busy"},{"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","status":"busy"},{"startsAt":"2026-11-10T16:00:00Z","endsAt":"2026-11-10T16:30:00Z","status":"busy"},{"startsAt":"2026-11-10T21:00:00Z","endsAt":"2026-11-10T21:30:00Z","status":"busy"},{"startsAt":"2026-11-11T09:30:00Z","endsAt":"2026-11-11T09:45:00Z","status":"busy"},{"startsAt":"2026-11-11T10:00:00Z","endsAt":"2026-11-11T11:00:00Z","status":"busy"},{"startsAt":"2026-11-11T13:00:00Z","endsAt":"2026-11-11T15:00:00Z","status":"busy"},{"startsAt":"2026-11-11T18:00:00Z","endsAt":"2026-11-11T20:00:00Z","status":"busy"},{"startsAt":"2026-11-12T09:30:00Z","endsAt":"2026-11-12T09:45:00Z","status":"busy"},{"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T08:00:00Z","endsAt":"2026-11-13T09:00:00Z","status":"busy"},{"startsAt":"2026-11-13T09:30:00Z","endsAt":"2026-11-13T09:45:00Z","status":"busy"},{"startsAt":"2026-11-13T13:00:00Z","endsAt":"2026-11-13T14:00:00Z","status":"busy"},{"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T18:00:00Z","endsAt":"2026-11-13T19:00:00Z","status":"busy"}],"accounts":[{"accountId":"{{account.avery}}","provider":"pyas","busy":[{"startsAt":"2026-11-08T15:00:00Z","endsAt":"2026-11-08T16:00:00Z","status":"busy"},{"startsAt":"2026-11-09T14:30:00Z","endsAt":"2026-11-09T14:45:00Z","status":"busy"},{"startsAt":"2026-11-09T16:00:00Z","endsAt":"2026-11-09T17:00:00Z","status":"busy"},{"startsAt":"2026-11-09T19:00:00Z","endsAt":"2026-11-09T19:30:00Z","status":"busy"},{"startsAt":"2026-11-09T20:00:00Z","endsAt":"2026-11-09T21:00:00Z","status":"busy"},{"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","status":"busy"},{"startsAt":"2026-11-10T21:00:00Z","endsAt":"2026-11-10T21:30:00Z","status":"busy"},{"startsAt":"2026-11-11T10:00:00Z","endsAt":"2026-11-11T11:00:00Z","status":"busy"},{"startsAt":"2026-11-11T14:30:00Z","endsAt":"2026-11-11T14:45:00Z","status":"busy"},{"startsAt":"2026-11-11T18:00:00Z","endsAt":"2026-11-11T20:00:00Z","status":"busy"},{"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T13:00:00Z","endsAt":"2026-11-13T14:00:00Z","status":"busy"},{"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T18:00:00Z","endsAt":"2026-11-13T19:00:00Z","status":"busy"}],"calendars":{"primary":[{"startsAt":"2026-11-08T15:00:00Z","endsAt":"2026-11-08T16:00:00Z","status":"busy"},{"startsAt":"2026-11-09T14:30:00Z","endsAt":"2026-11-09T14:45:00Z","status":"busy"},{"startsAt":"2026-11-09T16:00:00Z","endsAt":"2026-11-09T17:00:00Z","status":"busy"},{"startsAt":"2026-11-09T19:00:00Z","endsAt":"2026-11-09T19:30:00Z","status":"busy"},{"startsAt":"2026-11-09T20:00:00Z","endsAt":"2026-11-09T21:00:00Z","status":"busy"},{"startsAt":"2026-11-10T14:30:00Z","endsAt":"2026-11-10T14:45:00Z","status":"busy"},{"startsAt":"2026-11-10T21:00:00Z","endsAt":"2026-11-10T21:30:00Z","status":"busy"},{"startsAt":"2026-11-11T10:00:00Z","endsAt":"2026-11-11T11:00:00Z","status":"busy"},{"startsAt":"2026-11-11T14:30:00Z","endsAt":"2026-11-11T14:45:00Z","status":"busy"},{"startsAt":"2026-11-11T18:00:00Z","endsAt":"2026-11-11T20:00:00Z","status":"busy"},{"startsAt":"2026-11-12T14:30:00Z","endsAt":"2026-11-12T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T13:00:00Z","endsAt":"2026-11-13T14:00:00Z","status":"busy"},{"startsAt":"2026-11-13T14:30:00Z","endsAt":"2026-11-13T14:45:00Z","status":"busy"},{"startsAt":"2026-11-13T18:00:00Z","endsAt":"2026-11-13T19:00:00Z","status":"busy"}]}},{"accountId":"{{account.sam}}","provider":"pyas","busy":[{"startsAt":"2026-11-08T10:00:00Z","endsAt":"2026-11-08T11:00:00Z","status":"busy"},{"startsAt":"2026-11-09T09:30:00Z","endsAt":"2026-11-09T09:45:00Z","status":"busy"},{"startsAt":"2026-11-09T14:00:00Z","endsAt":"2026-11-09T14:30:00Z","status":"busy"},{"startsAt":"2026-11-09T15:00:00Z","endsAt":"2026-11-09T16:00:00Z","status":"busy"},{"startsAt":"2026-11-10T09:30:00Z","endsAt":"2026-11-10T09:45:00Z","status":"busy"},{"startsAt":"2026-11-10T16:00:00Z","endsAt":"2026-11-10T16:30:00Z","status":"busy"},{"startsAt":"2026-11-11T09:30:00Z","endsAt":"2026-11-11T09:45:00Z","status":"busy"},{"startsAt":"2026-11-11T13:00:00Z","endsAt":"2026-11-11T15:00:00Z","status":"busy"},{"startsAt":"2026-11-12T09:30:00Z","endsAt":"2026-11-12T09:45:00Z","status":"busy"},{"startsAt":"2026-11-13T08:00:00Z","endsAt":"2026-11-13T09:00:00Z","status":"busy"},{"startsAt":"2026-11-13T09:30:00Z","endsAt":"2026-11-13T09:45:00Z","status":"busy"}],"calendars":{"primary":[{"startsAt":"2026-11-08T10:00:00Z","endsAt":"2026-11-08T11:00:00Z","status":"busy"},{"startsAt":"2026-11-09T09:30:00Z","endsAt":"2026-11-09T09:45:00Z","status":"busy"},{"startsAt":"2026-11-09T14:00:00Z","endsAt":"2026-11-09T14:30:00Z","status":"busy"},{"startsAt":"2026-11-09T15:00:00Z","endsAt":"2026-11-09T16:00:00Z","status":"busy"},{"startsAt":"2026-11-10T09:30:00Z","endsAt":"2026-11-10T09:45:00Z","status":"busy"},{"startsAt":"2026-11-10T16:00:00Z","endsAt":"2026-11-10T16:30:00Z","status":"busy"},{"startsAt":"2026-11-11T09:30:00Z","endsAt":"2026-11-11T09:45:00Z","status":"busy"},{"startsAt":"2026-11-11T13:00:00Z","endsAt":"2026-11-11T15:00:00Z","status":"busy"},{"startsAt":"2026-11-12T09:30:00Z","endsAt":"2026-11-12T09:45:00Z","status":"busy"},{"startsAt":"2026-11-13T08:00:00Z","endsAt":"2026-11-13T09:00:00Z","status":"busy"},{"startsAt":"2026-11-13T09:30:00Z","endsAt":"2026-11-13T09:45:00Z","status":"busy"}]}}]},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"from":"2026-11-08T00:00:00Z","to":"2026-11-15T00:00:00Z","partial":false}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/invitations":{"get":{"operationId":"invitations.list","summary":"List invitations","description":"Lists the invitations that virtual calendars sent for the app, newest first. The sandbox doesn't send invitations. Each one is listed with the status `captured` and the iCalendar text attendees would have received.","tags":["Invitations"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":1024},"example":"{{account.avery}}"},{"name":"eventId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":1024}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["queued","sent","captured","held","suppressed","failed"]}},{"name":"limit","in":"query","required":false,"description":"The maximum number of results in one page. Defaults to 50.","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"A page of invitations.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"description":"Pass it as `cursor` to get the next page. `null` on the last page.","type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/invitations/{invitationId}":{"get":{"operationId":"invitations.get","summary":"Get an invitation","description":"**In the sandbox:** Use an ID from `GET /v2/invitations`. An event with attendees on a virtual calendar creates invitations.","tags":["Invitations"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND"},"parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"example":"inv_from_the_list"}],"responses":{"200":{"description":"The invitation.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Invitation"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"inv_23871b494bdc3886eaf3bef0","accountId":"{{account.avery}}","calendarId":"{{calendar.avery.primary}}","eventId":"evtrsm7egur84pa64mdnoet","method":"REQUEST","kind":"new","to":"sam.patel@example.org","status":"captured","reason":null,"subject":"Invitation: Project kickoff @ Tue, Nov 10, 2026 10:00 AM to 11:00 AM (America/New_York)","createdAt":"2026-11-08T20:00:32.966Z","sentAt":null,"bounced":false,"complained":false,"ics":"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Pyas//Virtual calendar//EN\r\nCALSCALE:GREGORIAN\r\nMETHOD:REQUEST\r\nBEGIN:VTIMEZONE\r\nTZID:America/New_York\r\nBEGIN:STANDARD\r\nDTSTART:19700101T000000\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0500\r\nEND:STANDARD\r\nBEGIN:DAYLIGHT\r\nDTSTART:20260308T020000\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0400\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nDTSTART:20261101T020000\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0500\r\nEND:STANDARD\r\nBEGIN:DAYLIGHT\r\nDTSTART:20270314T020000\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0400\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nDTSTART:20271107T020000\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0500\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:evtrsm7egur84pa64mdnoet@cal.pyas.io\r\nSEQUENCE:0\r\nDTSTAMP:20261108T200032Z\r\nDTSTART;TZID=America/New_York:20261110T100000\r\nDTEND;TZID=America/New_York:20261110T110000\r\nSUMMARY:Project kickoff\r\nORGANIZER;CN=Avery Brooks:mailto:{{calendar.avery.primary}}@cal.pyas.io\r\nATTENDEE;CN=Sam Patel;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:\r\n mailto:sam.patel@example.org\r\nSTATUS:CONFIRMED\r\nTRANSP:OPAQUE\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/keys":{"get":{"operationId":"keys.list","summary":"List API keys","description":"Returns the app's keys, with their status and, for a rotated key, when it stops working. A live key lists live keys, and a test key lists test keys. Key values are never returned.","tags":["Keys"],"security":[{"ApiKey":[]}],"responses":{"200":{"description":"The keys.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/keys/{keyId}":{"get":{"operationId":"keys.get","summary":"Get an API key","description":"**In the sandbox:** `current` is the key that sent the request. The API reference sends requests with a key created for the docs, which isn't one of your app's keys. With your own test key, this request returns that key.","tags":["Keys"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND","key":"docs"},"parameters":[{"name":"keyId","in":"path","required":true,"description":"The key's ID, or `current` for the key that sent the request.","schema":{"type":"string","minLength":1,"maxLength":64},"example":"current"}],"responses":{"200":{"description":"The key.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/ApiKey"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"keyId":"3f7c2a91-5d4e-4b8a-9c6f-2e1d0b7a8c53","name":"Production","mode":"live","scopes":["read","write"],"status":"active","last4":null,"expiresAt":null,"graceEndsAt":null,"rotatedFrom":null,"rotatedTo":null,"createdAt":"2026-11-08T20:00:31Z","seenInBrowser":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/keys/{keyId}/rotate":{"post":{"operationId":"keys.rotate","summary":"Rotate an API key","description":"Creates a new key with the same name, scopes and mode, and returns its value once in this response. A key can rotate only itself, so send this request with the key that you want to rotate, and use `current` as the key ID. To rotate a different key, use the dashboard. The old key gets a grace period during which both keys work (default 24 hours, at most 168), so you can deploy the new key without any failed requests. When the grace period ends, the old key stops working. Pyas sends an `api_key.expiring` webhook 1 hour before the grace period ends, and an `api_key.revoked` webhook when it ends. A key can be rotated only once.\n\n**In the sandbox:** Rotates the key that sent the request. The API reference sends requests with a key created for the docs, which can't be rotated. With your own key, the response includes the new key (returned only once), and the old key keeps working for 24 more hours.","tags":["Keys"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND","key":"docs"},"parameters":[{"name":"keyId","in":"path","required":true,"description":"The key's ID, or `current` for the key that sent the request.","schema":{"type":"string","minLength":1,"maxLength":64},"example":"current"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"graceHours":{"type":"integer","minimum":0,"maximum":168,"description":"The number of hours that the old key keeps working. `0` stops the old key immediately."},"expiresInDays":{"type":"integer","minimum":1,"maximum":3650,"description":"The number of days until the new key expires. Defaults to the old key's lifetime, or no expiration if the old key never expired."}},"additionalProperties":false},"example":{"graceHours":24}}}},"responses":{"201":{"description":"The new key's value and details, and the details of the key you rotated.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"key":{"type":"string","description":"The new key's value, such as `pyas_sk_live_...`. Use it in place of the key you rotated. It is returned only in this response, so store it now."},"newKey":{"description":"The new key's details, such as its ID and last 4 characters. Its value is in `key`.","$ref":"#/components/schemas/ApiKey"},"previousKey":{"description":"The key you rotated, with the `rotating` status. It keeps working until `graceEndsAt`, then stops.","$ref":"#/components/schemas/ApiKey"}},"required":["key","newKey","previousKey"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"key":"pyas_sk_live_example","newKey":{"keyId":"2f660cba-c95f-4314-9466-b494c83efdae","name":"Production","mode":"live","scopes":["read","write"],"status":"active","last4":"NzNh","expiresAt":null,"graceEndsAt":null,"rotatedFrom":"3f7c2a91-5d4e-4b8a-9c6f-2e1d0b7a8c53","rotatedTo":null,"createdAt":"2026-11-08T20:00:32Z","seenInBrowser":null},"previousKey":{"keyId":"3f7c2a91-5d4e-4b8a-9c6f-2e1d0b7a8c53","name":"Production","mode":"live","scopes":["read","write"],"status":"rotating","last4":null,"expiresAt":"2026-11-09T20:00:32Z","graceEndsAt":"2026-11-09T20:00:32Z","rotatedFrom":null,"rotatedTo":"2f660cba-c95f-4314-9466-b494c83efdae","createdAt":"2026-11-08T20:00:31Z","seenInBrowser":null}},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/logs":{"get":{"operationId":"logs.list","summary":"List request logs","description":"Returns the app's v2 requests, newest first. Each log includes the status, error code and hint, and what happened while the request was processed: operations, provider requests, token refreshes, and the webhooks and invitations it triggered. A test key lists the sandbox's requests. Logs are kept for 7 days, or 14 days on Growth and 30 days on Scale. Request and response bodies are never stored.","tags":["Logs"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":256}},{"name":"subjectId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":256}},{"name":"outcome","in":"query","required":false,"description":"`failed` returns requests that received a 4xx or 5xx response. `succeeded` returns requests that received a 2xx or 3xx response.","schema":{"type":"string","enum":["failed","succeeded"]},"example":"failed"},{"name":"status","in":"query","required":false,"description":"An HTTP status code.","schema":{"type":"integer","minimum":100,"maximum":599}},{"name":"errorCode","in":"query","required":false,"description":"An error code, such as `CONNECTION_REVOKED`.","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"route","in":"query","required":false,"description":"An endpoint, as it appears in `route`, such as \"POST /v2/events\".","schema":{"type":"string","minLength":1,"maxLength":256}},{"name":"since","in":"query","required":false,"description":"Returns only requests made at or after this time.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"}},{"name":"until","in":"query","required":false,"description":"Returns only requests made before this time.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"}},{"name":"limit","in":"query","required":false,"description":"The maximum number of results in one page.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","minLength":1,"maxLength":2048}}],"responses":{"200":{"description":"The request logs.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/RequestLog"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/logs/{traceId}":{"get":{"operationId":"logs.get","summary":"Get a request log","description":"Returns one request by its trace ID, which is the `X-Trace-Id` header of any v2 response or the `traceId` of an error. Logs are written within a few seconds of the response.\n\n**In the sandbox:** Use the `X-Trace-Id` header from any earlier response, or the `traceId` from an error. Logs are written a few seconds after the response is sent.","tags":["Logs"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND"},"parameters":[{"name":"traceId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"trc_000000000000000000000000"}],"responses":{"200":{"description":"The request log.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/RequestLog"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","createdAt":"2026-11-08T20:00:32.997Z","mode":"test","keyId":null,"client":null,"method":"GET","route":"GET /v2/calendars","operationId":"calendars.list","path":"/v2/calendars","status":200,"durationMs":4,"accountId":"{{account.avery}}","subjectId":null,"error":null,"idempotencyKey":null,"replayed":false,"cache":"MISS","queuedMs":null,"operations":[{"provider":"pyas","operation":"listCalendars","accountId":"{{account.avery}}","durationMs":1}],"providerCalls":[],"tokenRefreshes":[],"webhookEvents":[],"invitations":[],"omitted":0},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/meeting-times":{"post":{"operationId":"meetingTimes.find","summary":"Find meeting times","description":"Finds free time slots common to several people across Google Calendar, Outlook and virtual calendars. Slots respect each attendee's working hours, buffers and minimum notice, and can include a room.","tags":["Availability"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"attendees":{"description":"The required and optional attendees. Send this or `accountIds`.","minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":128,"description":"The Pyas `accountId` of the attendee's connected account."},"calendarRefs":{"description":"The calendars whose events count as busy. Defaults to `primary`.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1}},"optional":{"type":"boolean","description":"Marks the attendee as optional. Each slot shows whether optional attendees are free, but doesn't require them to be."}},"required":["accountId"],"additionalProperties":false}},"accountIds":{"description":"A shorthand for `attendees`. Each account is a required attendee, read on its primary calendar.","minItems":1,"type":"array","items":{"type":"string","minLength":1}},"from":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$","description":"The start of the time window to search.","format":"date-time","examples":["2026-03-15T14:00:00Z"]},"to":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$","description":"The end of the time window, at most 62 days after `from`.","format":"date-time","examples":["2026-03-15T14:00:00Z"]},"durationMinutes":{"type":"integer","minimum":5,"maximum":1440,"description":"The length of the meeting in minutes. Defaults to 30."},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"The IANA time zone that slots line up with (on the hour or half hour there). Slot times are always returned in UTC. Defaults to UTC."},"workingHours":{"description":"The working hours to use for attendees whose provider doesn't report them. Without a `timezone`, they apply in each attendee's own time zone. Defaults to 09:00 to 17:00, Monday to Friday.","type":"object","properties":{"days":{"minItems":1,"type":"array","items":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]}},"start":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"end":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"timezone":{"type":"string"}},"required":["days","start","end"],"additionalProperties":false},"respectWorkingHours":{"type":"boolean","description":"Whether to return only slots within working hours. Defaults to `true`."},"buffer":{"description":"The minutes to keep free before and after other events.","type":"object","properties":{"before":{"type":"integer","minimum":0,"maximum":240},"after":{"type":"integer","minimum":0,"maximum":240}},"additionalProperties":false},"minimumNoticeMinutes":{"type":"integer","minimum":0,"maximum":43200,"description":"The minimum number of minutes between now and the start of a slot."},"slotMinutes":{"type":"integer","minimum":5,"maximum":60,"description":"The interval between slot start times, in minutes: 5, 10, 15, 20, 30 or 60. Defaults to 30."},"tentativeIsBusy":{"type":"boolean","description":"Whether to count tentative events as busy. Defaults to `true`."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"The maximum number of slots to return. Defaults to 20."},"rooms":{"description":"Finds a free room as well, from the listed room email addresses or from the organization's matching rooms.","type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":128,"description":"The account whose organization the rooms are in."},"emails":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^[^\\s@]+@[^\\s@]+$"}},"minCapacity":{"type":"integer","minimum":1,"maximum":10000},"building":{"type":"string","minLength":1,"maxLength":256},"required":{"type":"boolean","description":"Whether to return only slots with a free room. Defaults to `true`."}},"required":["accountId"],"additionalProperties":false}},"required":["from","to"],"additionalProperties":false},"example":{"accountIds":["{{account.avery}}","{{account.sam}}"],"from":"{{in.1d}}","to":"{{in.8d}}","durationMinutes":30,"timezone":"America/New_York"}}}},"responses":{"200":{"description":"The available slots, earliest first.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/MeetingSlot"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"timezone":{"type":"string"},"attendees":{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"optional":{"type":"boolean"},"workingHours":{"anyOf":[{"type":"object","properties":{"days":{"type":"array","items":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]}},"start":{"type":"string"},"end":{"type":"string"},"timezone":{"type":"string"},"source":{"type":"string","enum":["provider","request","default"]}},"required":["days","start","end","timezone","source"],"additionalProperties":false},{"type":"null"}]},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["accountId","optional","workingHours"],"additionalProperties":false},"description":"Each attendee, the working hours used for them, and any error reading their calendars."},"partial":{"type":"boolean","description":"`true` when an attendee or room couldn't be read. The slots are calculated without them."},"rooms":{"type":"object","properties":{"candidates":{"type":"array","items":{"type":"string"},"description":"The rooms considered."},"errors":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Rooms that couldn't be read, with the reason for each."}},"required":["candidates","errors"],"additionalProperties":false}},"required":["timezone","attendees","partial"],"additionalProperties":false}}},"example":{"success":true,"data":[{"startsAt":"2026-11-10T14:00:00Z","endsAt":"2026-11-10T14:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-10T15:00:00Z","endsAt":"2026-11-10T15:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-10T15:30:00Z","endsAt":"2026-11-10T16:00:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-10T16:30:00Z","endsAt":"2026-11-10T17:00:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-11T15:00:00Z","endsAt":"2026-11-11T15:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-11T15:30:00Z","endsAt":"2026-11-11T16:00:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-11T16:00:00Z","endsAt":"2026-11-11T16:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-11T16:30:00Z","endsAt":"2026-11-11T17:00:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-12T14:00:00Z","endsAt":"2026-11-12T14:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-12T15:00:00Z","endsAt":"2026-11-12T15:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-12T15:30:00Z","endsAt":"2026-11-12T16:00:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-12T16:00:00Z","endsAt":"2026-11-12T16:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-12T16:30:00Z","endsAt":"2026-11-12T17:00:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-13T14:00:00Z","endsAt":"2026-11-13T14:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-13T15:00:00Z","endsAt":"2026-11-13T15:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-13T15:30:00Z","endsAt":"2026-11-13T16:00:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-13T16:00:00Z","endsAt":"2026-11-13T16:30:00Z","optionalFree":[],"optionalBusy":[]},{"startsAt":"2026-11-13T16:30:00Z","endsAt":"2026-11-13T17:00:00Z","optionalFree":[],"optionalBusy":[]}],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"timezone":"America/New_York","attendees":[{"accountId":"{{account.avery}}","optional":false,"workingHours":{"days":["monday","tuesday","wednesday","thursday","friday"],"start":"09:00","end":"17:00","timezone":"America/New_York","source":"default"}},{"accountId":"{{account.sam}}","optional":false,"workingHours":{"days":["monday","tuesday","wednesday","thursday","friday"],"start":"09:00","end":"17:00","timezone":"Europe/London","source":"default"}}],"partial":false}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/meetings":{"get":{"operationId":"meetings.list","summary":"List meetings","description":"Lists a Zoom account's meetings, the next ones first. `type` chooses which: `upcoming` (the default), `scheduled`, `live` or `previous`. Microsoft Teams and Google Meet have no list of meetings made with no event, so their accounts are rejected: keep the ID the create returns.","tags":["Meetings"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /zoom/meetings"],"notes":["v1's `maxResults` is `limit`, `nextPageToken` is `cursor`, and `startDate` and `endDate` are `from` and `to`."]},"parameters":[{"name":"accountId","in":"query","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.zoom}}"},{"name":"type","in":"query","required":false,"description":"Which meetings: `upcoming` (the default), `scheduled`, `live` or `previous`.","schema":{"type":"string","enum":["upcoming","scheduled","live","previous"]}},{"name":"from","in":"query","required":false,"description":"The first day (YYYY-MM-DD).","schema":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},{"name":"to","in":"query","required":false,"description":"The last day (YYYY-MM-DD).","schema":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},{"name":"limit","in":"query","required":false,"description":"The maximum number of meetings in one page. Defaults to 30.","schema":{"type":"integer","minimum":1,"maximum":300}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","minLength":1,"maxLength":2048}}],"responses":{"200":{"description":"The meetings.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Meeting"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"description":"Pass it as `cursor` to get the next page. `null` on the last page.","type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[{"id":"{{meeting.zoom.standup}}","provider":"zoom","accountId":"{{account.zoom}}","kind":"recurring","title":"Team standup","description":null,"startsAt":"2026-11-09T14:30:00Z","durationMinutes":15,"timezone":"America/New_York","recurrence":null,"occurrences":[],"joinUrl":"https://zoom.us/j/{{meeting.zoom.standup}}?pwd=9pnByLlPi43xeCouDVOGZ3GJK8RNuRWi","passcode":null,"dialIn":[],"settings":{},"createdAt":"2026-11-08T20:00:23Z"},{"id":"67556028668","provider":"zoom","accountId":"{{account.zoom}}","kind":"scheduled","title":"Customer onboarding (Zoom)","description":null,"startsAt":"2026-11-09T16:00:00Z","durationMinutes":60,"timezone":"America/New_York","recurrence":null,"occurrences":[],"joinUrl":"https://zoom.us/j/67556028668?pwd=k1NV6aHSXvDYLT96s3yhRedsmHRIroO0","passcode":null,"dialIn":[],"settings":{},"createdAt":"2026-11-08T20:00:24Z"},{"id":"{{meeting.zoom.demo}}","provider":"zoom","accountId":"{{account.zoom}}","kind":"scheduled","title":"Product demo","description":"Walk through the new scheduling flow.","startsAt":"2026-11-12T20:00:00Z","durationMinutes":45,"timezone":"America/New_York","recurrence":null,"occurrences":[],"joinUrl":"https://zoom.us/j/{{meeting.zoom.demo}}?pwd=uQj_Ps-IiROCfXW0Y-B5v7kTyLW3P6P7","passcode":null,"dialIn":[],"settings":{},"createdAt":"2026-11-08T20:00:23Z"}],"provider":"zoom","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"meetings.create","summary":"Create a meeting","description":"Creates a meeting with no calendar event: a Zoom meeting on a Zoom account, a Microsoft Teams meeting on a Microsoft work or school account, or a Google Meet link on a Google account. Zoom meetings always have a passcode: set one in `settings`, or Pyas makes one; Teams makes its own. A Teams meeting with no event happens once and has no description. A Google Meet link has no title or time: send only `accountId` and `settings`. It needs the `meetingSettings` connect feature (Google's `meetings.space.created` permission). To put a meeting on an event, use `conferencing` on `POST /v2/events` instead.","tags":["Meetings"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["POST /zoom/meetings"],"notes":["v1's `meetingData` fields are top level: `title`, `description`, `startsAt` (was `startDate`), `durationMinutes` (was `duration`), `timezone` (was `timeZone`), `attendees`, `recurrence` (an RRULE) and `settings` (`admission: organizer` for v1's `waitingRoom: true`)."]},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and doesn't make the change twice.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeetingCreate"},"example":{"accountId":"{{account.zoom}}","title":"Customer kickoff","startsAt":"{{in.2d.16:00}}","durationMinutes":45,"timezone":"America/New_York","settings":{"admission":"organizer"}}}}},"responses":{"201":{"description":"The meeting.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Meeting"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"70544193435","provider":"zoom","accountId":"{{account.zoom}}","kind":"scheduled","title":"Customer kickoff","description":null,"startsAt":"2026-11-10T16:00:00Z","durationMinutes":45,"timezone":"America/New_York","recurrence":null,"occurrences":[],"joinUrl":"https://zoom.us/j/70544193435?pwd=ULy4JwXVyskJ5qGKo71ayxu4dZsVvoGc","passcode":"Cbx2Q611p0","dialIn":[{"label":"US New York","number":"+1 555 0100","pin":"661300"}],"settings":{"admission":"organizer","recording":"none","joinBeforeHost":false,"muteOnEntry":false,"coHosts":[]},"createdAt":"2026-11-08T20:00:25Z"},"provider":"zoom","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`VALIDATION_REJECTED_BY_PROVIDER`: The calendar provider rejected this input.\n\n`VALIDATION_IDEMPOTENCY_CONFLICT`: This idempotency key was already used with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/meetings/{meetingId}":{"delete":{"operationId":"meetings.delete","summary":"Delete a meeting","description":"Deletes the meeting. With `notify=true`, Zoom emails the host and the people invited that it was canceled. Microsoft Teams sends no cancellation for a meeting with no event, so `notify=true` is rejected there. Google Meet links can't be deleted, so a Google account is rejected.","tags":["Meetings"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["DELETE /zoom/meetings/:id"],"notes":["v1 always sent the cancellation email; in v2 it is `notify=true`."]},"parameters":[{"name":"meetingId","in":"path","required":true,"description":"The meeting ID, as the create or list returned it.","schema":{"type":"string","minLength":1,"maxLength":512},"example":"{{meeting.zoom.demo}}"},{"name":"accountId","in":"query","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.zoom}}"},{"name":"notify","in":"query","required":false,"description":"Zoom only. Whether Zoom emails a cancellation. `false` if you don't set it.","schema":{"type":"boolean"},"example":"false"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and doesn't make the change twice.","schema":{"type":"string"}}],"responses":{"200":{"description":"The request succeeded. `data` is `null`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":"zoom","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"meetings.get","summary":"Get a meeting","description":"Gets a meeting, with a recurring Zoom meeting's occurrences.","tags":["Meetings"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["GET /zoom/meetings/:id"],"notes":["v1 returned the meeting in `meeting`; v2 returns it in `data`, like every v2 read."]},"parameters":[{"name":"meetingId","in":"path","required":true,"description":"The meeting ID, as the create or list returned it.","schema":{"type":"string","minLength":1,"maxLength":512},"example":"{{meeting.zoom.standup}}"},{"name":"accountId","in":"query","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.zoom}}"}],"responses":{"200":{"description":"The meeting.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Meeting"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{meeting.zoom.standup}}","provider":"zoom","accountId":"{{account.zoom}}","kind":"recurring","title":"Team standup","description":null,"startsAt":"2026-11-09T14:30:00Z","durationMinutes":15,"timezone":"America/New_York","recurrence":"FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;COUNT=60","occurrences":[{"id":"1794234600000","startsAt":"2026-11-09T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1794321000000","startsAt":"2026-11-10T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1794407400000","startsAt":"2026-11-11T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1794493800000","startsAt":"2026-11-12T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1794580200000","startsAt":"2026-11-13T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1794839400000","startsAt":"2026-11-16T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1794925800000","startsAt":"2026-11-17T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795012200000","startsAt":"2026-11-18T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795098600000","startsAt":"2026-11-19T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795185000000","startsAt":"2026-11-20T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795444200000","startsAt":"2026-11-23T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795530600000","startsAt":"2026-11-24T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795617000000","startsAt":"2026-11-25T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795703400000","startsAt":"2026-11-26T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1795789800000","startsAt":"2026-11-27T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1796049000000","startsAt":"2026-11-30T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1796135400000","startsAt":"2026-12-01T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1796221800000","startsAt":"2026-12-02T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1796308200000","startsAt":"2026-12-03T14:30:00Z","durationMinutes":15,"status":"available"},{"id":"1796394600000","startsAt":"2026-12-04T14:30:00Z","durationMinutes":15,"status":"available"}],"joinUrl":"https://zoom.us/j/{{meeting.zoom.standup}}?pwd=9pnByLlPi43xeCouDVOGZ3GJK8RNuRWi","passcode":"standup1","dialIn":[{"label":"US New York","number":"+1 555 0100","pin":"863020"}],"settings":{"admission":"everyone","recording":"none","joinBeforeHost":false,"muteOnEntry":false,"coHosts":[]},"createdAt":"2026-11-08T20:00:23Z"},"provider":"zoom","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"meetings.update","summary":"Update a meeting","description":"Changes only the fields you send, and returns the meeting as it is now. A Google Meet link changes only its settings.","tags":["Meetings"],"security":[{"ApiKey":[]}],"x-pyas-v1":{"replaces":["PATCH /zoom/meetings/:id"],"notes":["`accountId` is in the query. v1 resent every field with a new passcode; v2 changes only what you send."]},"parameters":[{"name":"meetingId","in":"path","required":true,"description":"The meeting ID, as the create or list returned it.","schema":{"type":"string","minLength":1,"maxLength":512},"example":"{{meeting.zoom.demo}}"},{"name":"accountId","in":"query","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.zoom}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and doesn't make the change twice.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeetingPatch"},"example":{"title":"Product demo: scheduling flow","durationMinutes":60}}}},"responses":{"200":{"description":"The meeting.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Meeting"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"id":"{{meeting.zoom.demo}}","provider":"zoom","accountId":"{{account.zoom}}","kind":"scheduled","title":"Product demo: scheduling flow","description":"Walk through the new scheduling flow.","startsAt":"2026-11-12T20:00:00Z","durationMinutes":60,"timezone":"America/New_York","recurrence":null,"occurrences":[],"joinUrl":"https://zoom.us/j/{{meeting.zoom.demo}}?pwd=uQj_Ps-IiROCfXW0Y-B5v7kTyLW3P6P7","passcode":"demo2026","dialIn":[{"label":"US New York","number":"+1 555 0100","pin":"510795"}],"settings":{"admission":"organizer","recording":"none","joinBeforeHost":false,"muteOnEntry":false,"coHosts":[]},"createdAt":"2026-11-08T20:00:24Z"},"provider":"zoom","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_REVOKED`: The user revoked access, or the provider no longer accepts the stored credentials.\n\n`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.\n\n`VALIDATION_REJECTED_BY_PROVIDER`: The calendar provider rejected this input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/metadata/import":{"post":{"operationId":"metadata.import","summary":"Import extended properties into metadata","description":"Copies the provider's extended properties from events on the selected calendars into the events' metadata. The import runs in the background and doesn't modify the calendar. With `dryRun: true`, the API immediately returns a report on a sample, showing which keys exist and on how many events, and writes nothing.\n\n**In the sandbox:** Copies the extended properties that another app wrote on Google and Outlook events into metadata. A dry run reports what would be copied. For Outlook, set `microsoft.properties` to the IDs of the properties to read.","tags":["Metadata"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountIds":{"description":"The accounts to import from. Send one of `accountIds`, `subjectId` or `allAccounts`.","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1}},"subjectId":{"description":"Imports from every account with this `subjectId`.","type":"string","minLength":1,"maxLength":255},"allAccounts":{"description":"Imports from every account in the app.","type":"boolean","const":true},"calendarRefs":{"description":"The calendars to read. Defaults to `primary`.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1}},"from":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$","description":"An ISO 8601 time with a zone.","format":"date-time","examples":["2026-03-15T14:00:00Z"]},"to":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$","description":"An ISO 8601 time with a zone.","format":"date-time","examples":["2026-03-15T14:00:00Z"]},"google":{"type":"object","properties":{"scope":{"type":"string","enum":["private","shared","both"],"description":"Which extended properties to read. Defaults to `both`."},"keys":{"description":"The keys to import. Defaults to every key.","minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1}}},"additionalProperties":false},"microsoft":{"type":"object","properties":{"properties":{"minItems":1,"maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","minLength":1},{"type":"object","properties":{"id":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["id","key"],"additionalProperties":false}]},"description":"The properties to read, by ID, of any type: `String {00020329-0000-0000-c000-000000000046} Name orderId`, `IntegerArray {...} Name counts` (imported as a list), or a numbered one such as `Integer 0x8012`. A named property imports under its name. To choose the key, send `{ \"id\": \"...\", \"key\": \"count\" }`, which a numbered property needs. Outlook can read these properties only by ID."}},"required":["properties"],"additionalProperties":false},"overwrite":{"type":"boolean","description":"Whether to replace metadata already set through v2. Defaults to `false`, which keeps the existing metadata."},"convert":{"type":"string","enum":["none","auto"],"description":"With `auto`, values such as \"42\" and \"true\" are converted to a number and a boolean."},"dryRun":{"type":"boolean","description":"Returns a report on a sample of recent events without writing any metadata."},"sampleSize":{"type":"integer","minimum":1,"maximum":1000,"description":"For a dry run, the number of events to read per calendar. Defaults to 200."}},"additionalProperties":false},"example":{"accountIds":["{{account.google}}"],"dryRun":true}}}},"responses":{"200":{"description":"The report on a sample, returned when `dryRun` is `true`.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/MetadataImportPreview"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}}}}},"202":{"description":"The import, queued.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/MetadataImport"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"importId":"mi_2387a8fe491044d8ad779768cee4a8f0","status":"queued","request":{"accounts":{"accountIds":["{{account.google}}"]},"calendarRefs":["primary"],"google":{"scope":"both"},"overwrite":false,"convert":"none"},"progress":{"calendars":0,"finished":0},"counts":{"scanned":0,"copied":0,"unchanged":0,"skipped":0},"skippedKeys":[],"skipped":[],"errors":[],"createdAt":"2026-11-08T20:00:32.982Z","startedAt":null,"finishedAt":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/metadata/imports":{"get":{"operationId":"metadata.imports.list","summary":"List metadata imports","tags":["Metadata"],"security":[{"ApiKey":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"The number of imports to return, newest first. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"The app's recent imports.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/MetadataImport"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/metadata/imports/{importId}":{"delete":{"operationId":"metadata.imports.cancel","summary":"Cancel a metadata import","description":"**In the sandbox:** Use the `importId` returned by `POST /v2/metadata/import`.","tags":["Metadata"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND"},"parameters":[{"name":"importId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"example":"mimp_from_the_import"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The cancelled import. Metadata that was already copied is kept.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/MetadataImport"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"importId":"mi_2387a8fe491044d8ad779768cee4a8f0","status":"cancelled","request":{"accounts":{"accountIds":["{{account.google}}"]},"calendarRefs":["primary"],"google":{"scope":"both"},"overwrite":false,"convert":"none"},"progress":{"calendars":0,"finished":0},"counts":{"scanned":0,"copied":0,"unchanged":0,"skipped":0},"skippedKeys":[],"skipped":[],"errors":[],"createdAt":"2026-11-08T20:00:32.982Z","startedAt":null,"finishedAt":"2026-11-08T20:00:32.994Z"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"metadata.imports.get","summary":"Get a metadata import","description":"**In the sandbox:** Use the `importId` returned by `POST /v2/metadata/import`.","tags":["Metadata"],"security":[{"ApiKey":[]}],"x-pyas-sandbox":{"status":404,"code":"RESOURCE_NOT_FOUND"},"parameters":[{"name":"importId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"example":"mimp_from_the_import"}],"responses":{"200":{"description":"The import's progress and results.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/MetadataImport"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"importId":"mi_2387a8fe491044d8ad779768cee4a8f0","status":"queued","request":{"accounts":{"accountIds":["{{account.google}}"]},"calendarRefs":["primary"],"google":{"scope":"both"},"overwrite":false,"convert":"none"},"progress":{"calendars":0,"finished":0},"counts":{"scanned":0,"copied":0,"unchanged":0,"skipped":0},"skippedKeys":[],"skipped":[],"errors":[],"createdAt":"2026-11-08T20:00:32.982Z","startedAt":null,"finishedAt":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/rooms":{"get":{"operationId":"rooms.list","summary":"List rooms and resources","description":"Returns the rooms and resources of the account's organization, from the Google Workspace resource directory or from the Microsoft Outlook room list. Both providers require an administrator's consent, and the error explains when it is missing. To book a room, add its email address to an event's `rooms`.","tags":["Availability"],"security":[{"ApiKey":[]}],"parameters":[{"name":"accountId","in":"query","required":true,"description":"The Pyas `accountId` of the connected account.","schema":{"type":"string","minLength":1,"maxLength":128},"example":"{{account.google}}"},{"name":"minCapacity","in":"query","required":false,"description":"Returns only rooms with at least this many seats.","schema":{"type":"integer","minimum":1,"maximum":10000},"example":"6"},{"name":"building","in":"query","required":false,"description":"In this building (its name, any case).","schema":{"type":"string","maxLength":256}},{"name":"feature","in":"query","required":false,"description":"Returns only rooms with a feature that contains this text, such as `video`.","schema":{"type":"string","maxLength":256}},{"name":"q","in":"query","required":false,"description":"Returns only rooms whose name or email address contains this text.","schema":{"type":"string","maxLength":256}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["room","resource"]}}],"responses":{"200":{"description":"The rooms and resources that match.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Room"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[{"id":"c_1880boardroom","name":"Boardroom","email":"c_1880boardroom@resource.calendar.google.com","capacity":12,"building":"HQ","floor":"3","features":["Video conferencing","Whiteboard"],"accessible":null,"kind":"room"},{"id":"c_1880room4b","name":"Room 4B","email":"c_1880room4b@resource.calendar.google.com","capacity":6,"building":"HQ","floor":"4","features":["Display"],"accessible":null,"kind":"room"}],"provider":"google","traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`CONNECTION_SCOPE_INSUFFICIENT`: The connected account did not grant a permission that this operation requires.\n\n`VALIDATION_UNSUPPORTED_OPERATION`: This provider does not support this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`PROVIDER_RATE_LIMITED`: The calendar provider is rate limiting requests for this account.\n\n`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`PROVIDER_UNAVAILABLE`: The calendar provider is not responding normally.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/sandbox":{"get":{"operationId":"sandbox.get","summary":"Get the sandbox","description":"Returns your app's sandbox. The sandbox works only with a test key and is created on its first request. It includes virtual accounts with sample calendars and events, and simulated Google, Outlook and Zoom accounts that respond as those providers do without contacting them.","tags":["Sandbox"],"security":[{"ApiKey":[]}],"responses":{"200":{"description":"The sandbox and its accounts.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Sandbox"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"seededAt":"2026-11-08T20:00:23.534Z","accounts":[{"accountId":"{{account.avery}}","provider":"pyas","name":"Avery Brooks","subjectId":"{{subject.avery}}"},{"accountId":"{{account.sam}}","provider":"pyas","name":"Sam Patel","subjectId":"{{subject.sam}}"},{"accountId":"{{account.yuki}}","provider":"pyas","name":"Yuki Tanaka","subjectId":"{{subject.yuki}}"},{"accountId":"{{account.jordan}}","provider":"pyas","name":"Jordan Lee","subjectId":"{{subject.jordan}}"},{"accountId":"{{account.riley}}","provider":"pyas","name":"Riley Chen","subjectId":"{{subject.riley}}"},{"accountId":"{{account.google}}","provider":"google","name":"Avery Brooks","subjectId":"{{subject.avery}}"},{"accountId":"{{account.outlook}}","provider":"microsoft","name":"Sam Patel","subjectId":"{{subject.sam}}"},{"accountId":"{{account.zoom}}","provider":"zoom","name":"Avery Brooks","subjectId":"{{subject.avery}}"}],"examples":{"account.avery":"{{account.avery}}","subject.avery":"{{subject.avery}}","calendar.avery.primary":"{{calendar.avery.primary}}","calendar.avery.work":"{{calendar.avery.work}}","event.avery.standup":"{{event.avery.standup}}","event.avery.sprint":"{{event.avery.sprint}}","event.avery.oneonone":"{{event.avery.oneonone}}","event.avery.productsync":"{{event.avery.productsync}}","event.avery.design":"{{event.avery.design}}","event.avery.customer":"{{event.avery.customer}}","event.avery.lunch":"{{event.avery.lunch}}","event.avery.dentist":"{{event.avery.dentist}}","event.avery.focus":"{{event.avery.focus}}","event.avery.talk":"{{event.avery.talk}}","event.avery.offsite":"{{event.avery.offsite}}","event.avery.holiday":"{{event.avery.holiday}}","event.avery.quarterly":"{{event.avery.quarterly}}","event.avery.board":"{{event.avery.board}}","event.avery.release":"{{event.avery.release}}","event.avery.oncall":"{{event.avery.oncall}}","event.avery.retro":"{{event.avery.retro}}","event.avery.hiring":"{{event.avery.hiring}}","account.sam":"{{account.sam}}","subject.sam":"{{subject.sam}}","calendar.sam.primary":"{{calendar.sam.primary}}","calendar.sam.work":"{{calendar.sam.work}}","event.sam.standup":"{{event.sam.standup}}","event.sam.sprint":"{{event.sam.sprint}}","event.sam.oneonone":"{{event.sam.oneonone}}","event.sam.productsync":"{{event.sam.productsync}}","event.sam.design":"{{event.sam.design}}","event.sam.customer":"{{event.sam.customer}}","event.sam.lunch":"{{event.sam.lunch}}","event.sam.dentist":"{{event.sam.dentist}}","event.sam.focus":"{{event.sam.focus}}","event.sam.talk":"{{event.sam.talk}}","event.sam.offsite":"{{event.sam.offsite}}","event.sam.holiday":"{{event.sam.holiday}}","event.sam.quarterly":"{{event.sam.quarterly}}","event.sam.board":"{{event.sam.board}}","event.sam.release":"{{event.sam.release}}","event.sam.oncall":"{{event.sam.oncall}}","event.sam.retro":"{{event.sam.retro}}","event.sam.hiring":"{{event.sam.hiring}}","account.yuki":"{{account.yuki}}","subject.yuki":"{{subject.yuki}}","calendar.yuki.primary":"{{calendar.yuki.primary}}","calendar.yuki.work":"{{calendar.yuki.work}}","event.yuki.standup":"{{event.yuki.standup}}","event.yuki.sprint":"{{event.yuki.sprint}}","event.yuki.oneonone":"{{event.yuki.oneonone}}","event.yuki.productsync":"{{event.yuki.productsync}}","event.yuki.design":"{{event.yuki.design}}","event.yuki.customer":"{{event.yuki.customer}}","event.yuki.lunch":"{{event.yuki.lunch}}","event.yuki.dentist":"{{event.yuki.dentist}}","event.yuki.focus":"{{event.yuki.focus}}","event.yuki.talk":"{{event.yuki.talk}}","event.yuki.offsite":"{{event.yuki.offsite}}","event.yuki.holiday":"{{event.yuki.holiday}}","event.yuki.quarterly":"{{event.yuki.quarterly}}","event.yuki.board":"{{event.yuki.board}}","event.yuki.release":"{{event.yuki.release}}","event.yuki.oncall":"{{event.yuki.oncall}}","event.yuki.retro":"{{event.yuki.retro}}","event.yuki.hiring":"{{event.yuki.hiring}}","account.jordan":"{{account.jordan}}","subject.jordan":"{{subject.jordan}}","calendar.jordan.primary":"{{calendar.jordan.primary}}","calendar.jordan.work":"{{calendar.jordan.work}}","event.jordan.standup":"{{event.jordan.standup}}","event.jordan.sprint":"{{event.jordan.sprint}}","event.jordan.oneonone":"{{event.jordan.oneonone}}","event.jordan.productsync":"{{event.jordan.productsync}}","event.jordan.design":"{{event.jordan.design}}","event.jordan.customer":"{{event.jordan.customer}}","event.jordan.lunch":"{{event.jordan.lunch}}","event.jordan.dentist":"{{event.jordan.dentist}}","event.jordan.focus":"{{event.jordan.focus}}","event.jordan.talk":"{{event.jordan.talk}}","event.jordan.offsite":"{{event.jordan.offsite}}","event.jordan.holiday":"{{event.jordan.holiday}}","event.jordan.quarterly":"{{event.jordan.quarterly}}","event.jordan.board":"{{event.jordan.board}}","event.jordan.release":"{{event.jordan.release}}","event.jordan.oncall":"{{event.jordan.oncall}}","event.jordan.retro":"{{event.jordan.retro}}","event.jordan.hiring":"{{event.jordan.hiring}}","account.riley":"{{account.riley}}","subject.riley":"{{subject.riley}}","calendar.riley.primary":"{{calendar.riley.primary}}","calendar.riley.work":"{{calendar.riley.work}}","event.riley.standup":"{{event.riley.standup}}","event.riley.sprint":"{{event.riley.sprint}}","event.riley.oneonone":"{{event.riley.oneonone}}","event.riley.productsync":"{{event.riley.productsync}}","event.riley.design":"{{event.riley.design}}","event.riley.customer":"{{event.riley.customer}}","event.riley.lunch":"{{event.riley.lunch}}","event.riley.dentist":"{{event.riley.dentist}}","event.riley.focus":"{{event.riley.focus}}","event.riley.talk":"{{event.riley.talk}}","event.riley.offsite":"{{event.riley.offsite}}","event.riley.holiday":"{{event.riley.holiday}}","event.riley.quarterly":"{{event.riley.quarterly}}","event.riley.board":"{{event.riley.board}}","event.riley.release":"{{event.riley.release}}","event.riley.oncall":"{{event.riley.oncall}}","event.riley.retro":"{{event.riley.retro}}","event.riley.hiring":"{{event.riley.hiring}}","event.avery.zoomcall":"{{event.avery.zoomcall}}","account.google":"{{account.google}}","account.outlook":"{{account.outlook}}","account.zoom":"{{account.zoom}}","calendar.google.primary":"{{calendar.google.primary}}","calendar.google.team":"{{calendar.google.team}}","calendar.google.holidays":"{{calendar.google.holidays}}","calendar.outlook.primary":"{{calendar.outlook.primary}}","calendar.outlook.acme":"{{calendar.outlook.acme}}","calendar.outlook.morgan":"{{calendar.outlook.morgan}}","attachment.google.agenda":"{{attachment.google.agenda}}","attachment.outlook.agenda":"{{attachment.outlook.agenda}}","permission.outlook.morgan":"{{permission.outlook.morgan}}","meeting.zoom.standup":"{{meeting.zoom.standup}}","meeting.zoom.demo":"{{meeting.zoom.demo}}","event.google.invite":"{{event.google.invite}}","event.google.kickoff":"{{event.google.kickoff}}","event.google.weekly":"{{event.google.weekly}}","event.google.focus":"{{event.google.focus}}","event.google.trip":"{{event.google.trip}}","event.google.office":"{{event.google.office}}","event.google.home":"{{event.google.home}}","event.outlook.review":"{{event.outlook.review}}","event.outlook.invite":"{{event.outlook.invite}}","event.outlook.oneonone":"{{event.outlook.oneonone}}","event.outlook.lunch":"{{event.outlook.lunch}}","event.outlook.acme":"{{event.outlook.acme}}","category.outlook.red":"{{category.outlook.red}}","category.outlook.orange":"{{category.outlook.orange}}","category.outlook.yellow":"{{category.outlook.yellow}}","category.outlook.green":"{{category.outlook.green}}","category.outlook.blue":"{{category.outlook.blue}}","category.outlook.purple":"{{category.outlook.purple}}","category.google.deepwork":"{{category.google.deepwork}}","category.google.travel":"{{category.google.travel}}","group.outlook.mine":"{{group.outlook.mine}}","group.outlook.others":"{{group.outlook.others}}","group.outlook.clients":"{{group.outlook.clients}}","group.outlook.projects":"{{group.outlook.projects}}","webhook.inbox":"{{webhook.inbox}}","webhookEvent.inbox":"{{webhookEvent.inbox}}","delivery.inbox":"{{delivery.inbox}}"}},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/sandbox/reset":{"post":{"operationId":"sandbox.reset","summary":"Reset the sandbox","description":"Deletes everything in the sandbox and repopulates it with the sample accounts, calendars and events.","tags":["Sandbox"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"The sandbox was reset.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"seededAt":{"description":"When the sandbox was last populated with sample data.","type":["string","null"]}},"required":["seededAt"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"seededAt":"2026-11-08T20:00:24.721Z"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/sandbox/simulate-change":{"post":{"operationId":"sandbox.simulateChange","summary":"Simulate an external change","description":"Creates, updates or deletes an event the way someone outside your app would, for example in Google Calendar, Microsoft Outlook or another app. Use it to test how your app handles changes it didn't make. Pyas detects the change and sends webhooks as it would for a real account. The webhooks don't include `request`, because the change didn't come from one of your requests. `created` adds an event tomorrow at 16:00 UTC. `updated` renames an event and moves it 30 minutes later. `deleted` deletes the event. If you omit `eventId`, the API uses the next upcoming single event on the calendar.\n\n**In the sandbox:** Then check for the webhooks in `GET /v2/webhooks/deliveries` (the sandbox inbox) or in the relay.","tags":["Sandbox"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":128,"description":"A sandbox account. Use a virtual account, or the simulated Google or Outlook account."},"change":{"type":"string","enum":["created","updated","deleted"]},"eventId":{"type":"string","minLength":1,"maxLength":1024},"calendarRef":{"type":"string","minLength":1,"maxLength":1024,"description":"Defaults to `primary`."}},"required":["accountId","change"],"additionalProperties":false},"example":{"accountId":"{{account.google}}","change":"updated","eventId":"{{event.google.kickoff}}"}}}},"responses":{"200":{"description":"The change that was made, and the event as it is now, or as it was before it was deleted. Webhooks are sent within a few seconds.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"change":{"type":"string","enum":["created","updated","deleted"]},"event":{"$ref":"#/components/schemas/Event"}},"required":["change","event"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"change":"updated","event":{"id":"{{event.google.kickoff}}","iCalUID":"{{event.google.kickoff}}@google.com","title":"Project Atlas kickoff (changed)","description":null,"location":null,"startsAt":"2026-11-09T19:30:00Z","endsAt":"2026-11-09T20:30:00Z","startsAtLocal":"2026-11-09T14:30:00-05:00","endsAtLocal":"2026-11-09T15:30:00-05:00","timezone":"America/New_York","isAllDay":false,"status":"confirmed","visibility":null,"attendees":[{"email":"casey.nguyen@example.com","name":"Casey Nguyen","response":"accepted","optional":false,"isOrganizer":false},{"email":"drew.okafor@example.com","name":"Drew Okafor","response":"needsAction","optional":false,"isOrganizer":false}],"rooms":[],"organizer":{"email":"{{calendar.google.primary}}","name":"Avery Brooks"},"conferencing":{"provider":"meet","joinUrl":"https://meet.google.com/slk-zsog-xml","meetingId":"slk-zsog-xml","passcode":null,"dialIn":[{"label":"+1 555-0100","number":"+1-555-0100","pin":"478462722"}]},"meetingUrl":"https://meet.google.com/slk-zsog-xml","recurrence":null,"series":null,"reminders":[],"attachments":[{"url":"https://docs.google.com/document/d/{{attachment.google.agenda}}/edit","title":"Kickoff agenda","mimeType":"application/vnd.google-apps.document"}],"showAs":"busy","eventType":"default","color":null,"guests":{"canModify":false,"canInviteOthers":true,"canSeeGuests":true,"canProposeTimes":true},"importance":null,"categories":[],"responseRequested":null,"autoDecline":null,"doNotDisturb":null,"workingLocation":null,"birthday":null,"source":null,"endTimeUnspecified":null,"privateCopy":null,"createdAt":"2026-11-08T20:00:24.212Z","updatedAt":"2026-11-08T20:00:24.680Z","version":"\"2\"","provider":"google","providerRefs":{"eventId":"{{event.google.kickoff}}","calendarId":"{{calendar.google.primary}}","accountId":"{{account.google}}"},"metadata":null}},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`CONNECTION_NOT_FOUND`: No connected account was found for this request.\n\n`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/sandbox/simulate-meeting":{"post":{"operationId":"sandbox.simulateMeeting","summary":"Simulate a Zoom meeting event","description":"Simulates a Zoom event for a meeting made with the simulated Zoom account, as Zoom would report it: the meeting of a sandbox event (send `eventId`), or one made with `POST /v2/meetings` (send `meetingId`, with the Zoom account as `accountId`). The meeting can start or end, a participant can join or leave, its recording can become ready, or it can be updated or deleted in Zoom. The matching webhook, such as `meeting.started` or `recording.ready`, is sent as it would be for a real Zoom account.\n\n**In the sandbox:** Then check for the `recording.ready` webhook in `GET /v2/webhooks/deliveries` (the sandbox inbox) or in the relay.","tags":["Sandbox"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":128,"description":"The calendar account the event is on. For a meeting made with `POST /v2/meetings`, the Zoom account."},"eventId":{"type":"string","minLength":1,"maxLength":1024,"description":"An event with a Zoom meeting created by the sandbox's Zoom account."},"meetingId":{"type":"string","minLength":1,"maxLength":32,"description":"Instead of `eventId`: a meeting made with `POST /v2/meetings` and the sandbox's Zoom account."},"what":{"type":"string","enum":["started","ended","participant_joined","participant_left","recording_ready","updated","deleted"]}},"required":["accountId","what"],"additionalProperties":false},"example":{"accountId":"{{account.avery}}","eventId":"{{event.avery.zoomcall}}","what":"recording_ready"}}}},"responses":{"200":{"description":"The simulated event and the meeting it applies to.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"what":{"type":"string"},"meetingId":{"type":"string"},"told":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The number of apps notified. `1` means your app was notified."}},"required":["what","meetingId","told"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"what":"recording_ready","meetingId":"67556028668","told":1},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/sandbox/simulate-reply":{"post":{"operationId":"sandbox.simulateReply","summary":"Simulate an invitation response","description":"Simulates an attendee of a sandbox event on a virtual calendar responding to its invitation by email, as their calendar app would. The response can be `accepted`, `declined` or `tentative`, with a comment and, optionally, a proposed alternative time. Pyas records the response on the attendee and sends `invitation.replied` and `event.updated`, as it would for a real reply.\n\n**In the sandbox:** Then check for `invitation.replied` in `GET /v2/webhooks/deliveries` (the sandbox inbox), and check the attendee's response on the event.","tags":["Sandbox"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":128,"description":"A virtual account in the sandbox."},"eventId":{"type":"string","minLength":1,"maxLength":1024},"email":{"type":"string","minLength":1,"maxLength":320,"description":"The email address of an attendee of the event."},"response":{"type":"string","enum":["accepted","declined","tentative"]},"comment":{"type":"string","minLength":1,"maxLength":2000},"proposedTime":{"type":"object","properties":{"startsAt":{"type":"string","minLength":1,"maxLength":40},"endsAt":{"type":"string","minLength":1,"maxLength":40}},"required":["startsAt","endsAt"],"additionalProperties":false}},"required":["accountId","eventId","email","response"],"additionalProperties":false},"example":{"accountId":"{{account.avery}}","eventId":"{{event.avery.design}}","email":"teammate2.1@example.com","response":"tentative","comment":"Could we start at 3:30?","proposedTime":{"startsAt":"{{in.1d.15:30}}","endsAt":"{{in.1d.16:30}}"}}}}},"responses":{"200":{"description":"The response was recorded.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"recorded":{"type":"boolean","const":true},"eventId":{"type":"string"}},"required":["recorded","eventId"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"recorded":true,"eventId":"{{event.avery.design}}"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/usage":{"get":{"operationId":"usage.get","summary":"Get usage by day","description":"Returns your organization's requests per day on v1, v2 and test keys, the share of requests made to v2, and the busiest endpoints. Usage is counted every 10 seconds, so today's figures can be up to 10 seconds behind.","tags":["Usage"],"security":[{"ApiKey":[]}],"parameters":[{"name":"from","in":"query","required":false,"description":"The first day (UTC), such as 2026-10-01.","schema":{"type":"string","minLength":1,"maxLength":10,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","format":"date"}},{"name":"to","in":"query","required":false,"description":"The last day (UTC), such as 2026-10-01.","schema":{"type":"string","minLength":1,"maxLength":10,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","format":"date"}},{"name":"appId","in":"query","required":false,"description":"Returns usage for this app only.","schema":{"type":"string","minLength":1,"maxLength":128}}],"responses":{"200":{"description":"Usage for the requested days. Defaults to the last 30 days, and covers at most 92 days.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Usage"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"additionalProperties":false}}},"example":{"success":true,"data":{"totals":{"v1":0,"v2":0,"test":0},"v2Share":null,"days":[],"topEndpoints":[]},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"from":"2026-10-10","to":"2026-11-08"}}}}},"400":{"description":"`VALIDATION_INVALID_QUERY`: A query parameter is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks":{"get":{"operationId":"webhooks.list","summary":"List webhook endpoints","description":"Returns the app's webhook endpoints. A live key returns live endpoints, and a test key returns test endpoints, which receive events from the sandbox. Endpoints created in the dashboard before v2 are included too, and use v1 payloads until you switch them.\n\n**In the sandbox:** A test key lists test endpoints, which receive events from the sandbox. Every sandbox includes the sandbox inbox ({{webhook.inbox}}), an endpoint hosted by Pyas.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"responses":{"200":{"description":"The endpoints.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[{"webhookId":"{{webhook.inbox}}","url":"pyas://sandbox-inbox","description":"The sandbox inbox, an endpoint hosted by Pyas that receives every sandbox event. To read what it received, call GET /v2/webhooks/deliveries.","mode":"test","payloadVersion":"v2","events":["*"],"triggers":[],"status":"active","disabledReason":null,"disabledAt":null,"auth":null,"signingSecret":{"last4":"9286"},"consecutiveFailures":0,"createdAt":"2026-11-08T20:00:24.351Z","updatedAt":"2026-11-08T20:00:24.351Z"}],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"webhooks.create","summary":"Create a webhook endpoint","description":"Creates a webhook endpoint. Pyas sends each event the endpoint subscribes to as a POST request, signed in the `Pyas-Signature` header with the signing secret returned in this response. Store the secret. You can retrieve it again later with `GET /v2/webhooks/:webhookId/secret`. To check that your endpoint works, send it a test delivery with `POST /v2/webhooks/:webhookId/test`.\n\n**In the sandbox:** The response includes the signing secret. Next, send the endpoint a test delivery with `POST /v2/webhooks/{webhookId}/test`.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"The URL of your endpoint. Must use HTTPS, except for test endpoints, which also accept HTTP."},"events":{"description":"The event types to receive. Defaults to `[\"*\"]`, which subscribes to all types, including types added later.","maxItems":50,"type":"array","items":{"type":"string","maxLength":64}},"description":{"anyOf":[{"type":"string","minLength":1,"maxLength":500},{"type":"null"}]},"auth":{"description":"A credential Pyas sends with every delivery, either as a custom header or as a bearer token.","anyOf":[{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"header"},"name":{"type":"string","minLength":1,"maxLength":100},"value":{"type":"string","minLength":1,"maxLength":4096}},"required":["type","name","value"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"bearer"},"token":{"type":"string","minLength":1,"maxLength":4096}},"required":["type","token"],"additionalProperties":false}]},{"type":"null"}]},"payloadVersion":{"type":"string","enum":["v2"]}},"required":["url"],"additionalProperties":false},"example":{"url":"https://example.com/pyas/webhooks","events":["event.*","connection.broken"],"description":"Calendar sync","auth":{"type":"header","name":"X-Webhook-Key","value":"my-shared-secret"}}}}},"responses":{"201":{"description":"The endpoint and its signing secret, returned in full.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"signingSecret":{"type":"string"}},"required":["endpoint","signingSecret"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"endpoint":{"webhookId":"004af03b-0f03-4e97-91df-852da33048d9","url":"https://example.com/pyas/webhooks","description":"Calendar sync","mode":"test","payloadVersion":"v2","events":["event.*","connection.broken"],"triggers":[],"status":"active","disabledReason":null,"disabledAt":null,"auth":{"type":"header","name":"X-Webhook-Key"},"signingSecret":{"last4":"Wazs"},"consecutiveFailures":0,"createdAt":"2026-11-08T20:00:25.699Z","updatedAt":"2026-11-08T20:00:25.699Z"},"signingSecret":"whsec_example"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`BILLING_FEATURE_UNAVAILABLE`: This feature is not included in the current plan.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_LIMIT_REACHED`: The limit for this resource has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/{webhookId}":{"delete":{"operationId":"webhooks.delete","summary":"Delete a webhook endpoint","description":"Deletes the endpoint. Pyas stops sending deliveries to it, and its deliveries remain available for 30 days.\n\n**In the sandbox:** This deletes the sandbox inbox. `POST /v2/sandbox/reset` creates it again.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"null"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":null,"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"webhooks.get","summary":"Get a webhook endpoint","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"}],"responses":{"200":{"description":"The endpoint.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/WebhookEndpoint"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"webhookId":"{{webhook.inbox}}","url":"pyas://sandbox-inbox","description":"The sandbox inbox, an endpoint hosted by Pyas that receives every sandbox event. To read what it received, call GET /v2/webhooks/deliveries.","mode":"test","payloadVersion":"v2","events":["*"],"triggers":[],"status":"active","disabledReason":null,"disabledAt":null,"auth":null,"signingSecret":{"last4":"9286"},"consecutiveFailures":0,"createdAt":"2026-11-08T20:00:24.351Z","updatedAt":"2026-11-08T20:00:24.351Z"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"webhooks.update","summary":"Update a webhook endpoint","description":"Updates the endpoint's URL, events, credential or description. You can also disable or re-enable it with `status`. Before re-enabling an endpoint, Pyas sends it a test delivery, and the endpoint stays disabled if that delivery fails. To switch an endpoint created before v2 to v2 payloads, set `payloadVersion` to `\"v2\"`. After the switch, v1 no longer sends the endpoint anything, and it receives signed, retried v2 deliveries of the event types that its v1 triggers correspond to, unless you set `events`. The first time an endpoint switches, a signing secret is created and returned in this response.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"events":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":64}},"description":{"anyOf":[{"type":"string","minLength":1,"maxLength":500},{"type":"null"}]},"auth":{"description":"A new credential, or `null` to remove it.","anyOf":[{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"header"},"name":{"type":"string","minLength":1,"maxLength":100},"value":{"type":"string","minLength":1,"maxLength":4096}},"required":["type","name","value"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"bearer"},"token":{"type":"string","minLength":1,"maxLength":4096}},"required":["type","token"],"additionalProperties":false}]},{"type":"null"}]},"status":{"type":"string","enum":["active","disabled"]},"payloadVersion":{"type":"string","enum":["v1","v2"]}},"additionalProperties":false},"example":{"events":["event.*","calendar.*"],"description":"Sandbox inbox: events and calendars"}}}},"responses":{"200":{"description":"The endpoint, and its new signing secret if one was created.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"signingSecret":{"type":"string"}},"required":["endpoint"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"endpoint":{"webhookId":"{{webhook.inbox}}","url":"pyas://sandbox-inbox","description":"Sandbox inbox: events and calendars","mode":"test","payloadVersion":"v2","events":["event.*","calendar.*"],"triggers":[],"status":"active","disabledReason":null,"disabledAt":null,"auth":null,"signingSecret":{"last4":"E2vA"},"consecutiveFailures":0,"createdAt":"2026-11-08T20:00:25.476Z","updatedAt":"2026-11-08T20:00:25.767Z"}},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`VALIDATION_ENDPOINT_UNREACHABLE`: The webhook endpoint did not accept a test delivery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/{webhookId}/replay":{"post":{"operationId":"webhooks.replay","summary":"Replay failed webhook deliveries","description":"Replays the deliveries to this endpoint that failed after every attempt, starting from the given time. Each request replays at most 1000 deliveries.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"since":{"type":"string","minLength":1,"maxLength":40,"description":"An ISO 8601 time. Replays failed deliveries created at or after this time."}},"required":["since"],"additionalProperties":false},"example":{"since":"{{in.-1d}}"}}}},"responses":{"202":{"description":"The number of deliveries queued again.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"replayed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["replayed"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"replayed":0},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/{webhookId}/secret":{"get":{"operationId":"webhooks.secret.get","summary":"Retrieve the signing secret","description":"Returns the secret that deliveries are signed with and, after a rotation, when the previous secret stops signing. Requires a key with the write scope.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"}],"responses":{"200":{"description":"The secret.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"signingSecret":{"type":"string"},"previous":{"anyOf":[{"type":"object","properties":{"expiresAt":{"type":"string"}},"required":["expiresAt"],"additionalProperties":false},{"type":"null"}]}},"required":["signingSecret","previous"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"signingSecret":"whsec_example","previous":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/{webhookId}/secret/rotate":{"post":{"operationId":"webhooks.secret.rotate","summary":"Rotate the signing secret","description":"Creates a new signing secret. The previous secret keeps signing deliveries alongside the new one for `graceHours` (default 24, at most 168), so you can update your endpoint without rejecting any deliveries.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"graceHours":{"type":"integer","minimum":0,"maximum":168}},"additionalProperties":false},"example":{"graceHours":24}}}},"responses":{"200":{"description":"The new secret.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"signingSecret":{"type":"string"},"previous":{"anyOf":[{"type":"object","properties":{"expiresAt":{"type":"string"}},"required":["expiresAt"],"additionalProperties":false},{"type":"null"}]}},"required":["signingSecret","previous"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"signingSecret":"whsec_example","previous":{"expiresAt":"2026-11-09T20:00:25.724Z"}},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/{webhookId}/test":{"post":{"operationId":"webhooks.test","summary":"Send a test delivery","description":"Sends a sample of any event type to the endpoint immediately, signed like a real delivery, and returns the result. The result includes your endpoint's status code, its response body, the time it took, and exactly what was sent, with your own credential hidden. Test deliveries are not retried, don't count against the endpoint, are marked `\"test\": true`, and are left out of the event list. You can test an endpoint while it is disabled.\n\n**In the sandbox:** You can send any event type. Your handler receives a realistic sample, signed like a real delivery, and the response shows how your endpoint responded.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","minLength":1,"maxLength":64,"description":"The event type to send a sample of. Defaults to `webhook.ping`."}},"additionalProperties":false},"example":{"type":"event.updated"}}}},"responses":{"200":{"description":"The result. `delivered` is `false` when your endpoint did not respond with a 2xx status.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"object","properties":{"delivered":{"type":"boolean"},"delivery":{"$ref":"#/components/schemas/WebhookDelivery"},"sent":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"body":{"type":"string"}},"required":["url","headers","body"],"additionalProperties":false},{"type":"null"}]}},"required":["delivered","delivery","sent"],"additionalProperties":false},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"delivered":true,"delivery":{"deliveryId":"del_v2dH4f5ag8CB77OT1WBx","webhookId":"{{webhook.inbox}}","eventId":"evt_7yChTM94C793nCcM9697","eventType":"event.updated","accountId":null,"status":"delivered","attempts":[{"n":1,"at":"2026-11-08T20:00:25Z","httpStatus":200,"responseBody":"{\"received\":true,\"by\":\"the Pyas sandbox inbox\"}","responseTimeMs":0,"error":null}],"nextAttemptAt":null,"replays":0,"createdAt":"2026-11-08T20:00:25Z","completedAt":"2026-11-08T20:00:25Z"},"sent":{"url":"pyas://sandbox-inbox","headers":{"Content-Type":"application/json","User-Agent":"Pyas-Webhooks/2","Pyas-Event-Id":"evt_7yChTM94C793nCcM9697","Pyas-Event-Type":"event.updated","Pyas-Delivery-Id":"del_v2dH4f5ag8CB77OT1WBx","Pyas-Timestamp":"1794168025","Pyas-Signature":"t=1794168025,v1=3c070b14da751b2be2c4d1a452b6e588894caeb651fbacdd8650f467dded1091"},"body":"{\"id\":\"evt_7yChTM94C793nCcM9697\",\"type\":\"event.updated\",\"apiVersion\":\"2\",\"createdAt\":\"2026-11-08T20:00:25Z\",\"livemode\":false,\"appId\":\"5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365\",\"accountId\":null,\"subjectId\":null,\"provider\":null,\"data\":{\"object\":{\"id\":\"sample1a2b3c4d5e6f7g8h9i\",\"calendarId\":\"primary\",\"seriesId\":null,\"isSeries\":false}},\"request\":null,\"test\":true}"}},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"400":{"description":"`VALIDATION_INVALID_BODY`: The request body is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/deliveries":{"get":{"operationId":"webhooks.deliveries.list","summary":"List webhook deliveries","description":"Returns deliveries from the last 30 days, newest first. Each delivery includes every attempt, with its status code, the first 1 KB of the response body, the time taken and any error. Use `status=failed` to list the dead-letter queue, which holds the deliveries that failed after every attempt.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"webhookId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhook.inbox}}"},{"name":"status","in":"query","required":false,"description":"Returns only deliveries with this status.","schema":{"type":"string","enum":["pending","retrying","delivered","failed"]}},{"name":"eventType","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"eventId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"since","in":"query","required":false,"description":"An ISO 8601 time with a zone.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"}},{"name":"limit","in":"query","required":false,"description":"The maximum number of results in one page.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","minLength":1,"maxLength":2048}}],"responses":{"200":{"description":"The deliveries.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[{"deliveryId":"{{delivery.inbox}}","webhookId":"{{webhook.inbox}}","eventId":"{{webhookEvent.inbox}}","eventType":"webhook.ping","accountId":null,"status":"delivered","attempts":[{"n":1,"at":"2026-11-08T20:00:23Z","httpStatus":200,"responseBody":"{\"received\":true,\"by\":\"the Pyas sandbox inbox\"}","responseTimeMs":0,"error":null}],"nextAttemptAt":null,"replays":0,"createdAt":"2026-11-08T20:00:23Z","completedAt":"2026-11-08T20:00:23Z"}],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/deliveries/{deliveryId}":{"get":{"operationId":"webhooks.deliveries.get","summary":"Get a webhook delivery","description":"Returns one delivery, including every attempt.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{delivery.inbox}}"}],"responses":{"200":{"description":"The delivery.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/WebhookDelivery"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"deliveryId":"{{delivery.inbox}}","webhookId":"{{webhook.inbox}}","eventId":"{{webhookEvent.inbox}}","eventType":"webhook.ping","accountId":null,"status":"delivered","attempts":[{"n":1,"at":"2026-11-08T20:00:23Z","httpStatus":200,"responseBody":"{\"received\":true,\"by\":\"the Pyas sandbox inbox\"}","responseTimeMs":0,"error":null}],"nextAttemptAt":null,"replays":0,"createdAt":"2026-11-08T20:00:23Z","completedAt":"2026-11-08T20:00:23Z"},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/deliveries/{deliveryId}/replay":{"post":{"operationId":"webhooks.deliveries.replay","summary":"Replay a webhook delivery","description":"Replays the delivery with a new series of attempts, sending the same event with the same body and `Pyas-Event-Id`. You can also replay a delivery that succeeded, for example if your endpoint lost it.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{delivery.inbox}}"},{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key that makes the request safe to retry. A retry with the same key returns the original response and does not make the change twice. Keys are kept for 24 hours.","schema":{"type":"string"}}],"responses":{"202":{"description":"The delivery, queued again.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/WebhookDelivery"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"deliveryId":"{{delivery.inbox}}","webhookId":"{{webhook.inbox}}","eventId":"{{webhookEvent.inbox}}","eventType":"webhook.ping","accountId":null,"status":"pending","attempts":[{"n":1,"at":"2026-11-08T20:00:24Z","httpStatus":200,"responseBody":"{\"received\":true,\"by\":\"the Pyas sandbox inbox\"}","responseTimeMs":0,"error":null}],"nextAttemptAt":"2026-11-08T20:00:25Z","replays":1,"createdAt":"2026-11-08T20:00:24Z","completedAt":null},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_CONFLICT`: The resource was modified or already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/event-types":{"get":{"operationId":"webhooks.eventTypes","summary":"List webhook event types","description":"Returns every event type, a description of what it means, and a sample of the `data` object that a delivery of that type includes.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"responses":{"200":{"description":"The event types.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"description":{"type":"string"},"sample":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A sample of the `data` object in a delivery of this type."}},"required":["type","description","sample"],"additionalProperties":false}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":[{"type":"connection.created","description":"An account was connected for the first time. `data.object` is the account.","sample":{"object":{"accountId":"acc_sample","provider":"google","email":"{{calendar.google.primary}}","name":"Avery Brooks","status":"active","subjectId":"user_123","scopes":["https://www.googleapis.com/auth/calendar"],"createdAt":"2026-10-09T20:00:24Z","updatedAt":"2026-11-08T20:00:24Z"}}},{"type":"connection.reauthorized","description":"An account was connected again, after it stopped working or to grant more permissions. `data.object` is the account.","sample":{"object":{"accountId":"acc_sample","provider":"google","email":"{{calendar.google.primary}}","name":"Avery Brooks","status":"active","subjectId":"user_123","scopes":["https://www.googleapis.com/auth/calendar"],"createdAt":"2026-10-09T20:00:24Z","updatedAt":"2026-11-08T20:00:24Z"}}},{"type":"connection.broken","description":"An account stopped working because access was revoked or could not be renewed. The user needs to connect it again. `data.object` is the account.","sample":{"object":{"accountId":"acc_sample","provider":"google","email":"{{calendar.google.primary}}","name":"Avery Brooks","status":"inactive","subjectId":"user_123","scopes":["https://www.googleapis.com/auth/calendar"],"createdAt":"2026-10-09T20:00:24Z","updatedAt":"2026-11-08T20:00:24Z"}}},{"type":"connection.deleted","description":"An account was deleted from Pyas. `data.object` is the account as it was before it was deleted.","sample":{"object":{"accountId":"acc_sample","provider":"google","email":"{{calendar.google.primary}}","name":"Avery Brooks","status":"active","subjectId":"user_123","scopes":["https://www.googleapis.com/auth/calendar"],"createdAt":"2026-10-09T20:00:24Z","updatedAt":"2026-11-08T20:00:24Z"}}},{"type":"calendar.created","description":"A calendar was added to an account. `data.object` holds the calendar ID.","sample":{"object":{"id":"team@group.calendar.google.com"}}},{"type":"calendar.updated","description":"A calendar was updated, for example its name, color or time zone. `data.object` holds the calendar ID. Read the calendar to get its new details.","sample":{"object":{"id":"team@group.calendar.google.com"}}},{"type":"calendar.deleted","description":"A calendar was removed from an account. `data.object` holds the calendar ID.","sample":{"object":{"id":"team@group.calendar.google.com"}}},{"type":"event.created","description":"An event was created. A new recurring series sends one webhook for the series. `data.object` holds the event ID and calendar ID. Read the event to get its details.","sample":{"object":{"id":"sample1a2b3c4d5e6f7g8h9i","calendarId":"primary","seriesId":null,"isSeries":false}}},{"type":"event.updated","description":"An event was updated. An update to a whole series sends one webhook for the series. `data.object` holds the event ID and calendar ID. Read the event to get its new details.","sample":{"object":{"id":"sample1a2b3c4d5e6f7g8h9i","calendarId":"primary","seriesId":null,"isSeries":false}}},{"type":"event.deleted","description":"An event was deleted or canceled. `data.object` holds the event ID and calendar ID.","sample":{"object":{"id":"sample1a2b3c4d5e6f7g8h9i","calendarId":"primary","seriesId":null,"isSeries":false}}},{"type":"invitation.replied","description":"An attendee responded to an invitation sent from a virtual calendar. `data.object` holds the event ID and calendar ID, and `data.reply` is the response.","sample":{"object":{"id":"sample1a2b3c4d5e6f7g8h9i","calendarId":"primary","seriesId":null,"isSeries":false},"reply":{"email":"sam.patel@example.org","response":"tentative","comment":"Running late from another meeting.","proposedTime":null}}},{"type":"meeting.updated","description":"A Zoom meeting that Pyas created for an event was updated in Zoom. `data.object` is the meeting and the event it belongs to, and `data.previous` contains the previous values. Pyas doesn't update the calendar event. Update the event yourself if you want it to match.","sample":{"object":{"meetingId":"84512345678","uuid":"SnJ2bYn7QnWqUj3sSvKQ5A==","topic":"Customer onboarding","startsAt":"2026-11-09T21:00:00Z","durationMinutes":60,"timezone":"America/New_York","eventId":"sample1a2b3c4d5e6f7g8h9i","calendarRef":"primary","accountId":"acc_sample","zoomAccountId":"acc_zoom_sample"},"previous":{"startsAt":"2026-11-09T20:00:00Z"}}},{"type":"meeting.deleted","description":"A Zoom meeting that Pyas created for an event was deleted in Zoom, so the event's join link no longer works. `data.object` is the meeting and its event.","sample":{"object":{"meetingId":"84512345678","uuid":"SnJ2bYn7QnWqUj3sSvKQ5A==","topic":"Customer onboarding","startsAt":"2026-11-09T21:00:00Z","durationMinutes":60,"timezone":"America/New_York","eventId":"sample1a2b3c4d5e6f7g8h9i","calendarRef":"primary","accountId":"acc_sample","zoomAccountId":"acc_zoom_sample"}}},{"type":"meeting.started","description":"A Zoom meeting that Pyas created for an event started. `data.object` is the meeting and its event.","sample":{"object":{"meetingId":"84512345678","uuid":"SnJ2bYn7QnWqUj3sSvKQ5A==","topic":"Customer onboarding","startsAt":"2026-11-09T21:00:00Z","durationMinutes":60,"timezone":"America/New_York","eventId":"sample1a2b3c4d5e6f7g8h9i","calendarRef":"primary","accountId":"acc_sample","zoomAccountId":"acc_zoom_sample","startedAt":"2026-11-08T20:00:24Z"}}},{"type":"meeting.ended","description":"A Zoom meeting that Pyas created for an event ended. `data.object` is the meeting and its event, with `startedAt` and `endedAt`.","sample":{"object":{"meetingId":"84512345678","uuid":"SnJ2bYn7QnWqUj3sSvKQ5A==","topic":"Customer onboarding","startsAt":"2026-11-09T21:00:00Z","durationMinutes":60,"timezone":"America/New_York","eventId":"sample1a2b3c4d5e6f7g8h9i","calendarRef":"primary","accountId":"acc_sample","zoomAccountId":"acc_zoom_sample","startedAt":"2026-11-08T19:05:24Z","endedAt":"2026-11-08T20:00:24Z"}}},{"type":"meeting.participant_joined","description":"A participant joined a Zoom meeting that Pyas created for an event. `data.participant` identifies the participant.","sample":{"object":{"meetingId":"84512345678","uuid":"SnJ2bYn7QnWqUj3sSvKQ5A==","topic":"Customer onboarding","startsAt":"2026-11-09T21:00:00Z","durationMinutes":60,"timezone":"America/New_York","eventId":"sample1a2b3c4d5e6f7g8h9i","calendarRef":"primary","accountId":"acc_sample","zoomAccountId":"acc_zoom_sample"},"participant":{"name":"Sam Patel","email":"sam.patel@example.org","joinedAt":"2026-11-08T20:00:24Z"}}},{"type":"meeting.participant_left","description":"A participant left a Zoom meeting that Pyas created for an event. `data.participant` identifies the participant.","sample":{"object":{"meetingId":"84512345678","uuid":"SnJ2bYn7QnWqUj3sSvKQ5A==","topic":"Customer onboarding","startsAt":"2026-11-09T21:00:00Z","durationMinutes":60,"timezone":"America/New_York","eventId":"sample1a2b3c4d5e6f7g8h9i","calendarRef":"primary","accountId":"acc_sample","zoomAccountId":"acc_zoom_sample"},"participant":{"name":"Sam Patel","email":"sam.patel@example.org","leftAt":"2026-11-08T20:00:24Z"}}},{"type":"recording.ready","description":"The cloud recording of a Zoom meeting that Pyas created for an event is ready. `data.object` lists the recording files with their type, size, start and end times, and share link.","sample":{"object":{"meetingId":"84512345678","uuid":"SnJ2bYn7QnWqUj3sSvKQ5A==","topic":"Customer onboarding","startsAt":"2026-11-09T21:00:00Z","durationMinutes":60,"timezone":"America/New_York","eventId":"sample1a2b3c4d5e6f7g8h9i","calendarRef":"primary","accountId":"acc_sample","zoomAccountId":"acc_zoom_sample","shareUrl":"https://zoom.us/rec/share/sample","files":[{"id":"rec-1","type":"shared_screen_with_speaker_view","fileType":"MP4","sizeBytes":48213002,"startedAt":"2026-11-08T19:05:24Z","endedAt":"2026-11-08T20:00:24Z","playUrl":"https://zoom.us/rec/play/sample"},{"id":"rec-2","type":"audio_transcript","fileType":"TRANSCRIPT","sizeBytes":18204,"startedAt":"2026-11-08T19:05:24Z","endedAt":"2026-11-08T20:00:24Z","playUrl":null}]}}},{"type":"api_key.expiring","description":"An API key expires soon. Sent a week before the key's expiry date, or an hour before a rotated key's grace period ends. `data.object` is the key, without its secret value.","sample":{"object":{"keyId":"key_sample","name":"production","mode":"live","expiresAt":"2026-11-08T21:00:24Z","rotatedTo":"key_sample2"}}},{"type":"api_key.revoked","description":"A rotated API key's grace period ended, and the key no longer works. `data.object` is the key.","sample":{"object":{"keyId":"key_sample","name":"production","mode":"live","expiresAt":"2026-11-08T20:00:24Z","rotatedTo":"key_sample2"}}},{"type":"webhook.ping","description":"A test delivery. Pyas sends it when you request one and when an endpoint is enabled again.","sample":{"object":{"message":"A test delivery from Pyas."}}}],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/events":{"get":{"operationId":"webhooks.events.list","summary":"List webhook events","description":"Returns events from the last 30 days, newest first, whether or not an endpoint received them. Use it to catch up after downtime or to check what happened. A test key returns the sandbox's events.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"type","in":"query","required":false,"description":"An event type, or a family such as `event.*`.","schema":{"type":"string","minLength":1,"maxLength":64},"example":"webhook.ping"},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"since","in":"query","required":false,"description":"Returns only events created at or after this time.","schema":{"format":"date-time","type":"string","maxLength":64,"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:?\\d{2})$"}},{"name":"limit","in":"query","required":false,"description":"The maximum number of results in one page.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` from the previous page.","schema":{"type":"string","minLength":1,"maxLength":2048}}],"responses":{"200":{"description":"The events.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object","properties":{"nextCursor":{"type":["string","null"]}},"required":["nextCursor"],"additionalProperties":false}}},"example":{"success":true,"data":[{"eventId":"{{webhookEvent.inbox}}","type":"webhook.ping","accountId":null,"subjectId":null,"provider":null,"createdAt":"2026-11-08T20:00:23Z","payload":{"id":"{{webhookEvent.inbox}}","type":"webhook.ping","apiVersion":"2","createdAt":"2026-11-08T20:00:23Z","livemode":false,"appId":"5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365","accountId":null,"subjectId":null,"provider":null,"data":{"object":{"message":"The sandbox inbox is ready."}},"request":null}}],"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{"nextCursor":null}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/events/{eventId}":{"get":{"operationId":"webhooks.events.get","summary":"Get a webhook event","description":"Returns one event and its payload, exactly as delivered.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64},"example":"{{webhookEvent.inbox}}"}],"responses":{"200":{"description":"The event.","content":{"application/json":{"schema":{"type":"object","required":["success","data","provider","traceId","meta"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/WebhookEvent"},"provider":{"type":["string","null"],"description":"The provider that handled the request (`google`, `microsoft`, `zoom` or `pyas`), if any."},"traceId":{"type":"string","description":"The request's trace ID. Include it when you contact support, so the request can be found in the logs."},"meta":{"type":"object"}}},"example":{"success":true,"data":{"eventId":"{{webhookEvent.inbox}}","type":"webhook.ping","accountId":null,"subjectId":null,"provider":null,"createdAt":"2026-11-08T20:00:23Z","payload":{"id":"{{webhookEvent.inbox}}","type":"webhook.ping","apiVersion":"2","createdAt":"2026-11-08T20:00:23Z","livemode":false,"appId":"5c1e9a47-2d3b-4f86-a0e9-7b4c2d18f365","accountId":null,"subjectId":null,"provider":null,"data":{"object":{"message":"The sandbox inbox is ready."}},"request":null}},"provider":null,"traceId":"trc_5f2a9c1e7b3d4a6f8e0c2b1d","meta":{}}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`RESOURCE_NOT_FOUND`: The calendar or event was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/webhooks/listen":{"get":{"operationId":"webhooks.listen","summary":"Stream sandbox webhook events","description":"Opens a Server-Sent Events stream of the sandbox's events as they happen, so you can receive webhooks on a machine with no public endpoint. Requires a test key. The stream starts with an `event: ready` message that includes a signing secret created for this stream. Each `event: delivery` message that follows includes a body and the same headers as a real delivery, signed with that secret. POST each one to your local handler to run it exactly as in production. The `pyas webhooks listen --forward` command does this for you. A stream stays open for 1 hour, and an app can have at most 5 streams open at a time.\n\n**In the sandbox:** The stream stays open. In a terminal, run `curl -N -H \"x-api-key: <test key>\" https://api.pyas.io/v2/webhooks/listen`, then create or update an event in the sandbox.","tags":["Webhooks"],"security":[{"ApiKey":[]}],"parameters":[{"name":"events","in":"query","required":false,"description":"A comma-separated list of event types to relay. Accepts `*` (the default) or a family such as `event.*`.","schema":{"type":"string","minLength":1,"maxLength":1024},"example":"event.*,connection.*"}],"responses":{"200":{"description":"The event stream (`text/event-stream`).","content":{"text/event-stream":{"schema":{"type":"string"}}}},"401":{"description":"`AUTH_INVALID_KEY`: The API key is missing, unknown or revoked.\n\n`AUTH_EXPIRED_KEY`: The API key has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`AUTH_SANDBOX_MISMATCH`: A test key was used with live data, or a live key was used with sandbox data.\n\n`AUTH_INSUFFICIENT_SCOPE`: The API key or session does not have permission to make this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`RESOURCE_LIMIT_REACHED`: The limit for this resource has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMIT_EXCEEDED`: The request rate exceeds this plan's rate limit.\n\n`RATE_LIMIT_BURST`: Too many requests were sent in a short period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"`INTERNAL_ERROR`: Something went wrong on our end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your app's API key. Live keys start with `pyas_sk_`, and test keys start with `pyas_sk_test_`."}},"schemas":{"Error":{"type":"object","description":"The response body of every v2 error. `code` is stable, so base your error handling on `code` rather than on `message`.","required":["success","error"],"properties":{"success":{"const":false},"error":{"type":"object","required":["code","message","hint","status","traceId","docs"],"properties":{"code":{"type":"string","enum":["AUTH_INVALID_KEY","AUTH_EXPIRED_KEY","AUTH_INVALID_SESSION","AUTH_EXPIRED_SESSION","AUTH_INSUFFICIENT_SCOPE","AUTH_KEY_IN_BROWSER","AUTH_SANDBOX_MISMATCH","AUTH_INVALID_CONNECT_SESSION","AUTH_ORIGIN_NOT_ALLOWED","CONNECTION_NOT_FOUND","CONNECTION_TOKEN_EXPIRED","CONNECTION_SCOPE_INSUFFICIENT","CONNECTION_REVOKED","CONNECTION_PROVIDER_NOT_CONFIGURED","CONNECTION_CONSENT_FAILED","PROVIDER_RATE_LIMITED","PROVIDER_UNAVAILABLE","PROVIDER_TIMEOUT","PROVIDER_PARTIAL_SUCCESS","PROVIDER_UNKNOWN_ERROR","VALIDATION_INVALID_BODY","VALIDATION_INVALID_QUERY","VALIDATION_INVALID_TIMEZONE","VALIDATION_PAYLOAD_TOO_LARGE","VALIDATION_IDEMPOTENCY_CONFLICT","VALIDATION_REJECTED_BY_PROVIDER","VALIDATION_UNSUPPORTED_OPERATION","VALIDATION_ENDPOINT_UNREACHABLE","RESOURCE_NOT_FOUND","RESOURCE_SYNC_TOKEN_EXPIRED","RESOURCE_CONFLICT","RESOURCE_LIMIT_REACHED","RATE_LIMIT_EXCEEDED","RATE_LIMIT_BURST","RATE_MONTHLY_QUOTA_EXCEEDED","BILLING_SUBSCRIPTION_REQUIRED","BILLING_CONNECTION_LIMIT","BILLING_FEATURE_UNAVAILABLE","BILLING_OVERDUE","CONNECT_TIMEOUT","CONNECT_CONSENT_DENIED","CONNECT_POPUP_BLOCKED","CONNECT_CANCELLED","CONNECT_SESSION_FAILED","CONNECT_NETWORK_ERROR","CONNECT_PROVIDER_ERROR","CONNECT_INVALID_CONFIG","INTERNAL_ERROR"]},"message":{"type":"string","description":"A description of the error, written for developers."},"hint":{"type":"string","description":"How to resolve the error."},"status":{"type":"integer"},"traceId":{"type":"string"},"docs":{"type":"string","format":"uri","description":"A link to the error code's documentation, for example https://developer.pyas.io/errors/VALIDATION_INVALID_QUERY"}}}}},"Account":{"type":"object","properties":{"accountId":{"type":"string","description":"The ID Pyas assigns to the account. Use it as `accountId` in other requests."},"provider":{"$ref":"#/components/schemas/Provider"},"email":{"type":["string","null"]},"name":{"type":["string","null"]},"status":{"type":"string","enum":["active","inactive"],"description":"`inactive` means the account is disabled because the user revoked access or the account was disconnected."},"subjectId":{"description":"Your own identifier for the account, such as your user or organization ID, if set.","type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"createdAt":{"type":["string","null"]},"updatedAt":{"type":["string","null"]}},"required":["accountId","provider","email","name","status","subjectId","scopes","createdAt","updatedAt"],"additionalProperties":false},"Provider":{"type":"string","description":"The provider: `google`, `microsoft`, `zoom` or `pyas` (virtual calendars).","examples":["google"]},"AccountSettings":{"type":"object","properties":{"timezone":{"type":["string","null"]},"locale":{"type":["string","null"]},"weekStart":{"anyOf":[{"type":"string","enum":["sunday","monday","saturday"]},{"type":"null"}]},"timeFormat":{"anyOf":[{"type":"string","enum":["12h","24h"]},{"type":"null"}]},"dateOrder":{"anyOf":[{"type":"string","enum":["MDY","DMY","YMD"]},{"type":"null"}]},"defaultEventMinutes":{"type":["number","null"]},"workingHours":{"anyOf":[{"type":"object","properties":{"days":{"type":"array","items":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]}},"start":{"type":"string"},"end":{"type":"string"},"timezone":{"type":"string"}},"required":["days","start","end","timezone"],"additionalProperties":false},{"type":"null"}]}},"required":["timezone","locale","weekStart","timeFormat","dateOrder","defaultEventMinutes","workingHours"],"additionalProperties":false,"description":"A field is `null` when the provider doesn't store or expose that setting."},"AccountStatus":{"type":"object","properties":{"accountId":{"type":"string"},"provider":{"$ref":"#/components/schemas/Provider"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"subjectId":{"type":["string","null"]},"state":{"type":"string","enum":["connected","needsReconnect","disconnected"]},"health":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","broken","unknown"]},"lastSuccessAt":{"type":["string","null"]},"lastFailure":{"anyOf":[{"type":"object","properties":{"at":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"},"operation":{"type":["string","null"]}},"required":["at","code","message","operation"],"additionalProperties":false},{"type":"null"}]}},"required":["status","lastSuccessAt","lastFailure"],"additionalProperties":false},"scopes":{"type":"object","properties":{"recorded":{"type":"array","items":{"type":"string"}},"source":{"type":"string","enum":["granted","requestedAtConnect"]}},"required":["recorded","source"],"additionalProperties":false},"features":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"available":{"type":"boolean"},"missingScopes":{"type":"array","items":{"type":"string"}},"reason":{"type":"string"}},"required":["available"],"additionalProperties":false},"description":"Each v2 feature (such as `readEvents`, `writeEvents`, `sharing` and `rooms`), whether it's available, and any permissions it's missing."},"capabilities":{"anyOf":[{"$ref":"#/components/schemas/ProviderCapabilities"},{"type":"null"}]},"userMessage":{"description":"A message to show the account's owner when they need to take action.","type":["string","null"]},"fixUrl":{"type":["string","null"]},"overall":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","attention","broken"],"description":"`healthy` means no action is needed. `attention` means the account works but something is limited, such as a missing permission or a provider that is not responding reliably. `broken` means the account no longer syncs."},"reason":{"description":"The reason for the status, written for you as the developer. For a message to show the account's owner, use `userMessage`. `null` when the status is `healthy`.","type":["string","null"]},"fix":{"anyOf":[{"type":"string","enum":["reconnect"]},{"type":"null"}],"description":"`reconnect` when connecting the account again fixes the problem. To reconnect it, create a connect session with this `accountId` (`POST /v2/connect/sessions`) and open PyasConnect with it. `null` when no action is needed, or when the owner can't fix the problem."}},"required":["status","reason","fix"],"additionalProperties":false,"description":"The account's overall health, as the dashboard shows it."},"check":{"description":"Included with `check=true`. The result of a live request to the provider.","type":"object","properties":{"ok":{"type":"boolean"},"at":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}},"required":["ok","at"],"additionalProperties":false}},"required":["accountId","provider","name","email","subjectId","state","health","scopes","features","capabilities","userMessage","fixUrl","overall"],"additionalProperties":false},"ProviderCapabilities":{"type":"object","properties":{"incrementalSync":{"type":"boolean"},"freeBusy":{"type":"boolean"},"batch":{"type":"boolean"},"nativeMetadata":{"type":"boolean"},"calendarWrite":{"type":"boolean"},"maxAttachmentBytes":{"type":"number","description":"The largest file, in bytes, that `POST /v2/events/{eventId}/attachments/file` accepts."},"push":{"type":"object","properties":{"supported":{"type":"boolean"},"maxTtlSeconds":{"type":"number"}},"required":["supported","maxTtlSeconds"],"additionalProperties":false}},"required":["incrementalSync","freeBusy","batch","nativeMetadata","calendarWrite","maxAttachmentBytes","push"],"additionalProperties":false},"WorkingLocationEntry":{"type":"object","properties":{"eventId":{"type":"string"},"startsAt":{"type":"string"},"endsAt":{"type":"string"},"isAllDay":{"type":"boolean"},"location":{"$ref":"#/components/schemas/WorkingLocation"}},"required":["eventId","startsAt","endsAt","isAllDay","location"],"additionalProperties":false},"WorkingLocation":{"type":"object","properties":{"type":{"type":"string","enum":["home","office","custom"]},"label":{"type":["string","null"]},"buildingId":{"type":["string","null"]},"floorId":{"type":["string","null"]},"floorSectionId":{"type":["string","null"]},"deskId":{"type":["string","null"]}},"required":["type","label"],"additionalProperties":false},"AccountImport":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","done"]},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"counts":{"type":"object","properties":{"pending":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["pending","created","updated","failed"],"additionalProperties":false},"createdAt":{"type":"string"},"finishedAt":{"type":["string","null"]},"items":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The account's position in the request."},"provider":{"type":"string","enum":["google","microsoft","zoom"]},"subjectId":{"type":["string","null"]},"status":{"type":"string","enum":["pending","created","updated","failed"],"description":"`created` means a new account was created. `updated` means an existing account received the new tokens."},"accountId":{"type":["string","null"]},"email":{"type":["string","null"]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether `POST /v2/accounts/imports/{importId}/retry` can retry this account."}},"required":["code","message","retryable"],"additionalProperties":false},{"type":"null"}]}},"required":["index","provider","subjectId","status","accountId","email","error"],"additionalProperties":false}}},"required":["id","status","total","counts","createdAt","finishedAt","items"],"additionalProperties":false},"CalendarGroup":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"calendarIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","calendarIds"],"additionalProperties":false,"description":"An Outlook calendar group."},"Calendar":{"type":"object","properties":{"id":{"type":"string","description":"The ID that identifies the calendar in every other v2 request."},"name":{"type":"string"},"description":{"type":["string","null"]},"timezone":{"description":"The IANA time zone name.","type":["string","null"]},"isPrimary":{"type":"boolean"},"color":{"description":"The color, as `#rrggbb`.","type":["string","null"]},"accessRole":{"type":"string","enum":["owner","writer","reader"]},"location":{"description":"Google Calendar only. `null` on Outlook.","type":["string","null"]},"conferencing":{"type":"object","properties":{"default":{"description":"The meeting link type Outlook adds by default. Google Calendar has no per-calendar default.","type":["string","null"]},"allowed":{"type":"array","items":{"type":"string"},"description":"The meeting link types that events on this calendar can use, such as `meet` or `teams`."}},"required":["default","allowed"],"additionalProperties":false},"tallyResponses":{"description":"Outlook only. Whether responses are counted. `null` on Google Calendar.","type":["boolean","null"]},"hidden":{"description":"Google Calendar only. Whether the calendar is hidden from the calendar list. `null` on Outlook.","type":["boolean","null"]},"metadata":{"anyOf":[{"$ref":"#/components/schemas/Metadata"},{"type":"null"}]},"provider":{"$ref":"#/components/schemas/Provider"},"providerRefs":{"type":"object","properties":{"calendarId":{"type":"string"},"accountId":{"type":"string"}},"required":["calendarId","accountId"],"additionalProperties":false},"raw":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The provider's original payload. Included only with `include=raw`."}},"required":["id","name","description","timezone","isPrimary","color","accessRole","location","conferencing","tallyResponses","hidden","provider","providerRefs"],"additionalProperties":false},"Metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":["string","number","boolean"]},{"type":"array","items":{"type":["string","number","boolean"]}}]},"description":"Your own key-value pairs, stored by Pyas with the object. A value is text, a number, a boolean or a list of those.","examples":[{"crmId":"deal_42","priority":2,"tags":["Food","Hiking"]}]},"CalendarWrite":{"type":"object","properties":{"accountId":{"type":"string","description":"The `accountId` of the connected account. You can send it here or in the query."},"name":{"type":"string","maxLength":256},"description":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}]},"timezone":{"type":["string","null"]},"color":{"description":"The color, as `#rrggbb`.","type":["string","null"]},"location":{"description":"Google Calendar only.","type":["string","null"]},"conferencing":{"type":"object","properties":{"default":{"type":["string","null"]},"allowed":{"type":"array","items":{"type":"string"}}},"additionalProperties":false},"tallyResponses":{"description":"Outlook only.","type":"boolean"},"hidden":{"description":"Google Calendar only. Whether to hide the calendar from the calendar list.","type":"boolean"},"groupId":{"description":"Outlook only, when creating a calendar. The calendar group to create it in.","type":"string"},"metadata":{"$ref":"#/components/schemas/Metadata"},"providerOptions":{"$ref":"#/components/schemas/ProviderOptions"}},"required":["name"],"additionalProperties":false},"ProviderOptions":{"type":"object","properties":{"google":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"microsoft":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"additionalProperties":false,"description":"Provider-specific fields that have no equivalent in v2, grouped by provider. Each group applies only to accounts on that provider."},"Category":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"color":{"description":"The color, as `#rrggbb`.","type":["string","null"]}},"required":["id","name","color"],"additionalProperties":false},"CalendarFeed":{"type":"object","properties":{"enabled":{"type":"boolean"},"url":{"description":"The feed URL (`https`). Anyone with the link can read the calendar, so treat it like a password.","type":["string","null"]},"webcalUrl":{"description":"The same feed URL with the `webcal:` scheme, which calendar apps open as a subscription.","type":["string","null"]},"details":{"anyOf":[{"type":"string","enum":["full","busy"]},{"type":"null"}],"description":"`full` includes titles, locations and notes. `busy` shows only when the calendar is busy."},"createdAt":{"type":["string","null"]},"expiresAt":{"description":"Sandbox feeds stop working after 1 week. Live feeds work until you disable them.","type":["string","null"]}},"required":["enabled","url","webcalUrl","details","createdAt","expiresAt"],"additionalProperties":false},"CalendarPermission":{"type":"object","properties":{"id":{"type":"string"},"grantee":{"type":"object","properties":{"type":{"type":"string","enum":["user","group","domain","public","organization"]},"email":{"type":["string","null"]},"domain":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["type","email","domain","name"],"additionalProperties":false},"role":{"anyOf":[{"$ref":"#/components/schemas/PermissionRole"},{"type":"string","const":"none"}]},"removable":{"type":"boolean","description":"`false` for permissions the provider doesn't allow you to delete, such as the owner and Outlook's built-in entries."}},"required":["id","grantee","role","removable"],"additionalProperties":false},"PermissionRole":{"type":"string","enum":["freeBusy","limitedRead","read","write","delegate","delegateWithPrivate","owner"],"description":"The level of access, from least to most: `freeBusy` (free/busy only), `limitedRead` (titles and locations, Outlook only), `read` (everything except private events), `write` (editing), `delegate` and `delegateWithPrivate` (a delegate, Outlook only), and `owner` (full control, Google Calendar only)."},"Palette":{"type":"object","properties":{"calendarColors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"color":{"type":"string"}},"required":["id","color"],"additionalProperties":false}},"eventColors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"color":{"type":"string"}},"required":["id","color"],"additionalProperties":false}}},"required":["calendarColors","eventColors"],"additionalProperties":false},"ConnectedAccount":{"type":"object","properties":{"accountId":{"type":"string","description":"The ID Pyas assigns to the connected account. A reconnected account keeps its existing ID."},"provider":{"type":"string","enum":["google","microsoft","zoom"]},"email":{"type":"string"},"name":{"type":"string"},"subjectId":{"type":["string","null"]},"existing":{"type":"boolean","description":"`true` when the account was already connected and this was a reconnect."},"grantedScopes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["accountId","provider","email","name","subjectId","existing","grantedScopes"],"additionalProperties":false},"ConnectSession":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","authorizing","completing","completed","failed"]},"mode":{"type":"string","enum":["popup","redirect"]},"reconnectAccountId":{"type":["string","null"]},"providers":{"type":"array","items":{"type":"string","enum":["google","microsoft","zoom"]}},"products":{"type":"array","items":{"type":"string"}},"features":{"type":"array","items":{"type":"string","enum":["manageCalendars","sharing","meetingSettings","attachmentUploads","rooms"]}},"subjectId":{"type":["string","null"]},"returnUrl":{"type":["string","null"]},"provider":{"anyOf":[{"type":"string","enum":["google","microsoft","zoom"]},{"type":"null"}],"description":"The provider the user chose, once they have chosen one."},"expiresAt":{"type":"string"},"account":{"anyOf":[{"$ref":"#/components/schemas/ConnectedAccount"},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","mode","reconnectAccountId","providers","products","features","subjectId","returnUrl","provider","expiresAt","account","error"],"additionalProperties":false},"Event":{"type":"object","properties":{"id":{"type":"string"},"iCalUID":{"description":"The iCalendar UID, which is the same on every calendar the meeting is on.","type":["string","null"]},"title":{"type":"string"},"description":{"type":["string","null"]},"location":{"type":["string","null"]},"startsAt":{"type":"string","description":"The time in UTC, ending in `Z`.","format":"date-time"},"endsAt":{"type":"string","description":"The time in UTC, ending in `Z`.","format":"date-time"},"startsAtLocal":{"type":"string","description":"The same time in the event's `timezone`, for display."},"endsAtLocal":{"type":"string"},"timezone":{"type":"string","description":"The IANA time zone name."},"isAllDay":{"type":"boolean"},"status":{"type":"string","enum":["confirmed","tentative","cancelled"]},"visibility":{"type":["string","null"]},"attendees":{"type":"array","items":{"$ref":"#/components/schemas/Attendee"}},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/EventRoom"},"description":"The rooms and resources booked for the event. They aren't counted as attendees."},"organizer":{"anyOf":[{"type":"object","properties":{"email":{"type":"string"},"name":{"type":["string","null"]}},"required":["email","name"],"additionalProperties":false},{"type":"null"}]},"conferencing":{"anyOf":[{"$ref":"#/components/schemas/Conferencing"},{"type":"null"}]},"meetingUrl":{"description":"The same value as `conferencing.joinUrl`, for convenience.","type":["string","null"]},"recurrence":{"description":"An RFC 5545 RRULE.","type":["string","null"]},"series":{"anyOf":[{"type":"object","properties":{"masterEventId":{"type":"string"},"originalStartsAt":{"type":"string","description":"The time this occurrence was originally scheduled to start.","format":"date-time"},"isException":{"type":"boolean"}},"required":["masterEventId","originalStartsAt","isException"],"additionalProperties":false},{"type":"null"}],"description":"Set on an occurrence of a recurring series."},"reminders":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string"},"minutesBefore":{"type":"number"}},"required":["method","minutesBefore"],"additionalProperties":false}},"attachments":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"},"mimeType":{"type":["string","null"]}},"required":["url","title","mimeType"],"additionalProperties":false}},"showAs":{"anyOf":[{"type":"string","enum":["busy","free","tentative","outOfOffice","workingElsewhere"]},{"type":"null"}]},"eventType":{"type":"string","enum":["default","focusTime","outOfOffice","workingLocation","birthday","fromGmail"]},"color":{"description":"The color, as `#rrggbb`. `null` means the event uses the calendar's color.","type":["string","null"]},"guests":{"type":"object","properties":{"canModify":{"type":"boolean"},"canInviteOthers":{"type":"boolean"},"canSeeGuests":{"type":"boolean"},"canProposeTimes":{"type":"boolean"}},"required":["canModify","canInviteOthers","canSeeGuests","canProposeTimes"],"additionalProperties":false},"importance":{"anyOf":[{"type":"string","enum":["low","normal","high"]},{"type":"null"}]},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"responseRequested":{"type":["boolean","null"]},"autoDecline":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["none","all","new"]},"message":{"type":["string","null"]}},"required":["mode","message"],"additionalProperties":false},{"type":"null"}]},"doNotDisturb":{"type":["boolean","null"]},"workingLocation":{"anyOf":[{"$ref":"#/components/schemas/WorkingLocation"},{"type":"null"}]},"birthday":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["birthday","anniversary","custom","other","self"]},"contact":{"type":["string","null"]},"customLabel":{"type":["string","null"]}},"required":["type","contact","customLabel"],"additionalProperties":false},{"type":"null"}]},"source":{"anyOf":[{"type":"object","properties":{"title":{"type":["string","null"]},"url":{"type":"string"}},"required":["title","url"],"additionalProperties":false},{"type":"null"}]},"endTimeUnspecified":{"type":["boolean","null"]},"privateCopy":{"type":["boolean","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"version":{"description":"The event's version. Send it in the `If-Match` header to update the event only if it hasn't changed.","type":["string","null"]},"provider":{"$ref":"#/components/schemas/Provider"},"providerRefs":{"type":"object","properties":{"eventId":{"type":"string"},"calendarId":{"type":"string"},"accountId":{"type":"string"}},"required":["eventId","calendarId","accountId"],"additionalProperties":false},"metadata":{"anyOf":[{"$ref":"#/components/schemas/Metadata"},{"type":"null"}]},"invitations":{"description":"Virtual calendars only. Included after a write that invited attendees.","type":"object","properties":{"queued":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"notSent":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"reason":{"type":"string"}},"required":["email","reason"],"additionalProperties":false}}},"required":["queued","notSent"],"additionalProperties":false},"extendedProperties":{"description":"The provider's extended properties. On Google, Google's own `private` and `shared` maps. On Outlook, the properties listed in `extendedPropertyIds`, under their names (a numbered property under its ID), typed as their IDs declare, and a multi-value property as a list. Included only with `include=extendedProperties`. Store your own data in `metadata`.","anyOf":[{"type":"object","properties":{"private":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"shared":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["private","shared"],"additionalProperties":false},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":["string","number","boolean"]},{"type":"array","items":{"type":["string","number","boolean"]}}]}}]},"raw":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The provider's original payload. Included only with `include=raw`."},"duplicateOf":{"description":"On a multi-account listing with `duplicates=flag`, the earlier event that this event is a copy of.","$ref":"#/components/schemas/EventCopy"},"alsoIn":{"description":"On a multi-account listing with `duplicates=collapse`, the other calendars that have the same event.","type":"array","items":{"$ref":"#/components/schemas/EventCopy"}}},"required":["id","iCalUID","title","description","location","startsAt","endsAt","startsAtLocal","endsAtLocal","timezone","isAllDay","status","visibility","attendees","rooms","organizer","conferencing","meetingUrl","recurrence","series","reminders","attachments","showAs","eventType","color","guests","importance","categories","responseRequested","autoDecline","doNotDisturb","workingLocation","birthday","source","endTimeUnspecified","privateCopy","createdAt","updatedAt","version","provider","providerRefs","metadata"],"additionalProperties":false},"Attendee":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":["string","null"]},"response":{"anyOf":[{"type":"string","enum":["needsAction","declined","tentative","accepted"]},{"type":"null"}]},"optional":{"type":"boolean"},"isOrganizer":{"type":"boolean"},"comment":{"description":"Virtual calendars only. The comment the attendee included with their response.","type":"string"},"proposedTime":{"description":"Virtual calendars only. A different time the attendee proposed.","type":"object","properties":{"startsAt":{"type":"string"},"endsAt":{"type":"string"}},"required":["startsAt","endsAt"],"additionalProperties":false}},"required":["email","name","response","optional","isOrganizer"],"additionalProperties":false},"EventRoom":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":["string","null"]},"response":{"anyOf":[{"type":"string","enum":["needsAction","declined","tentative","accepted"]},{"type":"null"}]}},"required":["email","name","response"],"additionalProperties":false},"Conferencing":{"type":"object","properties":{"provider":{"type":"string","description":"The conferencing service, such as `zoom`, `meet` or `teams`."},"joinUrl":{"type":"string"},"meetingId":{"type":["string","null"]},"passcode":{"type":["string","null"]},"dialIn":{"type":"array","items":{"type":"object","properties":{"label":{"type":["string","null"]},"number":{"type":"string"},"pin":{"type":["string","null"]}},"required":["label","number","pin"],"additionalProperties":false}},"settings":{"description":"Included after a write that set options, and with `include=conferencingSettings`.","$ref":"#/components/schemas/ConferencingOptions"}},"required":["provider","joinUrl","meetingId","passcode","dialIn"],"additionalProperties":false},"ConferencingOptions":{"type":"object","properties":{"admission":{"description":"Who can join without waiting.","type":"string","enum":["everyone","organization","invited","organizer"]},"recording":{"type":"string","enum":["none","cloud","local"]},"transcription":{"description":"Google Meet only.","type":"boolean"},"joinBeforeHost":{"description":"Zoom only.","type":"boolean"},"muteOnEntry":{"description":"Zoom only.","type":"boolean"},"passcode":{"description":"Zoom only. If you don't set one, Pyas generates a passcode.","type":"string"},"coHosts":{"description":"Alternative hosts on Zoom, or co-organizers on Microsoft Teams.","type":"array","items":{"type":"string"}},"presenters":{"description":"Microsoft Teams only.","type":"string","enum":["everyone","organization","organizer"]},"chat":{"description":"Microsoft Teams only.","type":"string","enum":["enabled","disabled","limited"]}},"additionalProperties":false,"description":"Meeting settings, with the same field names for Zoom, Microsoft Teams and Google Meet. If the conferencing service doesn't support a setting, the request is rejected with the reason."},"EventCopy":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"eventId":{"type":"string"},"match":{"type":"string","enum":["iCalUID","titleAndTime"],"description":"How the copy was identified as the same event."}},"required":["accountId","calendarRef","eventId","match"],"additionalProperties":false},"EventCreate":{"type":"object","properties":{"accountId":{"type":"string","description":"The `accountId` of the connected account. You can send it here or in the query."},"calendarRef":{"type":"string","description":"The calendar to use. Defaults to `primary`. You can send it here or in the query."},"title":{"type":"string","maxLength":1024},"description":{"type":"string","maxLength":65536},"location":{"type":"string","maxLength":1024},"startsAt":{"type":"string","description":"An ISO 8601 time with a zone, or a date such as `2026-03-15` for an all-day event.","examples":["2026-03-15T14:00:00Z"]},"endsAt":{"type":"string","description":"The end of the event. Must be later than `startsAt`.","examples":["2026-03-15T15:00:00Z"]},"timezone":{"type":"string","description":"The IANA time zone of the event. Defaults to the calendar's time zone."},"isAllDay":{"type":"boolean"},"attendees":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"},"optional":{"type":"boolean"}},"required":["email"],"additionalProperties":false}},"rooms":{"maxItems":20,"type":"array","items":{"type":"string"},"description":"The email addresses of the rooms to book (see `GET /v2/rooms`). On an update, send the complete list."},"recurrence":{"type":"string","description":"An RFC 5545 RRULE, such as `FREQ=WEEKLY;BYDAY=MO`.","examples":["FREQ=WEEKLY;BYDAY=MO,WE"]},"conferencing":{"type":"object","properties":{"provider":{"type":"string","enum":["meet","teams","zoom"]},"accountId":{"description":"For `zoom`, the connected Zoom account to create the meeting with.","type":"string"},"options":{"$ref":"#/components/schemas/ConferencingOptions"}},"required":["provider"],"additionalProperties":false,"description":"A meeting link, created with the event."},"reminders":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"method":{"type":"string","enum":["popup","email"]},"minutesBefore":{"type":"integer","minimum":0,"maximum":40320}},"required":["method","minutesBefore"],"additionalProperties":false}},"visibility":{"type":"string","enum":["default","public","private","confidential"]},"notifyAttendees":{"type":"boolean","description":"Whether the provider emails attendees about this change. Outlook always emails them: there, `false` isn't applied, and the response's `meta.notifyAttendees` says so."},"metadata":{"$ref":"#/components/schemas/Metadata"},"showAs":{"type":"string","enum":["busy","free","tentative","outOfOffice","workingElsewhere"]},"color":{"type":"string","description":"The color, as `#rrggbb`. The provider uses the closest color it offers."},"guests":{"type":"object","properties":{"canModify":{"type":"boolean"},"canInviteOthers":{"type":"boolean"},"canSeeGuests":{"type":"boolean"},"canProposeTimes":{"type":"boolean"}},"additionalProperties":false},"importance":{"type":"string","enum":["low","normal","high"]},"categories":{"maxItems":25,"type":"array","items":{"type":"string"}},"responseRequested":{"type":"boolean"},"autoDecline":{"type":"object","properties":{"mode":{"type":"string","enum":["none","all","new"]},"message":{"type":["string","null"]}},"additionalProperties":false},"doNotDisturb":{"type":"boolean"},"workingLocation":{"$ref":"#/components/schemas/WorkingLocation"},"source":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"}},"required":["url"],"additionalProperties":false},"endTimeUnspecified":{"type":"boolean"},"privateCopy":{"type":"boolean"},"status":{"type":"string","enum":["confirmed","tentative"],"description":"To cancel an event, send a `DELETE` request instead."},"providerOptions":{"$ref":"#/components/schemas/ProviderOptions"},"eventType":{"description":"Can be set only when creating an event, because providers don't allow it to be updated.","type":"string","enum":["default","focusTime","outOfOffice","workingLocation","birthday"]},"id":{"description":"Google Calendar only. Your own event ID, 5 to 1024 characters from a-v and 0-9.","type":"string"},"birthday":{"type":"object","properties":{"type":{"type":"string","enum":["birthday","anniversary","custom","other","self"]}},"required":["type"],"additionalProperties":false}},"required":["title","startsAt","endsAt"],"additionalProperties":false,"description":"A new event. The v1 request body (`{ accountId, calendarId, eventData }`) is also accepted."},"EventPatch":{"type":"object","properties":{"accountId":{"type":"string","description":"The `accountId` of the connected account. You can send it here or in the query."},"calendarRef":{"type":"string","description":"The calendar to use. Defaults to `primary`. You can send it here or in the query."},"title":{"type":"string","maxLength":1024},"description":{"anyOf":[{"type":"string","maxLength":65536},{"type":"null"}]},"location":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}]},"startsAt":{"type":"string","description":"An ISO 8601 time with a zone, or a date such as `2026-03-15` for an all-day event.","examples":["2026-03-15T14:00:00Z"]},"endsAt":{"type":"string","description":"The end of the event. Must be later than `startsAt`.","examples":["2026-03-15T15:00:00Z"]},"timezone":{"type":"string","description":"The IANA time zone of the event. Defaults to the calendar's time zone."},"isAllDay":{"type":"boolean"},"attendees":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"},"optional":{"type":"boolean"}},"required":["email"],"additionalProperties":false}},"rooms":{"maxItems":20,"type":"array","items":{"type":"string"},"description":"The email addresses of the rooms to book (see `GET /v2/rooms`). On an update, send the complete list."},"recurrence":{"anyOf":[{"type":"string","description":"An RFC 5545 RRULE, such as `FREQ=WEEKLY;BYDAY=MO`.","examples":["FREQ=WEEKLY;BYDAY=MO,WE"]},{"type":"null"}]},"conferencing":{"description":"Send `provider` to create a new meeting, `options` alone to update the existing meeting's settings, or `null` to remove the meeting.","anyOf":[{"anyOf":[{"type":"object","properties":{"provider":{"type":"string","enum":["meet","teams","zoom"]},"accountId":{"description":"For `zoom`, the connected Zoom account to create the meeting with.","type":"string"},"options":{"$ref":"#/components/schemas/ConferencingOptions"}},"required":["provider"],"additionalProperties":false,"description":"A meeting link, created with the event."},{"type":"object","properties":{"options":{"$ref":"#/components/schemas/ConferencingOptions"}},"required":["options"],"additionalProperties":false}]},{"type":"null"}]},"reminders":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"method":{"type":"string","enum":["popup","email"]},"minutesBefore":{"type":"integer","minimum":0,"maximum":40320}},"required":["method","minutesBefore"],"additionalProperties":false}},"visibility":{"type":"string","enum":["default","public","private","confidential"]},"notifyAttendees":{"type":"boolean","description":"Whether the provider emails attendees about this change. Outlook always emails them: there, `false` isn't applied, and the response's `meta.notifyAttendees` says so."},"metadata":{"$ref":"#/components/schemas/Metadata"},"showAs":{"type":"string","enum":["busy","free","tentative","outOfOffice","workingElsewhere"]},"color":{"anyOf":[{"type":"string","description":"The color, as `#rrggbb`. The provider uses the closest color it offers."},{"type":"null"}]},"guests":{"type":"object","properties":{"canModify":{"type":"boolean"},"canInviteOthers":{"type":"boolean"},"canSeeGuests":{"type":"boolean"},"canProposeTimes":{"type":"boolean"}},"additionalProperties":false},"importance":{"type":"string","enum":["low","normal","high"]},"categories":{"maxItems":25,"type":"array","items":{"type":"string"}},"responseRequested":{"type":"boolean"},"autoDecline":{"type":"object","properties":{"mode":{"type":"string","enum":["none","all","new"]},"message":{"type":["string","null"]}},"additionalProperties":false},"doNotDisturb":{"type":"boolean"},"workingLocation":{"$ref":"#/components/schemas/WorkingLocation"},"source":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"}},"required":["url"],"additionalProperties":false},{"type":"null"}]},"endTimeUnspecified":{"type":"boolean"},"privateCopy":{"type":"boolean"},"status":{"type":"string","enum":["confirmed","tentative"],"description":"To cancel an event, send a `DELETE` request instead."},"providerOptions":{"$ref":"#/components/schemas/ProviderOptions"}},"additionalProperties":false,"description":"Only the fields to update. Setting a nullable field to `null` clears it."},"Attachment":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"mimeType":{"type":["string","null"]},"size":{"type":["number","null"]},"url":{"description":"The file's location. `null` for a file stored in Outlook. Download it with `/content`.","type":["string","null"]},"kind":{"type":"string","enum":["file","link","item"]}},"required":["id","name","mimeType","size","url","kind"],"additionalProperties":false},"FreeBusy":{"type":"object","properties":{"busy":{"type":"array","items":{"$ref":"#/components/schemas/BusyBlock"},"description":"The busy times of every requested calendar, merged into one list. Use it to see when anyone is busy."},"accounts":{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"provider":{"anyOf":[{"$ref":"#/components/schemas/Provider"},{"type":"null"}]},"busy":{"type":"array","items":{"$ref":"#/components/schemas/BusyBlock"},"description":"Busy times across this account's calendars, merged."},"calendars":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/BusyBlock"}},"description":"Busy times for each calendar, keyed by the requested `calendarRef`."},"errors":{"description":"Calendars the provider couldn't return free/busy data for, with the reason for each.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"error":{"description":"Included when the account couldn't be read, for example because access was revoked. The other accounts are still returned.","type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["accountId","provider","busy","calendars"],"additionalProperties":false}}},"required":["busy","accounts"],"additionalProperties":false},"BusyBlock":{"type":"object","properties":{"startsAt":{"type":"string"},"endsAt":{"type":"string"},"status":{"description":"Included when the provider distinguishes busy from tentative or out of office.","type":"string","enum":["busy","tentative","outOfOffice"]}},"required":["startsAt","endsAt"],"additionalProperties":false},"Invitation":{"type":"object","properties":{"id":{"type":"string"},"accountId":{"type":"string"},"calendarId":{"type":"string"},"eventId":{"type":"string"},"method":{"type":"string","description":"The iTIP method: `REQUEST` (an invitation or update) or `CANCEL`."},"kind":{"type":"string","description":"The type of message sent to the attendee: an invitation, an update or a cancellation."},"to":{"type":"string"},"status":{"type":"string","enum":["queued","sent","captured","held","suppressed","failed"],"description":"The delivery status: `queued`, `sent`, `captured` (in the sandbox, never sent), `held` (over the daily limit), `suppressed` (the address bounced or complained before) or `failed`."},"reason":{"type":["string","null"]},"subject":{"type":"string"},"createdAt":{"type":"string"},"sentAt":{"type":["string","null"]},"bounced":{"type":"boolean"},"complained":{"type":"boolean"},"ics":{"type":"string","description":"The iCalendar text sent to the attendee. In the sandbox, the text that would have been sent."}},"required":["id","accountId","calendarId","eventId","method","kind","to","status","reason","subject","createdAt","sentAt","bounced","complained","ics"],"additionalProperties":false},"ApiKey":{"type":"object","properties":{"keyId":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["live","test"]},"scopes":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","rotating","inactive","revoked"],"description":"`rotating` means the key has been replaced but keeps working until `graceEndsAt`."},"last4":{"description":"The last 4 characters of the key, to help you tell keys apart.","type":["string","null"]},"expiresAt":{"type":["string","null"]},"graceEndsAt":{"type":["string","null"]},"rotatedFrom":{"type":["string","null"]},"rotatedTo":{"type":["string","null"]},"createdAt":{"type":["string","null"]},"seenInBrowser":{"anyOf":[{"type":"object","properties":{"at":{"type":"string"},"origin":{"type":"string"}},"required":["at","origin"],"additionalProperties":false},{"type":"null"}],"description":"When the key was last sent from a web page, and from which origin. A live key sent that way is refused (`AUTH_KEY_IN_BROWSER`); a test key still works, with a `Pyas-Warning` header. Keys belong in server code."}},"required":["keyId","name","mode","scopes","status","last4","expiresAt","graceEndsAt","rotatedFrom","rotatedTo","createdAt","seenInBrowser"],"additionalProperties":false},"RequestLog":{"type":"object","properties":{"traceId":{"type":"string"},"createdAt":{"type":"string"},"mode":{"type":"string","enum":["live","test"]},"keyId":{"description":"The API key that made the request.","type":["string","null"]},"client":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["mcp","cli","package"],"description":"`mcp`: an AI tool connected to the Pyas MCP server. `cli`: the Pyas CLI. `package`: one of the Pyas packages your code runs, such as `@pyas/ai-tools`."},"name":{"type":"string","description":"The name the tool registered with, such as \"Claude\", \"Cursor\" or \"Pyas CLI\", or the name of the package."}},"required":["kind","name"],"additionalProperties":false},{"type":"null"}],"description":"The tool or Pyas package that made the request, or `null` for your own code."},"method":{"type":"string"},"route":{"type":"string","description":"The endpoint, with IDs replaced by `:id`, such as \"GET /v2/events/:id\"."},"operationId":{"description":"The operation in the API reference, such as `events.create`.","type":["string","null"]},"path":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"durationMs":{"type":"number"},"accountId":{"type":["string","null"]},"subjectId":{"type":["string","null"]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":["string","null"]},"hint":{"type":["string","null"]},"docs":{"type":["string","null"]}},"required":["code","message","hint","docs"],"additionalProperties":false},{"type":"null"}],"description":"The error returned for the request, if it failed, with a link to the error's documentation."},"idempotencyKey":{"type":["string","null"]},"replayed":{"type":"boolean","description":"`true` if the response was replayed from an earlier request with the same `Idempotency-Key`."},"cache":{"description":"Where read data was served from, as reported in the `X-Pyas-Cache` header: `HIT`, `MISS`, `PARTIAL`, `BYPASS` or `STALE`.","type":["string","null"]},"queuedMs":{"description":"The longest time, in milliseconds, that a provider request waited in the queue, as reported in the `X-Pyas-Provider-Queued-Ms` header.","type":["number","null"]},"operations":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","description":"`google`, `microsoft`, `pyas` (virtual) or `zoom`. For the sandbox's simulated Google and Outlook accounts, the value includes \"(simulated)\"."},"operation":{"type":"string","description":"The operation Pyas performed for the request, such as `listEvents`, `createEvent` or `getFreeBusy`."},"accountId":{"type":"string"},"durationMs":{"type":"number"},"error":{"description":"The error code, if the operation failed.","type":"string"}},"required":["provider","operation","accountId","durationMs"],"additionalProperties":false}},"providerCalls":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string"},"method":{"type":"string"},"host":{"type":"string"},"path":{"type":"string","description":"The provider path, with IDs, email addresses and tokens replaced by `:id`."},"status":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The HTTP status the provider returned, or `null` if no response was received."},"durationMs":{"type":"number"},"failure":{"description":"`timeout` or `network` when no response was received.","type":"string"},"retryAfter":{"description":"The number of seconds the provider asked Pyas to wait before retrying, when it throttled the request.","type":"number"}},"required":["provider","method","host","path","status","durationMs"],"additionalProperties":false},"description":"Each HTTP request made to Google, Microsoft or Zoom. Requests for sandbox accounts don't make any."},"tokenRefreshes":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string"},"accountId":{"type":"string"},"outcome":{"type":"string"}},"required":["provider","accountId","outcome"],"additionalProperties":false}},"webhookEvents":{"type":"array","items":{"type":"object","properties":{"eventId":{"type":"string"},"type":{"type":"string"}},"required":["eventId","type"],"additionalProperties":false},"description":"The webhook events the request triggered. Retrieve an event with GET /v2/webhooks/events/{eventId}, and its deliveries with GET /v2/webhooks/deliveries?eventId={eventId}."},"invitations":{"type":"array","items":{"type":"string"},"description":"The invitations the request sent. Retrieve one with GET /v2/invitations/{invitationId}."},"omitted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The number of entries omitted because a list exceeded its limit of 50 entries."}},"required":["traceId","createdAt","mode","keyId","client","method","route","operationId","path","status","durationMs","accountId","subjectId","error","idempotencyKey","replayed","cache","queuedMs","operations","providerCalls","tokenRefreshes","webhookEvents","invitations","omitted"],"additionalProperties":false},"MeetingSlot":{"type":"object","properties":{"startsAt":{"type":"string"},"endsAt":{"type":"string"},"optionalFree":{"type":"array","items":{"type":"string"},"description":"Optional attendees free for the whole slot."},"optionalBusy":{"type":"array","items":{"type":"string"}},"rooms":{"description":"Rooms free for the whole slot, when the request includes `rooms`.","type":"array","items":{"type":"string"}}},"required":["startsAt","endsAt","optionalFree","optionalBusy"],"additionalProperties":false},"Meeting":{"type":"object","properties":{"id":{"type":"string","description":"The meeting ID at the provider: Zoom's meeting number, or Microsoft Teams' online meeting ID."},"provider":{"type":"string","enum":["zoom","teams","meet"],"description":"The meeting service: `zoom`, `teams` or `meet`, as in `conferencing.provider` on events. The response's top-level `provider` is the account's: `zoom`, `microsoft` or `google`."},"accountId":{"type":"string"},"kind":{"type":"string","enum":["scheduled","recurring","recurringNoFixedTime","instant","space"],"description":"`recurring` repeats at fixed times (`recurrence`). `recurringNoFixedTime` (Zoom) and `space` (a Google Meet link) work at any time."},"title":{"description":"`null` for a Google Meet link, which has no title.","type":["string","null"]},"description":{"type":["string","null"]},"startsAt":{"description":"For a recurring meeting, its first occurrence.","type":["string","null"]},"durationMinutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"timezone":{"type":["string","null"]},"recurrence":{"description":"An RRULE, such as `FREQ=WEEKLY;BYDAY=MO,WE;COUNT=10`.","type":["string","null"]},"occurrences":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"startsAt":{"type":"string"},"durationMinutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"status":{"type":["string","null"]}},"required":["id","startsAt","durationMinutes","status"],"additionalProperties":false},"description":"A recurring meeting's occurrences, from a get. Empty in a list."},"joinUrl":{"type":["string","null"]},"passcode":{"type":["string","null"]},"dialIn":{"type":"array","items":{"type":"object","properties":{"label":{"type":["string","null"]},"number":{"type":"string"},"pin":{"type":["string","null"]}},"required":["label","number","pin"],"additionalProperties":false}},"settings":{"$ref":"#/components/schemas/ConferencingOptions"},"createdAt":{"type":["string","null"]}},"required":["id","provider","accountId","kind","title","description","startsAt","durationMinutes","timezone","recurrence","occurrences","joinUrl","passcode","dialIn","settings","createdAt"],"additionalProperties":false,"description":"A meeting on its own, with no calendar event. To add a meeting to an event, use `conferencing` on the event instead."},"MeetingCreate":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":128,"description":"The `accountId` of a connected Zoom account, a Microsoft work or school account for Microsoft Teams, or a Google account for a Google Meet link."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"The meeting's topic. Required for Zoom and Microsoft Teams; a Google Meet link has none."},"description":{"description":"The agenda. Zoom only.","type":"string","maxLength":2000},"startsAt":{"description":"When it starts (ISO 8601). For a recurring meeting, its first occurrence. Required for Zoom and Microsoft Teams; a Google Meet link works at any time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"durationMinutes":{"description":"Its length in minutes. 30 if you don't set it.","type":"integer","minimum":1,"maximum":1440},"timezone":{"description":"An IANA time zone, such as `America/New_York`. Recurring meetings repeat in it.","type":"string","maxLength":64},"recurrence":{"description":"Zoom only. A recurrence rule (RRULE): FREQ=DAILY, WEEKLY or MONTHLY, INTERVAL, BYDAY or BYMONTHDAY, and COUNT (up to 60) or UNTIL. Zoom needs an end.","type":"string","maxLength":500},"attendees":{"description":"People invited by email. On Microsoft Teams, the meeting's attendees.","maxItems":100,"type":"array","items":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["email"],"additionalProperties":false}},"settings":{"$ref":"#/components/schemas/ConferencingOptions"}},"required":["accountId"],"additionalProperties":false},"MeetingPatch":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"startsAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"durationMinutes":{"type":"integer","minimum":1,"maximum":1440},"timezone":{"type":"string","maxLength":64},"recurrence":{"description":"A recurrence rule (RRULE): FREQ=DAILY, WEEKLY or MONTHLY, INTERVAL, BYDAY or BYMONTHDAY, and COUNT (up to 60) or UNTIL. Zoom needs an end. `null` makes it a single meeting.","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"attendees":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["email"],"additionalProperties":false}},"settings":{"$ref":"#/components/schemas/ConferencingOptions"}},"additionalProperties":false,"description":"Only the fields you send change."},"MetadataImportPreview":{"type":"object","properties":{"dryRun":{"type":"boolean","const":true},"sampled":{"type":"object","properties":{"accounts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"accountsInAll":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"calendars":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"events":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["accounts","accountsInAll","calendars","events"],"additionalProperties":false},"google":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"events":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"examples":{"type":"array","items":{"type":"string"}},"scopes":{"type":"array","items":{"type":"string","enum":["private","shared"]},"description":"The Google scopes the key was found in."},"conflicts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"On how many events the key held different values in private and shared. The private value is imported."},"canBeMetadataKey":{"type":"boolean"}},"required":["key","events","examples","scopes","conflicts","canBeMetadataKey"],"additionalProperties":false}}},"required":["keys"],"additionalProperties":false},"microsoft":{"type":"object","properties":{"properties":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"events":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"examples":{"type":"array","items":{"type":"string"}}},"required":["id","key","events","examples"],"additionalProperties":false}}},"required":["properties"],"additionalProperties":false},"wouldCopy":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unchanged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"wouldSkip":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"skipped":{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"eventId":{"type":"string"},"reason":{"type":"string"}},"required":["accountId","eventId","reason"],"additionalProperties":false}},"errors":{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"propertyId":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}},"required":["accountId","calendarRef","code","message"],"additionalProperties":false}}},"required":["dryRun","sampled","google","microsoft","wouldCopy","unchanged","wouldSkip","skipped","errors"],"additionalProperties":false},"MetadataImport":{"type":"object","properties":{"importId":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"]},"request":{"type":"object","properties":{"accounts":{"anyOf":[{"type":"object","properties":{"accountIds":{"type":"array","items":{"type":"string"}}},"required":["accountIds"],"additionalProperties":false},{"type":"object","properties":{"subjectId":{"type":"string"}},"required":["subjectId"],"additionalProperties":false},{"type":"object","properties":{"allAccounts":{"type":"boolean","const":true}},"required":["allAccounts"],"additionalProperties":false}]},"calendarRefs":{"type":"array","items":{"type":"string"}},"from":{"type":"string"},"to":{"type":"string"},"google":{"type":"object","properties":{"scope":{"type":"string","enum":["private","shared","both"]},"keys":{"type":"array","items":{"type":"string"}}},"required":["scope"],"additionalProperties":false},"microsoft":{"type":"object","properties":{"properties":{"type":"array","items":{"type":"string"}},"keys":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["properties"],"additionalProperties":false},"overwrite":{"type":"boolean"},"convert":{"type":"string","enum":["none","auto"]},"dryRun":{"type":"boolean"},"sampleSize":{"type":"number"}},"required":["accounts","calendarRefs","google","overwrite","convert"],"additionalProperties":false},"progress":{"type":"object","properties":{"calendars":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"finished":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["calendars","finished"],"additionalProperties":false},"counts":{"type":"object","properties":{"scanned":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"copied":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unchanged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"skipped":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["scanned","copied","unchanged","skipped"],"additionalProperties":false},"skippedKeys":{"type":"array","items":{"type":"string"},"description":"Provider keys that can't be used as metadata keys."},"skipped":{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"eventId":{"type":"string"},"reason":{"type":"string"}},"required":["accountId","eventId","reason"],"additionalProperties":false},"description":"The first events that were skipped, with the reason for each."},"errors":{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"calendarRef":{"type":"string"},"propertyId":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}},"required":["accountId","calendarRef","code","message"],"additionalProperties":false}},"createdAt":{"type":"string"},"startedAt":{"type":["string","null"]},"finishedAt":{"type":["string","null"]}},"required":["importId","status","request","progress","counts","skippedKeys","skipped","errors","createdAt","startedAt","finishedAt"],"additionalProperties":false},"Room":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"capacity":{"type":["number","null"]},"building":{"type":["string","null"]},"floor":{"type":["string","null"]},"features":{"type":"array","items":{"type":"string"}},"accessible":{"description":"Reported by Outlook. `null` on Google Calendar.","type":["boolean","null"]},"kind":{"type":"string","enum":["room","resource"]}},"required":["id","name","email","capacity","building","floor","features","accessible","kind"],"additionalProperties":false},"Sandbox":{"type":"object","properties":{"seededAt":{"description":"When the sandbox was last populated with sample data.","type":["string","null"]},"accounts":{"type":"array","items":{"type":"object","properties":{"accountId":{"type":"string"},"provider":{"type":"string"},"name":{"type":"string"},"subjectId":{"type":["string","null"]}},"required":["accountId","provider","name","subjectId"],"additionalProperties":false}},"examples":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"The IDs in this sandbox that the examples in the API reference use, such as {{account.avery}}, {{calendar.avery.work}} and {{event.avery.design}}."}},"required":["seededAt","accounts","examples"],"additionalProperties":false},"Usage":{"type":"object","properties":{"totals":{"type":"object","properties":{"v1":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Live requests to v1."},"v2":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Live requests to v2."},"test":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Requests made with test keys, in the v2 sandbox."}},"required":["v1","v2","test"],"additionalProperties":false},"v2Share":{"description":"The share of live requests made to v2, from 0 to 1. `null` when there were no live requests.","type":["number","null"]},"days":{"type":"array","items":{"type":"object","properties":{"v1":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Live requests to v1."},"v2":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Live requests to v2."},"test":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Requests made with test keys, in the v2 sandbox."},"day":{"type":"string","format":"date"}},"required":["v1","v2","test","day"],"additionalProperties":false}},"topEndpoints":{"type":"array","items":{"type":"object","properties":{"endpoint":{"type":"string","description":"The method and path, such as `GET /v2/events`."},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["endpoint","count"],"additionalProperties":false}}},"required":["totals","v2Share","days","topEndpoints"],"additionalProperties":false},"WebhookEndpoint":{"type":"object","properties":{"webhookId":{"type":"string"},"url":{"type":"string"},"description":{"type":["string","null"]},"mode":{"type":"string","enum":["live","test"],"description":"`test` endpoints receive events from the sandbox."},"payloadVersion":{"type":"string","enum":["v1","v2"],"description":"With `v1`, the endpoint receives v1 deliveries, as it did before v2. With `v2`, it receives signed v2 deliveries of the types in `events`, which are retried and recorded."},"events":{"type":"array","items":{"type":"string"},"description":"The v2 event types the endpoint receives, or `*` for all types."},"triggers":{"type":"array","items":{"type":"string"},"description":"The v1 triggers the endpoint receives. Used only with v1 payloads."},"status":{"type":"string","enum":["active","disabled"]},"disabledReason":{"type":["string","null"]},"disabledAt":{"type":["string","null"]},"auth":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["header","bearer"]},"name":{"description":"The name of the header the credential is sent in, when `type` is `header`.","type":["string","null"]}},"required":["type","name"],"additionalProperties":false},{"type":"null"}],"description":"The credential Pyas sends to your endpoint with each delivery, if any. Its value is never returned."},"signingSecret":{"anyOf":[{"type":"object","properties":{"last4":{"type":["string","null"]}},"required":["last4"],"additionalProperties":false},{"type":"null"}],"description":"Set for endpoints with v2 payloads. To retrieve the full secret, call `GET /v2/webhooks/:webhookId/secret`."},"consecutiveFailures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The number of consecutive deliveries that failed after every attempt. The endpoint is disabled after 50 consecutive failed deliveries."},"createdAt":{"type":["string","null"]},"updatedAt":{"type":["string","null"]}},"required":["webhookId","url","description","mode","payloadVersion","events","triggers","status","disabledReason","disabledAt","auth","signingSecret","consecutiveFailures","createdAt","updatedAt"],"additionalProperties":false},"WebhookDelivery":{"type":"object","properties":{"deliveryId":{"type":"string"},"webhookId":{"type":"string"},"eventId":{"type":"string"},"eventType":{"type":"string"},"accountId":{"type":["string","null"]},"status":{"type":"string","enum":["pending","retrying","delivered","failed"]},"attempts":{"type":"array","items":{"type":"object","properties":{"n":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"at":{"type":"string"},"httpStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"responseBody":{"description":"The first 1 KB of the response body.","type":["string","null"]},"responseTimeMs":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"error":{"type":["string","null"]}},"required":["n","at","httpStatus","responseBody","responseTimeMs","error"],"additionalProperties":false}},"nextAttemptAt":{"type":["string","null"]},"replays":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["deliveryId","webhookId","eventId","eventType","accountId","status","attempts","nextAttemptAt","replays","createdAt","completedAt"],"additionalProperties":false},"WebhookEvent":{"type":"object","properties":{"eventId":{"type":"string"},"type":{"type":"string"},"accountId":{"type":["string","null"]},"subjectId":{"type":["string","null"]},"provider":{"type":["string","null"]},"createdAt":{"type":"string"},"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The payload, exactly as delivered."}},"required":["eventId","type","accountId","subjectId","provider","createdAt","payload"],"additionalProperties":false}}}}