Skip to content
Skip to main content

Add attachments to a calendar event

Last updated:

You’re building an event flow and the design says “attach the agenda PDF to the invite.” So you reach for an attachments field on the event create request, and it isn’t there. That’s not a bug. Calendar events aren’t email messages, and most calendar APIs treat file attachments as either provider-specific or off-limits. The fix is to attach the file where attendees actually open it: a link in the event description, a conferencing block for the call, and metadata for your own bookkeeping.

This guide shows what the Nylas Calendar API supports on an event, why true file attachments behave differently from email, and how to attach files and links so they reach every attendee across Google, Microsoft, iCloud, and the rest.

Does the Calendar API support file attachments on events?

Section titled “Does the Calendar API support file attachments on events?”

The Nylas event_create schema has no attachments field, so you can’t upload a file directly onto a calendar event the way you do with a message. Events support a fixed set of create fields, including description, conferencing, location, participants, and metadata. To attach a document, you put a link to it in the description, which every provider renders in the invite body.

This is the biggest difference from the Messages API, where attachments is a first-class array and the request size limit is 25 MB. Calendar providers don’t store binary files on an event object. Google Calendar can reference Drive files, and Microsoft Graph can attach files to its own events, but neither exposes a portable file-upload field that works the same across providers. So a link in the description is the one approach that behaves identically on Google, Microsoft, iCloud, and EWS calendars. Host the file in your own storage or a shared drive, then reference the public or signed URL.

How do I add attachments to a Google Calendar event using the API?

Section titled “How do I add attachments to a Google Calendar event using the API?”

Through Nylas, you attach a file to a Google Calendar event by putting its URL in the event description. The POST /v3/grants/{grant_id}/events endpoint accepts a description string that Google renders as the invite body, where attendees click the link. For Google accounts, this field accepts up to 8,192 characters, enough for several signed file URLs.

The request below creates a Google Calendar event with a linked document and a set of participants. The calendar_id query parameter is required, and when is the only required body field. Pass notify_participants=true so Google emails the invite, link included, to all 2 attendees.

If you only need Google and want a real file object on the event, the native Google Calendar API supports it: events.insert with supportsAttachments=true and an attachments[] array of Drive file links. That’s Google-only, requires the Drive scope, and won’t carry over to a Microsoft or iCloud attendee. The unified description-link approach trades that one provider feature for code that runs the same everywhere.

What does a calendar event management system need from a calendar API?

Section titled “What does a calendar event management system need from a calendar API?”

A calendar event management system needs five things from a calendar API: create, read, update, and delete on events, plus participant handling. The Nylas Calendar API covers all five through POST, GET, PUT, and DELETE on /v3/grants/{grant_id}/events, with participants, conferencing, recurrence, and metadata as fields on the event itself. One schema spans every supported calendar provider.

Beyond raw CRUD, a production system needs a few more guarantees. It needs idempotent updates, which PUT /v3/grants/{grant_id}/events/{event_id} gives you by replacing the full nested object. It needs your own application data on each event, which the metadata field stores as up to 50 key-value pairs, each value capped at 500 characters, so you can stash a document ID or a workflow status. It needs change notifications, which calendar webhooks deliver without polling. And it needs to attach context to the invite, which the description-link pattern handles. Building that against Google’s API, Microsoft Graph, and CalDAV separately means three integrations. Want the file on the event? Reference it once in the description and every provider shows it.

How do I create calendar events with participants?

Section titled “How do I create calendar events with participants?”

Pass a participants array to POST /v3/grants/{grant_id}/events, where each entry needs an email and optionally a name. Each participant becomes an attendee on the provider’s invite. Set the notify_participants query parameter to true and the provider emails everyone the invite, including any links you placed in the description. The email field is the only required property per participant.

The request below creates an event with three attendees and an attached resource link in the body. One thing to watch: Microsoft and iCloud ignore the notify_participants flag and always send notifications, so expect attendees on those providers to get an email regardless of what you pass. The participants array has no documented size cap in the schema, but provider limits apply, so keep large invites reasonable.

Section titled “Native file attachments vs description links”

If you’ve shipped against the Google Calendar API before, you know events.insert accepts an attachments[] array of Drive files. It works, but it’s Google-only and the file has to live in Drive. The table compares attaching a real file object per provider against the unified link approach. The Nylas column is the one that runs unchanged across every provider.

ApproachNative provider APINylas description link
File on eventGoogle attachments[] (Drive only); Microsoft Graph event attachmentsLink in description, up to 8,192 chars on Google
Cross-providerDifferent field or unsupported per providerOne field, works on every supported calendar provider
StorageMust live in Google Drive or OneDriveAny URL you host or sign
ScopesExtra Drive or files scopeStandard calendar scope only
Code pathsOne integration per provider1 unified call

The honest tradeoff: if your app is Google-only and your files already live in Drive, the native attachments[] array gives users an inline file chip on the event, which a plain link doesn’t. That’s a real UX win for a single-provider build. The moment you add Microsoft or iCloud, that chip disappears and you’re back to maintaining separate code, so the link approach wins on reach.

Section titled “Things to know about event links and metadata”

A few rules shape how attached links behave on calendar events. Google renders the description as HTML in many cases, so a raw URL usually becomes clickable, but test your formatting because providers differ. Keep URLs signed and short-lived if the file is sensitive, since anyone with the invite can read the description. Don’t store the file contents in metadata: each value caps at 500 characters and the field is for your application’s IDs, not document bodies.

For recurring invites, the description and its links apply to the whole series unless you update a single instance. Stripping a link later means a PUT that replaces the description, since the update replaces the full field rather than patching it. If you need a guaranteed inline file object on Google specifically, drop to the native Google Calendar API for that one provider and keep Nylas for the rest. The Google Calendar API events reference documents the supportsAttachments parameter in full.