Google Apps Platform

Google Calendar API v1 Developer's Guide: Protocol

This API is a subject to the Deprecation Policy and will be deprecated on November 17, 2014. Please use APIv3 instead.

Google Calendar allows client applications to view and update calendar events in the form of Google Data API feeds. Your client application can use the Google Calendar Data API to create new events, edit or delete existing events, and query for events that match particular criteria.

There are many possible uses for the Calendar Data API. For example, you can create a web front end for your group's calendar that uses Google Calendar as a back end. Or you can generate a public calendar for Google Calendar to display, based on your organization's event database. Or you can search relevant calendars to display a list of upcoming events on those calendars.

In addition to providing some background on the capabilities of the Google Calendar Data API, this document provides examples interacting with the API by sending HTTP messages containing XML formatted messages. If you're using one of our client libraries to interact with the API, you may also be interested in exploring the examples found on the appropriate tab above.

Contents

Audience

This document is intended for programmers who want to write client applications that can interact with Google Calendar. It provides a series of examples of basic Data API interactions using raw XML/HTTP, with explanations. After reading this document, you may wish to learn more about interacting with the API using our client libraries by reading the language-specific examples found on the other tabs at the top of this document.

For Calendar Data API reference information, see the reference guide. This document assumes that you understand the general ideas behind the Google Data APIs protocol. Each example in this document shows how to use the bare protocol to interact with Calendar.

Terms of use

You agree to abide by the Google Calendar Terms of Use when using the Calendar Data API.

Authenticating to the Calendar service

Inserting, updating or deleting entries requires authenticating using one of the two different authentication systems supported by services. The appropriate method of authentication depends on the type of client you're writing.

If your client is a standalone single-user "installed" client (such as a desktop application), then you should use the ClientLogin system; if your client is a multi-user web application client, then you should use the AuthSub system. Both of these methods involve interacting with an authentication service. The authentication service returns an authentication token that your client can then send to the Calendar Data API service along with every subsequent request on behalf of that user.

AuthSub proxy authentication

AuthSub proxy authentication is used by web applications which need to authenticate their users to Google accounts. The website operator does not need access to the username and password for the user - only special AuthSub tokens are required. Please see the AuthSub documentation for more detailed information.

To acquire an AuthSub token for a given user, your application must redirect the user to the AuthSubRequest URL, which prompts them to log into their Google account. The AuthSubRequest URL might look like this:

https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Fwww.google.com%2fcalendar%2Ffeeds%2F&session=1&secure=0&next=http%3A%2F%2Fwww.coolcalendarsite.com%2Fwelcome.html

Notice the query parameters sent to the AuthSubRequest URL:

Parameter Description
scope A base URL for feed requests. For Google Calendar feeds this value is https://www.google.com/calendar/feeds/.
session Indicates whether the token returned can be exchanged for a multi-use (session) token.
secure Indicates whether the token returned will be a secure token.
next The URL of the page that Google should redirect the user to after authentication.

After the user logs in, the AuthSub system redirects them to the URL you specified in the next query parameter of the AuthSubRequest URL. The AuthSub system appends an authentication token to that URL, as the value of the token query parameter like this:

http://www.coolcalendarsite.com/welcome.html?token=yourAuthToken

This token value represents a single-use AuthSub token. Since session = True was specified above, this token can be exchanged for an AuthSub session token using by calling the AuthSubSessionToken service with the single-use token in an Authorization header like this:

GET /accounts/AuthSubSessionToken HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="yourAuthToken"
User-Agent: Java/1.5.0_06
Host: https://www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

The AuthSubSessionToken service response will include a Token header that contains the session token and an Expiration header that indicates how long the token will remain valid. Your server-side application can use the session token value in the Authorization header of subsequent interactions with Google Calendar. Here's an example of a HTTP request you would send to the Google Calendar feed service that contains a non-secure token:

GET /calendar/feeds/default/private/full HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="yourSessionToken"
User-Agent: Java/1.5.0_06
Host: www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

ClientLogin username/password authentication

The ClientLogin method requires having access to the username and password for a Google Account. To receive an authentication token using the ClientLogin mechanism, send a POST request to the following URL:

https://www.google.com/accounts/ClientLogin

The POST body should contain a set of query parameters, as described in the following table. They should look like parameters passed by an HTML form, using the application/x-www-form-urlencoded content type.

Parameter Description
Email The user's email address.
Passwd The user's password.
source Identifies your client application. Should take the form companyName-applicationName-versionID; below, we'll use the name exampleCo-exampleApp-1.
service The string cl, which is the service name for Google Calendar.

If the authentication request fails, you'll receive an HTTP 403 Forbidden status code.

If it succeeds, then the response from the service is an HTTP 200 OK status code, plus three long alphanumeric codes in the body of the response: SID, LSID, and Auth. The Auth value is the authorization token that you'll send to Calendar with your request, so keep a copy of that value. You can ignore the SID and LSID values.

Since all requests to private feeds require authentication, you have to set the Authorization header in the request, using the following format:

Authorization: GoogleLogin auth=yourAuthToken

Where yourAuthToken is the Auth string returned by the login request.

As mentioned earlier, this authentication system (known as "Google Authentication for Installed Applications"; also known as "ClientLogin") is appropriate only for use in installed client applications such as desktop clients, not for use in web applications. For web applications, you should instead use the account authentication proxy, also known as "AuthSub".

For more information about authentication, including detailed instructions for using AuthSub, see the Google Data APIs Authentication Overview and the Google Account Authentication documentation.

Magic cookie authentication

The simplest feed URL to use is that of the calendar's read-only, "magic cookie" private feed, because that URL doesn't require authentication. The usual procedure for determining that URL involves using a JavaScript-enabled GUI browser to get the URL manually. If you can't or don't want to use such a browser, then you can instead interact with Calendar using one of the other feed URLs, which require authentication, but which you can construct without using a browser.

To find your calendar's "magic cookie" feed URL:

  1. In the list of calendars on the left side of the page, find the calendar you want to interact with. You can create a new calendar for this purpose if you want to.
  2. Click the arrow button to the right of the calendar. Select "Calendar settings" from the drop-down menu. The Calendar Details page appears.
  3. Scroll down to the Private Address section and select the XML button. The feed URL appears.
  4. Copy the URL. This is the URL of your calendar's read-only "magic cookie" private feed; it includes a special coded string that lets you read the private feed without having to do authentication. This is the URL you'll use to request a feed from Calendar, so you won't have to do authentication just to view the feed.

The feed URL has the following form:

https://www.google.com/calendar/feeds/userID/private-magicCookie/basic

You can modify this URL in the following ways:

  • If you want a private feed that requires authentication, convert the "private-{magic-cookie}" part of this path to just "private".
  • If you want the "full" calendar project, change the last component from "basic" to "full". (A similar "composite" feed is also available. For more information, see the section on comments.)

The "basic" form of the feed holds event information that is formatted for reading, more suited to human consumption of the feed. The "full" form of the feed holds structured events that are represented as "Kinds", so they are more suited to computer processing.

If you're looking at settings for the user's main calendar, then userID is the user's email address. If you're looking at settings for another calendar, then userID is a longer and more complicated email address. In either case, magicCookie is a special code that lets you read the private feed without having to do authentication. Here's an example of a feed URL:

https://www.google.com/calendar/feeds/jo@gmail.com/private-08ce2fac8efa42f2a0d04eceb7d68cc9/full

Under some circumstances, you may want to generate a new "magic cookie" URL. (Note that if someone else gets access to that URL, they can view your calendar without authentication.) To do that, click the "Reset Private URLs" link in the Calendar Details page.

Retrieving settings (Experimental)

The Calendar Data API provides access to a read-only view of a user's current settings as set within the Google Calendar HTML interface. This can be retrieved by sending an authenticated GET request to the settings feed URL:

https://www.google.com/calendar/feeds/userId/settings

The result is a feed that includes all of the user's settings as key/value pairs:

    <?xml version="1.0" encoding="UTF-8"?>
    <feed xmlns="http://www.w3.org/2005/Atom"
        xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
        xmlns:gCal="http://schemas.google.com/gCal/2005">
      <id>http://www.google.com/calendar/feeds/default/settings</id>
      <updated>2009-03-05T10:46:25.244Z</updated>
      <title type="text">Coach's's personal settings</title>
      <link rel="alternate" type="text/html" href="https://www.google.com/calendar/feeds/render"/>
      <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings"/>
      <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings"/>
      <author>
        <name>Coach</name>
        <email>user@gmail.com</email>
      </author>
      <generator version="1.0" uri="http://www.google.com/calendar">Google Calendar</generator>
      <openSearch:startIndex>1</openSearch:startIndex>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/alternateCalendar</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/alternateCalendar"/>
        <gCal:settingsProperty name="alternateCalendar" value="0"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/country</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/country"/>
        <gCal:settingsProperty name="country" value="EH"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/customCalMode</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/customCalMode"/>
        <gCal:settingsProperty name="customCalMode" value="custom,14"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/dateFieldOrder</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/dateFieldOrder"/>
        <gCal:settingsProperty name="dateFieldOrder" value="MDY"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/defaultCalMode</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/defaultCalMode"/>
        <gCal:settingsProperty name="defaultCalMode" value="custom"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/displayAllTimezones</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/displayAllTimezones"/>
        <gCal:settingsProperty name="displayAllTimezones" value="false"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/format24HourTime</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/format24HourTime"/>
        <gCal:settingsProperty name="format24HourTime" value="false"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/hideInvitations</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/hideInvitations"/>
        <gCal:settingsProperty name="hideInvitations" value="false"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/hideWeekends</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/hideWeekends"/>
        <gCal:settingsProperty name="hideWeekends" value="false"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/locale</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/locale"/>
        <gCal:settingsProperty name="locale" value="en"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/showDeclinedEvents</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/showDeclinedEvents"/>
        <gCal:settingsProperty name="showDeclinedEvents" value="true"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/timezone</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/timezone"/>
        <gCal:settingsProperty name="timezone" value="America/Los_Angeles"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/timezoneLabel</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/timezoneLabel"/>
        <gCal:settingsProperty name="timezoneLabel" value=""/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/userLocation</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/userLocation"/>
        <gCal:settingsProperty name="userLocation" value="94043"/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/weather</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/weather"/>
        <gCal:settingsProperty name="weather" value=""/>
      </entry>
      <entry>
        <id>http://www.google.com/calendar/feeds/default/settings/weekStart</id>
        <updated>2009-03-05T10:46:25.245Z</updated>
        <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/settings/weekStart"/>
        <gCal:settingsProperty name="weekStart" value="0"/>
      </entry>
    </feed>
    

A list of settings and their values can be found in the reference guide under gCal:settingsProperty.

Retrieving calendar lists

The Calendar Data API provides several ways to access the list of calendars that appear in the Google Calendar web application. There are three types of calendars in this list: primary, secondary, and imported calendars. A primary calendar is created for a user when they sign up for a Google Calendar account. All other calendars created by that user are called secondary calendars. Imported calendars are calendars that a user subscribes to that someone else has created.

Retrieving all calendars

You can get a list of a user's calendars by sending an authenticated GET request to the allcalendars feed URL:

https://www.google.com/calendar/feeds/default/allcalendars/full

The result is a feed that includes all primary, secondary, and imported calendars:

<feed xmlns='http://www.w3.org/2005/Atom'
      xmlns:gd='http://schemas.google.com/g/2005'
      xmlns:gCal='http://schemas.google.com/gCal/2005'>
  <id>http://www.google.com/calendar/feeds/default/allcalendars/full</id>
  <updated>2007-07-11T22:10:30.252Z</updated>
  <title type="text">Coach's Calendar List</title>
  <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/allcalendars/full"/>
  <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/allcalendars/full"/>
  <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/allcalendars/full"/>
  <author>
    <name>Coach</name>
    <email>user@gmail.com</email>
  </author>
  <generator version="1.0" uri="http://www.google.com/calendar">Google Calendar</generator>
  <openSearch:startIndex>1</openSearch:startIndex>
  <entry>
    <id>http://www.google.com/calendar/feeds/default/allcalendars/full/user%40gmail.com</id>
    <published>2007-07-11T22:10:30.257Z</published>
    <updated>2007-07-11T21:46:35.000Z</updated>
    <title type="text">My Primary Calendar</title>
    <summary type="text">A primary calendar is created by default for each Google Calendar user.</summary>
    <link rel="alternate" type="text/html" href="https://www.google.com/calendar/feeds/user%40gmail.com/private/full"/>
    <link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="https://www.google.com/calendar/feeds/user%40gmail.com/acl/full"/>
    <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/allcalendars/full/user%40gmail.com"/>
    <author>
      <name>Coach</name>
      <email>user@gmail.com</email>
    </author>
    <gCal:timezone value="America/Los_Angeles"/>
    <gCal:hidden value="false"/>
    <gCal:color value="#2952A3"/>
    <gCal:selected value="true"/>
    <gCal:accesslevel value="owner"/>
    <gd:where valueString="Mountain View"/>
  </entry>
  <entry>
    <id>http://www.google.com/calendar/feeds/default/allcalendars/full/rf1c66uld6dgk2t5lh43svev6g%40group.calendar.google.com</id>
    <published>2007-07-11T22:10:30.258Z</published>
    <updated>2007-07-11T21:50:15.000Z</updated>
    <title type="text">Little Giants</title>
    <summary type="text">This calendar contains practice times and this season's Little League game schedule.  Go Little Giants!</summary>
    <link rel="alternate" type="text/html" href="https://www.google.com/calendar/feeds/rf1c66uld6dgk2t5lh43svev6g%40group.calendar.google.com/private/full"/>
    <link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="https://www.google.com/calendar/feeds/rf1c66uld6dgk2t5lh43svev6g%40group.calendar.google.com/acl/full"/>
    <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/allcalendars/full/rf1c66uld6dgk2t5lh43svev6g%40group.calendar.google.com"/>
    <author>
      <name>Little Giants</name>
    </author>
    <gCal:timezone value="America/Los_Angeles"/>
    <gCal:hidden value="false"/>
    <gCal:color value="#5A6986"/>
    <gCal:selected value="false"/>
    <gCal:accesslevel value="owner"/>
    <gd:where valueString="San Fransisco"/>
  </entry>
  <entry>
    <id>http://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com</id>
    <published>2007-07-11T22:10:30.297Z</published>
    <updated>2007-06-05T09:38:50.000Z</updated>
    <title type="text">Google Doodles</title>
    <summary type="text"/>
    <link rel="alternate" type="text/html" href="https://www.google.com/calendar/feeds/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com/private/full"/>
    <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com"/>
    <author>
      <name>Google Doodles</name>
    </author>
    <gCal:timezone value="Etc/GMT"/>
    <gCal:hidden value="false"/>
    <gCal:color value="#5229A3"/>
    <gCal:selected value="false"/>
    <gCal:accesslevel value="read"/>
    <gd:where valueString=""/>
  </entry>
</feed>

There are several new elements here, all in the gCal namespace. For information about those elements, see GCal namespace element reference.

Note: This feed is accessible only using an authentication token, so you cannot use a magic cookie URL to access the feed. For information on authentication, see the earlier Authenticating to the Calendar service section.

Retrieving only calendars that a user owns

There is also an owncalendars feed that you can query to retrieve the list of calendars that the authenticated user has owner access to. The owncalendars feed is located at:

https://www.google.com/calendar/feeds/default/owncalendars/full

Querying this feed will return a list of calendars that includes the user's primary and secondary calendars, as well as any imported calendars for which the user has been granted ownership. The feed will resemble the feed in the previous example, but it will contain only calendars where the <gCal:accesslevel> has a value of owner.

Managing Calendars

The owncalendars feed can also be used to create, update, and delete calendars. Calendars created through the owncalendars feed will be secondary calendars.

Creating new calendars

To create a new calendar, first create the XML for a calendar <entry> element like the ones in the previous example. For example, you might create the following XML to represent a calendar to keep track of your Little League team:

<entry xmlns='http://www.w3.org/2005/Atom'
       xmlns:gd='http://schemas.google.com/g/2005'
       xmlns:gCal='http://schemas.google.com/gCal/2005'>
  <title type='text'>Little League Schedule</title>
  <summary type='text'>This calendar contains the practice schedule and game times.</summary>
  <gCal:timezone value='America/Los_Angeles'></gCal:timezone>
  <gCal:hidden value='false'></gCal:hidden>
  <gCal:color value='#2952A3'></gCal:color>
  <gd:where rel='' label='' valueString='Oakland'></gd:where>
</entry>

To insert this calendar, send an HTTP POST message with this calendar <entry> element in the message body, using the application/atom+xml content type, to the owncalendars feed URL:

POST https://www.google.com/calendar/feeds/default/owncalendars/full

Upon success, the server will respond with an HTTP 201 Created message that contains the calendar <entry> element you submitted, but with some additional elements (shown in bold) that are set by the server such as <atom:id>, <atom:published>, <atom:updated>, and mulitple <atom:link> elements:

<entry xmlns='http://www.w3.org/2005/Atom'
       xmlns:gCal='http://schemas.google.com/gCal/2005'
       xmlns:gd='http://schemas.google.com/g/2005'>
  <id>http://www.google.com/calendar/feeds/default/owncalendars/full/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com</id>
  <published>2007-07-12T16:46:11.815Z</published>
  <updated>2007-07-12T16:46:11.000Z</updated>
  <title type='text'>Little League Schedule</title>
  <summary type='text'>This calendar contains the practice schedule and game times.</summary>
  <link rel='alternate' type='text/html' href='https://www.google.com/calendar/feeds/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com/private/full'/>
  <link rel='http://schemas.google.com/acl/2007#accessControlList' type='application/atom+xml' href='https://www.google.com/calendar/feeds/ppgcfga9qo8jmdwan231w7s8h44%40group.calendar.google.com/acl/full'/>
  <link rel='self' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/owncalendars/full/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com'/>
  <link rel='edit' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/owncalendars/full/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com'/>
  <author>
    <name>Little League Schedule</name>
  </author>
  <gCal:timezone value='America/Los_Angeles'/>
  <gCal:hidden value='false'/>
  <gCal:color value='#2952A3'/>
  <gCal:selected value='false'/>
  <gCal:accesslevel value='owner'/>
  <gd:where valueString='Oakland'/>
</entry>

Updating existing calendars

You can update most information about a user's calendar via the owncalendars feed. You'll need to parse out the calendar entry's edit URL. This URL is found in the <link> element where the value of the rel attribute is edit:

<link rel='edit' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/allcalendars/full/calendarId'></link>

To update the calendar, send an HTTP PUT to the edit URL with the updated calendar <entry> element in the message body. The following entry will update the calendar's title and color, and mark it as selected:

PUT https://www.google.com/calendar/feeds/default/owncalendars/full/calendarID

<entry xmlns='http://www.w3.org/2005/Atom'
       xmlns:gCal='http://schemas.google.com/gCal/2005'
       xmlns:gd='http://schemas.google.com/g/2005'>
  <id>http://www.google.com/calendar/feeds/default/owncalendars/full/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com</id>
  <published>2007-07-12T16:46:11.815Z</published>
  <updated>2007-07-12T16:46:11.000Z</updated>
  <title type='text'>New Title</title>
  <summary type='text'>This calendar contains the practice schedule and game times.</summary>
  <link rel='alternate' type='text/html' href='https://www.google.com/calendar/feeds/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com/private/full'/>
  <link rel='http://schemas.google.com/acl/2007#accessControlList' type='application/atom+xml' href='https://www.google.com/calendar/feeds/ppgcfga9qo8jmdwan231w7s8h44%40group.calendar.google.com/acl/full'/>
  <link rel='self' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/owncalendars/full/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com'/>
  <link rel='edit' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/owncalendars/full/ppgcfga9qo8jmdwan231w7s8h4%40group.calendar.google.com'/>
  <author>
    <name>Little League Schedule</name>
  </author>
  <gCal:timezone value='America/Los_Angeles'/>
  <gCal:hidden value='false'/>
  <gCal:color value='#0D7813'/>
  <gCal:selected value='true'/>
  <gCal:accesslevel value='owner'/>
  <gd:where valueString='Oakland'/>
</entry>

Deleting calendars

Calendars are deleted by sending a DELETE request to the calendar's edit URL. This is the same URL used to update the calendar. For example, to delete the above calendar send the following HTTP request:

DELETE /calendar/feeds/default/owncalendars/full/ppgcfga9qo8jmdwan231w7s8h44%40group.calendar.google.com

Note: You can't delete a user's primary calendar, i.e. the calendar with the user's email address in the ID. If you try to delete a primary calendar you will get an HTTP 400 Bad Request error.

Managing subscriptions to calendars

The allcalendars feed can be used to modify the list of imported calendars that a user has subscribed to. Calendars inserted via the allcalendars feed will be added as imported calendars.

Adding new subscriptions

To subscribe to an existing calendar, you first need to find the calendar's ID. The calendar ID is available on the calendar settings page, next to the Calendar Address buttons. If you're subscribing to a user's primary calendar, the id will just be the user's email address.

Once you have the calendar ID, create a calendar <entry> element that contains the <atom:id> of the calendar you wish to subscribe to. For example, you could use the following XML to subscribe to the Google Doodles calendar:

<entry xmlns='http://www.w3.org/2005/Atom'
  <id>c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com</id>
</entry>

To then subscribe to the Google Doodles calendar, send an HTTP POST message to the allcalendars feed URL with this calendar <entry> element in the message body (using the application/atom+xml content type):

POST https://www.google.com/calendar/feeds/default/allcalendars/full

Upon success, the server will respond with an HTTP 201 Created message that contains the calendar <entry> that corresponds to the calendar you subscribed to. This calendar <entry> will be populated with data specific to the Google Doodles calendar such as the <title>, <summary>, and <gd:where>, as well as elements that are specific to this subscription, such as <gCal:color>, <gCal:hidden>, and <gCal:selected>. Here's an example of the XML returned by the server, with personalization settings shown in bold:

<entry xmlns='http://www.w3.org/2005/Atom'
       xmlns:gCal='http://schemas.google.com/gCal/2005'
       xmlns:gd='http://schemas.google.com/g/2005'>
  <id>http://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com</id>
  <published>2007-07-12T17:09:08.033Z</published>
  <updated>2007-06-05T09:38:50.000Z</updated>
  <title type='text'>Google Doodles</title>
  <summary type='text'></summary>
  <link rel='alternate' type='text/html' href='https://www.google.com/calendar/feeds/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com/private/full'/>
  <link rel='self' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com'/>
  <link rel='edit' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com'/>
  <author>
    <name>Google Doodles</name>
  </author>
  <gCal:timezone value='Etc/GMT'/>
  <gCal:hidden value='false'/>
  <gCal:color value='#2952A3'/>
  <gCal:selected value='true'/>
  <gCal:accesslevel value='read'/>
  <gd:where valueString=''/>
</entry>

Updating calendar subscriptions

You can update the following personalization settings of a calendar using the allcalendars feed:

  • color - the color of the calendar in the UI.
  • hidden - whether or not the calendar is shown in the UI.
  • selected - whether or not the calendar is selected in the UI.

The personalization settings can be modified with the allcalendars feed even if the user doesn't own the calendar. However, the title and summary of the calendar can only be updated by an owner of the calendar using the owncalendars feed.

To update a subscription you'll need to parse out the calendar entry's edit URL. This URL is found in the <link> element where the value of the rel attribute is edit:

<link rel='edit' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/allcalendars/full/calendarId'></link>

Send an HTTP PUT to the edit URL with the updated calendar <entry> element in the message body. The following entry will update the color and unselected the calendar:

PUT https://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com

<entry xmlns='http://www.w3.org/2005/Atom'
       xmlns:gCal='http://schemas.google.com/gCal/2005'
       xmlns:gd='http://schemas.google.com/g/2005'>
  <id>http://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com</id>
  <published>2007-07-12T17:09:08.033Z</published>
  <updated>2007-06-05T09:38:50.000Z</updated>
  <title type='text'>Google Doodles</title>
  <summary type='text'></summary>
  <link rel='alternate' type='text/html' href='https://www.google.com/calendar/feeds/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com/private/full'/>
  <link rel='self' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com'/>
  <link rel='edit' type='application/atom+xml' href='https://www.google.com/calendar/feeds/default/allcalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com'/>
  <author>
    <name>Google Doodles</name>
  </author>
  <gCal:timezone value='Etc/GMT'/>
  <gCal:hidden value='false'/>
  <gCal:color value='#A32929'/>
  <gCal:selected value='false'/>
  <gCal:accesslevel value='read'/>
  <gd:where valueString=''/>
</entry>

Deleting subscriptions

Subscriptions are deleted by sending a DELETE request to the calendar's edit URL. This is the same URL used to update the subscription. For example, to delete the subscription to the Google Doodles calendar, send the following HTTP request:

DELETE /calendar/feeds/default/owncalendars/full/c4o4i7m2lbamc4k26sc2vokh5g%40group.calendar.google.com

Retrieving events

Retrieving events without query parameters

The general idea of how to request a Calendar feed is that you determine the URL of the feed type you want (see Calendar feed types), and then you send an HTTP GET request for that URL. Calendar then returns a Data API feed containing calendar events, each of which is an Event kind. For more information about kinds, see the Kinds document.

Google provides client libraries for interacting with Google Data API services in a variety of programming languages. You can use the client libraries to send the HTTP request and handle the returned feed; see the other tabs of this document for information on how to do this in various languages. But whether or not you use the client library, the following is what's going on at the protocol level. If you're using a UNIX system and you want to try this out without writing any code, you may find the UNIX command-line utilities curl or wget useful; for more information, see the manual pages for those utilities.

To get a feed, you send the following HTTP request to Calendar, using the URL you found in the previous section of this document:

GET https://www.google.com/calendar/feeds/userID/private-magicCookie/full

(With the appropriate values in place of userID and magicCookie, of course.)

When you send that GET request, Calendar may return an HTTP 302 redirect; the redirect URL has a new query parameter, gsessionid, appended to it. (Note that some methods of sending the GET request may not show you the response headers by default; if you receive a blank response, check your HTTP utility's documentation to find out how to view response headers.) That gsessionid parameter is the way that Calendar keeps track of your session, to improve speed of response.

(Some methods of sending the GET request may automatically follow redirects, and in some cases Calendar may not send a redirect at all; in such cases, you don't need to send the second request described below.)

So after you've sent the GET request, you have to read the HTTP headers of the response to find the URL with the session ID appended; then you need to send another GET request with that new URL. (Note that if you're using the UNIX command line to send requests, you may have to precede the question mark in the new URL with a backslash to keep your shell from interpreting it.)

In response to the second GET request, Calendar returns an HTTP 200 OK status code and a feed containing all the events in your calendar. If there's only one event in your calendar, then Calendar returns something similar to the following feed. We've edited the following example a little to make it a little more readable by humans; in particular, a real Calendar feed contains actual magic-cookie values and entry IDs.

<feed xmlns='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'>
  <id>http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full</id>
  <updated>2006-03-29T07:35:59.000Z</updated>
  <title type='text'>Jo March</title>
  <subtitle type='text'>This is my main calendar.</subtitle>
  <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full'></link>
  <link rel='self' type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full'></link>
  <author>
    <name>Jo March</name>
    <email>jo@gmail.com</email>
  </author>
  <generator version='1.0' uri='http://www.google.com/calendar/'>CL2</generator>
  <gd:where valueString='California'></gd:where>
  <entry>
    <id>http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID</id>
    <published>2006-03-30T22:00:00.000Z</published>
    <updated>2006-03-28T05:47:31.000Z</updated>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/g/2005#event'></category>
    <title type='text'>Lunch with Darcy</title>
    <content type='text'>Lunch to discuss future plans.</content>
    <link rel='alternate' type='text/html'
      href='https://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
      title='alternate'></link>
    <link rel='self' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID'></link>
    <author>
      <name>Jo March</name>
      <email>jo@gmail.com</email>
    </author>
    <gd:transparency
      value='http://schemas.google.com/g/2005#event.opaque'></gd:transparency>
    <gd:eventStatus
      value='http://schemas.google.com/g/2005#event.confirmed'></gd:eventStatus>
    <gd:comments>
      <gd:feedLink
        href='https://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID/comments/'></gd:feedLink>
    </gd:comments>
    <gd:when startTime='2006-03-30T22:00:00.000Z'
      endTime='2006-03-30T23:00:00.000Z'></gd:when>
    <gd:where></gd:where>
  </entry>
</feed>

For information about what each of those elements means, see the Google Data APIs Protocol Reference document and the Calendar elements reference.

If your request fails for some reason, Calendar may return a different status code; for information about the status codes, see the Google Data API Protocol Reference document.

Note: The events in a feed are ordered by the values of their updated elements by default, with the most recently updated event appearing first in the feed. For information on changing the ordering, see Calendar query parameters reference.

Retrieving events for a specified date range

The Calendar Data API lets you request a set of entries that match specified criteria. In addition to the standard Data API query parameters, Calendar provides two additional query parameters, start-min and start-max, to let you request all events that fall within or overlap a range of dates. For more information, see Calendar query parameters reference.

It's a good idea to limit your queries to a range of dates if you're not limiting them in any other way, just to avoid retrieving all entries ever posted to the calendar.

Here's how to create and send a date-range query at the protocol level:

First, authenticate the user, if you haven't already done so. See the previous example for information on how to do that.

Then send an HTTP request like the following to Calendar, using the special "default" URL:

GET https://www.google.com/calendar/feeds/default/private/full?start-min=2006-03-16T00:00:00&start-max=2006-03-24T23:59:59

Be sure to include the Authorization header in the request, as described in the previous example.

When you send that GET request, Calendar may return an HTTP 302 redirect with a gsessionid appended to it, just like in the earlier examples. In that case, read the HTTP headers of the response to find the URL with the session ID appended; then send another GET request with that new URL. (This second GET request also needs to have the Authorization header set.)

In response to the second GET request (or the first one if there was no redirect), Calendar returns an HTTP 200 OK status code and a feed containing any event that overlaps the minimum and maximum start times you specified.

Retrieving events matching a full text query

Google Calendar supports full-text queries that search the title and content of an event. To perform a full-text query send an HTTP request using the 'q' parameter in the URL.

GET https://www.google.com/calendar/feeds/default/private/full?q=Tennis

To query using standard Data API query parameters, just change the URL to use other parameters.

Note: Google Calendar doesn't support Data API category queries.

Creating events

The Calendar Data API allows you to create two types of events: single-occurrence events and recurring events, which are set up to repeat on a predetermined schedule.

Creating single-occurrence events

Adding an event to a calendar is a little bit more complicated than getting a feed, because you need to create the XML code or client-library object representing the event, and you need to use authentication.

First, create an entry of the Event kind. (For more information about kinds, see the Kinds document.) For example, you might create the following entry:

<entry xmlns='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/g/2005#event'></category>
  <title type='text'>Tennis with Beth</title>
  <content type='text'>Meet for a quick lesson.</content>
  <gd:transparency
    value='http://schemas.google.com/g/2005#event.opaque'>
  </gd:transparency>
  <gd:eventStatus
    value='http://schemas.google.com/g/2005#event.confirmed'>
  </gd:eventStatus>
  <gd:where valueString='Rolling Lawn Courts'></gd:where>
  <gd:when startTime='2006-04-17T15:00:00.000Z'
    endTime='2006-04-17T17:00:00.000Z'></gd:when>
</entry>

Note that this entry does not contain the standard APP <author> tag. The server will insert author information based on the user that submits the request (i.e. the user whose authentication token accompanies the request).

To post an entry, send the following HTTP request to Calendar, using a special "default" URL (and an Authorization header; see the section on authentication above). Calendar automatically redirects the default URL to the URL of the read/write private feed of the calendar belonging to the authenticated user. (Note that you don't have to use the default URL to send a POST request to Calendar; you can specify the user ID instead of "default" if you prefer. For more information, see the Calendar feed types reference.)

POST https://www.google.com/calendar/feeds/default/private/full

The content that you send with the POST request should be the <entry> element you created above, using the application/atom+xml content type.

Just like in the previous example, Calendar may return an HTTP 302 redirect; if so, then the redirect URL has a new parameter, gsessionid, appended to it. If you received the redirect, then send the same POST request again, with the same Authorization header and the same content, but with the gsessionid parameter appended. The response may also include a S cookie, which you should store and send this cookie with future requests as appropriate. Please see the knowledge base for more information on handling sessions with the Calendar Data API. Please note: if a session ID indicated in a cookie header conflicts with the session ID passed as a gsessionid URL parameter, you will get caught in a redirect loop.

When you send that second POST request (or the first one in cases where there's no redirect), Calendar creates a calendar event, then returns an HTTP 201 CREATED status code, along with a copy of the new event in the form of an <entry> element. The returned entry is similar to the one you sent, but the returned one contains various elements added by Calendar, such as an <id> element.

If your request fails for some reason, Calendar may return a different status code; for information about the status codes, see the Google Data API Protocol Reference document.

Note that if you use the Data API to add an event to your calendar that involves multiple participants, the event appears on the other people's calendars just as it would if you added it by hand using the Calendar GUI.

Creating quick add events

To create an event using Google Calendar's quick add feature, set the event entry's content to the quick add string you'd like to use. Then add a <gCal:quickadd> element with a value attribute set to true. For example, the following event <entry> element will create an event on April 11 from 3pm-3:30pm with a title of 'Tennis with John':

<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gCal='http://schemas.google.com/gCal/2005'>
  <content type="html">Tennis with John April 11 3pm-3:30pm</content>
  <gCal:quickadd value="true"/>
</entry>

The response from the server will contain an event <entry> with the appropriate fields populated by the server. Note that the <content> element is now empty and the <gCal:quickadd> element is no longer present:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005">
  ...
  <title type="text">Tennis with John</title>
  <content type="text" />
  <gd:when endTime="2007-04-11T15:30:00.000-07:00" startTime="2007-04-11T15:00:00.000-07:00" />
  ...
</entry>

Creating Calendar Event Gadgets

You can also create Gadgets as events in Google Calendar. Calendar Event Gadgets, formerly called web content, can contain images, HTML pages, or gadgets.

To create a simple Calendar Event Gadget that displays an image first create the XML for a calendar event <entry> element that contains a <link> element with the rel attribute set to http://schemas.google.com/gCal/2005/webContent. This <link> element should then contain a <gCal:webContent> element.

For example, the following entry would create a Calendar Event Gadget that displays the World Cup doodle (dimensions 276x120, and located at http://www.google.com/logos/worldcup06.gif). The icon at http://www.google.com/calendar/images/google-holiday.gif will be used to display the Calendar Event Gadget in the Calendar user interface before it is clicked.

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gCal="http://schemas.google.com/gCal/2005" >
  <link rel="http://schemas.google.com/gCal/2005/webContent"
        href="http://www.google.com/calendar/images/google-holiday.gif"
        title="World Cup"
        type="image/gif">
    </gCal:webContent url="http://www.google.com/logos/worldcup06.gif" width="276" height="120" />
  </link>
</entry>

To create a Calendar Event Gadget that displays a gadget, create an event entry with a web content link again, but this time the type should be application/x-google-gadgets+xml. You'll also need to get the gadget's URL from the iGoogle Directory. This example configures a Calendar Event Gadget to display the DateTime gadget and specifies the appropriate user preferences.

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gCal="http://schemas.google.com/gCal/2005" >
  <link rel="http://schemas.google.com/gCal/2005/webContent"
        href="http://www.google.com/favicon.ico"
        title="DateTime Gadget (a classic!)"
        type="application/x-google-gadgets+xml">
    <gCal:webContent url="http://google.com/ig/modules/datetime.xml" width="300" height="136">
      <gCal:webContentGadgetPref name="color" value="green" />
    </gCal:webContent>
  </link>
</entry>

Once you've created the Gadget's event, insert it just like normal event by sending an HTTP POST to the event feed URL with the event <entry> element in the message body.

POST https://www.google.com/calendar/feeds/default/private/full

Note: For more information on Calendar Event Gadgets, check out the documentation here.

Creating recurring events

Creating recurring events is very similar to creating a single-occurrence event. The event is created as a XML element of the Event kind, but includes a gd:recurrence element instead of a gd:when element. A gd:recurrence element contains syntax for recurring events based upon the iCalendar standard (RFC 2445).

Here's an example of an all-day recurring event that occurs weekly on Tuesdays from May 1st, 2007 through September 4th, 2007:

<entry xmlns='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/g/2005#event'></category>
  <title type='text'>Tuesday Tennis Lessons with Jane</title>
  <content type='text'>Meet on Tuesdays for a quick lesson.</content>
  <gd:transparency
    value='http://schemas.google.com/g/2005#event.opaque'>
  </gd:transparency>
  <gd:eventStatus
    value='http://schemas.google.com/g/2005#event.confirmed'>
  </gd:eventStatus>
  <gd:where valueString='Rolling Lawn Courts'></gd:where>
  <gd:recurrence>DTSTART;VALUE=DATE:20070501
DTEND;VALUE=DATE:20070502
RRULE:FREQ=WEEKLY;BYDAY=Tu;UNTIL=20070904
</gd:recurrence>
</entry>

As per RFC 2445, each line of the recurrence syntax ends in a carriage return and a line feed (CRLF). As the event is an all-day event, it does not include a reference to a timezone. If you do include a recurring event which references a timezone, you don't need to include the VTIMEZONE definition if the timezone used is a standard Java timezone definition.

This entry can then be sent via a POST to the Calendar servers using the method described in the Creating single-occurrence events section.

Retrieving recurring events using the Calendar Data API can be done via several methods, using the query parameters defined in the Reference Guide. Here's a basic overview:

  • No query parameters: a recurring event is returned as a single entry element, with a gd:recurrence child element. No gd:when elements are returned for the recurring event.
  • start-min and/or start-max specified: a recurring event is represented as a single entry element, with multiple gd:when elements for each occurrence in the range specified. The gd:recurrence element is also included in the entry.
  • singleevents=true: recurring events are represented in the same format as single events, with a single entry element per occurrence of the event. Each entry includes a single gd:when element, but does not include the gd:recurrence syntax. It does, however, include a gd:originalEvent element.

Updating events

To update an existing event send a PUT request with the updated entry in the message body to the post's edit URL. Be sure that the <id> value in the entry you POST exactly matches the <id> of the existing entry. The edit URL is highlighted in the following event entry:

  <entry xmlns='http://www.w3.org/2005/Atom'
         xmlns:gd='http://schemas.google.com/g/2005'
         xmlns:gCal='http://schemas.google.com/gCal/2005'>
    <id>http://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID</id>
    <published>2006-03-30T22:00:00.000Z</published>
    <updated>2006-03-28T05:47:31.000Z</updated>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/g/2005#event'></category>
    <title type='text'>Lunch with Darcy</title>
    <content type='text'>Change of plans - Let's discuss the new proposal.</content>
    <link rel='alternate' type='text/html'
      href='https://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
      title='alternate'></link>
    <link rel='self' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID'></link>
    <link rel='edit' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID/version' />
    ...
  </entry>

IMPORTANT! To ensure forward compatibility, be sure that when you PUT an updated entry you preserve all the XML that was present when you retrieved the entry from Google Calendar. Otherwise, when we implement new stuff and include <new-awesome-feature> elements in the feed, your client won't return them and your users will miss out! The Google Data API client libraries all handle this correctly, so if you're using one of the libraries you're all set.

Deleting events

Calendar events are deleted by sending a DELETE request to the event's edit URL. This is the same URL used to update the event.

Performing multiple operations with a batch request

If you're performing a lot of operations, the time it takes to send and and receive all those HTTP messages can really add up, making your app slow and unresponsive. With batch requests you can have the server perform multiple operations with a single HTTP request. The basic idea is that you create a calendar event feed and add an entry for each operation you want to perform. The following snippet shows a batch request that contains four operations, one each for creating, querying, updating, and deleting an event, but you can use any combination of operations that you want. Most of the unnecessary elements have been omitted.

<feed xmlns='http://www.w3.org/2005/Atom'
      xmlns:batch='http://schemas.google.com/gdata/batch'
      xmlns:gCal='http://schemas.google.com/gCal/2005'>
  <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
  <entry>
    <batch:id>1</batch:id>
    <batch:operation type='insert' />
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event inserted via batch</title>
  </entry>
  <entry>
    <batch:id>2</batch:id>
    <batch:operation type='query' />
    <id>http://www.google.com/calendar/feeds/default/private/full/glcs0kv2qqa0gf52qi1jo018gc</id>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event queried via batch</title>
  </entry>
  <entry>
    <batch:id>3</batch:id>
    <batch:operation type='update' />
    <id>http://www.google.com/calendar/feeds/default/private/full/ujm0go5dtngdkr6u91dcqvj0qs</id>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event updated via batch</title>
    <link rel='alternate' type='text/html'
        href='https://www.google.com/calendar/event?eid=dWptMGdvNWR0bmdka3I2dTkxZGNxdmowcXMgaGFyaXNodi50ZXN0QG0' title='alternate' />
    <link rel='self' type='application/atom+xml'
        href='http://www.google.com/calendar/feeds/default/private/full/ujm0go5dtngdkr6u91dcqvj0qs' />
    <link rel='edit' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/ujm0go5dtngdkr6u91dcqvj0qs/63326098791' />
  </entry>
  <entry>
    <batch:id>4</batch:id>
    <batch:operation type='delete' />
    <id>http://www.google.com/calendar/feeds/default/private/full/d8qbg9egk1n6lhsgq1sjbqffqc</id>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event deleted via batch</title>
    <link rel='alternate' type='text/html'
        href='https://www.google.com/calendar/event?eid=ZDhxYmc5ZWdrMW42bGhzZ3Exc2picWZmcWMgaGFyaXNodi50ZXN0QG0' title='alternate' />
    <link rel='self' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/d8qbg9egk1n6lhsgq1sjbqffqc' />
    <link rel='edit' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/d8qbg9egk1n6lhsgq1sjbqffqc/63326018324' />
  </entry>
</feed>

Note: The update and delete entries require an edit link in order for optimistic concurrency to work.

Once you build your batch request feed, you need to send an authenticated POST request to the batch URL of the events feed. The batch URL is highlighed in the following events feed:

<feed xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
  <id>http://www.google.com/calendar/feeds/<calendarId>/private/full</id>
  <updated>2007-09-21T22:59:51.000Z</updated>
  <title type='text'>Jo March</title>
  <subtitle type='text'>This is my main calendar.</subtitle>
  <link rel='alternate' type='text/html'
      href='https://www.google.com/calendar/embed?src=<calendarId>' />
  <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/<calendarId>/private/full' />
  <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/<calendarId>/private/full' />
  <link rel='http://schemas.google.com/g/2005#batch' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/<calendarId>/private/full/batch' />
  <link rel='self' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/<calendarId>/private/full?max-results=25' />
  .
  .
  .
</feed>

After submitting the batch request, the server will respond with a feed that contains the status of each operation. You can parse this response to see if each operation was successful or not. Here's an abbreviated version of the response when submitting the above batch request feed.

<feed xmlns='http://www.w3.org/2005/Atom'
      xmlns:batch='http://schemas.google.com/gdata/batch'
      xmlns:gCal='http://schemas.google.com/gCal/2005'>
  <id>http://www.google.com/calendar/feeds/default/private/full</id>
  <updated>2007-09-21T23:01:00.380Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event'></category>
  <title type='text'>Batch Feed</title>
  <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/default/private/full' />
  <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/default/private/full' />
  <link rel='http://schemas.google.com/g/2005#batch' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/default/private/full/batch' />
  <entry>
    <batch:id>1</batch:id>
    <batch:status code='201' reason='Created' />
    <batch:operation type='insert' />
    <id>http://www.google.com/calendar/feeds/default/private/full/n9ug78gd9tv53ppn4hdjvk68ek</id>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event inserted via batch</title>
    <link rel='alternate' type='text/html'
        href='https://www.google.com/calendar/event?eid=bjl1Zzc4Z2Q5dHY1M3BwbjRoZGp2azY4ZWsgaGFyaXNodi50ZXN0QG0' title='alternate' />
    <link rel='self' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/n9ug78gd9tv53ppn4hdjvk68ek' />
    <link rel='edit' type='application/atom+xml'
      href='https://www.google.com/calendar/feeds/default/private/full/n9ug78gd9tv53ppn4hdjvk68ek/63326098860' />
  </entry>
  <entry>
    <batch:id>2</batch:id>
    <batch:status code='200' reason='Success' />
    <batch:operation type='query' />
    <id>http://www.google.com/calendar/feeds/default/private/full/glsc0kv2aqa0ff52qi1jo018gc</id>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event queried via batch</title>
    <link rel='alternate' type='text/html'
        href='https://www.google.com/calendar/event?eid=Z2xzYzBrdjJhcWEwZmY1MnFpMWpvMDE4Z2MgaGFyaXNodi50ZXN0QG0' title='alternate' />
    <link rel='self' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/glsc0kv2aqa0ff52qi1jo018gc' />
    <link rel='edit' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/glsc0kv2aqa0ff52qi1jo018gc/63326098791' />
  </entry>
  <entry xmlns:gCal='http://schemas.google.com/gCal/2005'>
    <batch:id>3</batch:id>
    <batch:status code='200' reason='Success' />
    <batch:operation type='update' />
    <id>http://www.google.com/calendar/feeds/default/private/full/ujm0go5dtngdkr6u91dcqvj0qs</id>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event updated via batch</title>
    <link rel='alternate' type='text/html'
        href='https://www.google.com/calendar/event?eid=dWptMGdvNWR0bmdka3I2dTkxZGNxdmowcXMgaGFyaXNodi50ZXN0QG0' title='alternate' />
    <link rel='self' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/ujm0go5dtngdkr6u91dcqvj0qs' />
    <link rel='edit' type='application/atom+xml'
        href='https://www.google.com/calendar/feeds/default/private/full/ujm0go5dtngdkr6u91dcqvj0qs/63326098860' />
    <batch:id>3</batch:id>
    <batch:status code='200' reason='Success' />
    <batch:operation type='update' />
  </entry>
  <entry>
    <batch:id>4</batch:id>
    <batch:status code='200' reason='Success' />
    <batch:operation type='delete' />
    <id>http://www.google.com/calendar/feeds/default/private/full/d8qbg9egk1n6lhsgq1sjbqffqc</id>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
    <title type='text'>Event deleted via batch</title>
    <content type='text'>Deleted</content>
  </entry>
</feed>

When working with batch requests, the size of the request must be under a megabyte and it's best to limit batches to 50-100 operations at a time. You can find more information about batch operations in the Google Data APIs Batch Processing documentation.

Sharing calendars

This section describes how to retrieve and modify Google Calendar access control lists (ACLs) using the raw protocol. An access control list identifies the set of users with whom a given calendar is shared, and the level of access for each user (such as read-only access, full access, and so on).

Specifically, an ACL is a list of access rules. Each access rule specifies a "scope" (a person or set of people) and then associates a "role" (an access level) with that scope. Those terms are defined as follows:

  • The scope of a rule directly or indirectly identifies a set of individuals to whom the rule applies. A scope has two parts: a type (such as user) and a value (such as an email address).
  • A role defines an access level, which determines what rights people identified by the given scope have. In Google Calendar, the defined roles include none, freebusy, read, and owner. (Note that most role names must be preceded by a specific namespace URI; see the examples and reference document for details.) A given scope can have only one role.

For information about the other defined scopes and roles, see the GAcl namespace element reference in the Calendar reference document.

Note: For a given scope, having a role of none is equivalent to having no role defined.

The ACL for each calendar is available as a Data API feed. Each entry in the feed defines a single access rule.

Google Calendar does not support query parameters on requests for ACL feeds.

Retrieving access control lists

To retrieve a calendar's ACL feed, you send an authenticated GET to the feed's URI. Only someone with owner access to a calendar can view that calendar's ACL feed.

You can determine the URI of a calendar's ACL feed by looking at the calendar's entry in one of the calendar feeds (see Retrieving Calendars). The ACL feed URI is given in the <link rel="http://schemas.google.com/acl/2007#accessControlList"> element.

For example, the following partial entry from a metafeed includes the URI of the ACL feed for a particular calendar.

<entry>
  <id>http://www.google.com/calendar/feeds/liz%40gmail.com/liz%40gmail.com</id>
  <published>2007-04-24T01:40:29.752Z</published>
  <updated>2007-04-21T00:52:04.000Z</updated>
  <title type='text'>My Calendar</title>
  ...
  <link rel='http://schemas.google.com/acl/2007#accessControlList'
    type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full'>
  </link>
  ...
</entry>

If you send a GET to that ACL feed URI, you might receive a feed like the following.

<feed xmlns='http://www.w3.org/2005/Atom'
    xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
    xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <id>http://www.google.com/calendar/feeds/liz%40gmail.com/acl/full</id>
  <updated>2007-04-21T00:52:04.000Z</updated>
  <title type='text'>Elizabeth Bennet's access control list</title>
  <link rel='http://schemas.google.com/acl/2007#controlledObject'
    type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/liz%40gmail.com/private/full'>
  </link>
  <link rel='http://schemas.google.com/g/2005#feed'
    type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full'>
  </link>
  <link rel='http://schemas.google.com/g/2005#post'
    type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full'>
  </link>
  <link rel='self' type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full'>
  </link>
  <generator version='1.0'
    uri='https://www.google.com/calendar'>Google Calendar</generator>
  <openSearch:totalResults>2</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <entry>
    <id>http://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/user%3Aliz%40gmail.com</id>
    <updated>2007-04-21T00:52:04.000Z</updated>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/acl/2007#accessRule'>
</category> <title type='text'>owner</title> <content type='text'></content> <link rel='self' type='application/atom+xml' href=https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/user%3Aliz%40gmail.com'> </link> <link rel='edit' type='application/atom+xml' href=https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/user%3Aliz%40gmail.com'> </link> <author>
<name>Elizabeth Bennet</name>
<email>liz@gmail.com</email>
</author> <gAcl:scope type='user' value='liz@gmail.com'></gAcl:scope> <gAcl:role value='http://schemas.google.com/gCal/2005#owner'> </gAcl:role> </entry> <entry> <id>http://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/default</id> <updated>2007-04-21T00:52:04.000Z</updated> <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'> </category> <title type='text'>read</title> <content type='text'></content> <link rel='self' type='application/atom+xml' href=https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/default'> </link> <link rel='edit' type='application/atom+xml' href=https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/default'> </link> <author>
<name>Elizabeth Bennet</name>
<email>liz@gmail.com</email>
</author> <gAcl:scope type='default'></gAcl:scope> <gAcl:role value='http://schemas.google.com/gCal/2005#read'> </gAcl:role> </entry> </feed>

A few comments on that feed:

  • The <link rel='http://schemas.google.com/acl/2007#controlledObject'> element contains the URI of the calendar feed for the calendar that this ACL belongs to.
  • Each rule/entry contains a <category scheme='http://schemas.google.com/g/2005#kind'> element, with term='http://schemas.google.com/acl/2007#accessRule'.
  • The ACL-specific elements use the namespace alias gAcl.
  • The first entry defines a role (owner) for a specific user (liz@gmail.com).
  • The second entry defines a role (read) for all other users (default).

Retrieving a rule

To retrieve a single ACL rule rather than the entire feed, you can construct the URI for a single rule using the scope type (such as user) and the scope value (such as the user's email address).

To construct the URI for a particular rule, start with the ACL feed URI; then add the scope type and value (URL-encoded as needed), separated by a colon, as an additional path element. For example, the following is the URI for the ACL rule (for the example calendar we've been using) for user darcy@gmail.com:

https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/user%3Adarcy%40gmail.com

If you request a rule that hasn't been defined, then the service returns an HTTP 404 NOT FOUND status code.

Adding a user to an access control list

A requester with permission to modify the access control list can add a new ACL rule by posting a new entry to the ACL feed's POST URI. The entry should contain the following elements:

  • <category>
  • <gAcl:scope>
  • <gAcl:role>

Any other elements that appear in the entry you send are ignored by the server.

Note: Another way to add a rule is to use PUT. For more information, see Updating a user's role in an ACL.

For example, you could send a POST request to the following URI, after authenticating as user liz@gmail.com:

POST /calendar/feeds/liz@gmail.com/acl/full

With the following entry in the body of the POST:

<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:scope type='user' value='darcy@gmail.com'></gAcl:scope>
  <gAcl:role
    value='http://schemas.google.com/gCal/2005#editor'>
  </gAcl:role>
</entry>

If the specified scope does not already have a role defined (or, equivalently, if the role for that scope is currently none), then Calendar creates a new ACL rule, and returns the corresponding ACL entry in the response. The returned entry includes several new elements provided by the server.

If there is already a rule in the access control list with a scope whose type and value match that in the request, and whose role is anything other than none, then the POST operation fails with error code 409 Conflict.

The above POST might receive the following successful result:

200 OK


<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <id>http://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/user%3Adarcy%40gmail.com</id>
  <updated>2007-04-15T22:03:57.000Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'>
  </category>
  <title type='text'>editor</title>
  <content type='text'></content>
  <link rel='self' type='application/atom+xml'
    href=https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/user%3Adarcy%40gmail.com'>
  </link>
  <link rel='edit' type='application/atom+xml'
    href=https://www.google.com/calendar/feeds/liz%40gmail.com/acl/full/user%3Adarcy%40gmail.com'>
  </link>
  <author>
    <name>Elizabeth Bennet</name>
    <email>liz@gmail.com</email>
  </author>
  <gAcl:scope type='user' value='darcy@gmail.com'></gAcl:scope>
  <gAcl:role value='http://schemas.google.com/gCal/2005#editor'>
  </gAcl:role>
</entry>

Updating a user's role in an ACL

To change an ACL rule, you can send a PUT request to the edit URI of the entry you want to modify. (You can also use this approach as an alternate method of creating new rules.)

You can construct the edit URI for a Google Calendar ACL rule entry using the entry's scope type and scope value, without having to retrieve the entry first.

For example, to change the ACL rule for user darcy@gmail.com, you could send the following PUT request:

PUT /calendar/feeds/liz@gmail.com/acl/full/user%3Adarcy%40gmail.com

With the following entry in the request body:

<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:scope type='user' value='darcy@gmail.com'></gAcl:scope>
  <gAcl:role value='http://schemas.google.com/gCal/2005#read'></gAcl:role>
</entry>

The URI fragment following /full/ in the PUT URI must indicate the same scope type and value as the <gAcl:scope> element in the entry you're sending.

The server silently overwrites any previous access level set for the indicated scope. If there is no existing rule for that scope, it will create a new one.

Note: Because a given rule is associated with a particular scope, it is not possible to modify the scope of a rule when updating it; only the role can be modified. An attempt to modify the scope will result in a 403 Forbidden error.

Removing a user from an access control list

To remove a specific access rule for a calendar, you may do either of the following:

  • Send an HTTP DELETE request to the appropriate ACL entry's edit URI.
  • Update the entry (with PUT) and set <gAcl:role value="none" />.

Doing either of those things causes the user (or group of users) specified in the scope to lose access to the calendar.

Additional operations

Extended properties

You can add extended properties (arbitrary name-value pairs) to Calendar events. These can be used to store application-specific IDs or other small amounts of information your application needs when interacting with a Google Calendar. The name of a property can contain up to 47 characters, and the value can contain up to 1024 characters. Extended properties are only accessible through the API – they do not appear in the Calendar user interface.

To include extended properties in your events, add the <extendedProperty> element like this:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" >
  <id>http://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID</id>
  <published>2006-03-30T22:00:00.000Z</published>
  <updated>2006-03-28T05:47:31.000Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/g/2005#event'></category>
  <title type='text'>Lunch with Darcy</title>
  <content type='text'>Lunch to discuss future plans.</content>
  <link rel='alternate' type='text/html'
    href=https://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
    title='alternate'></link>
  <link rel='self' type='application/atom+xml'
    href=https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID'></link>
  <link rel='edit' type='application/atom+xml'
    href=https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID/version' />
  <gd:extendedProperty name="propname" value="propvalue" />
  ...
</entry>

Note: Extended properties are not indexed so you can't query based on their keys or values.

Reminders and Notifications

To include reminders in your events, add the <gd:reminder> element as a child of the <when> element like this:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" >
  <id>http://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID</id>
  <published>2006-03-30T22:00:00.000Z</published>
  <updated>2006-03-28T05:47:31.000Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/g/2005#event'></category>
  <title type='text'>Lunch with Darcy</title>
  <content type='text'>Lunch to discuss future plans.</content>
  <link rel='alternate' type='text/html'
    href=https://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
    title='alternate'></link>
  <link rel='self' type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID'></link>
  <link rel='edit' type='application/atom+xml'
    href=https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID/version' />
  <gd:when startTime='2006-03-30T22:00:00.000Z' endTime='2006-03-30T23:00:00.000Z'>
    <gd:reminder minutes='30' method='email' />
    <gd:reminder minutes='10' method='alert' />
  </gd:when>  ...
</entry>

You can include up to five reminders per event. The available methods are email, alert (a popup in the browser), sms (a text message), or none. By default every event created through the Google Calendar interface is associated with a SMS reminder, even if SMS notifications are not enabled in your Google Calendar account setting.

For an event to inherit the default reminder setting of your Google Calendar account, you can either add an empty reminder element with no method value <gd:reminder /> or add a <gd:reminder method='all' /> element.

If you want to ensure that no reminders are sent, add a <gd:reminder method='none' /> element.

Note: The value of the minutes can be any arbitrary number of minutes between 5 minutes to 4 weeks.

Comments

When attendees reply to an event invitation, they have the ability to add a "note" to their reply. These notes are accessible via the Calendar API as comments.

Comment feeds are available as part of the "full" or "composite" event feeds. The "full" feed does not contain the comments themselves, but instead provides a link to a separate feed containing the comments. The "composite" feed includes data from both the full and comment feed together (it is a composite of the two feeds).

Note: The composite feed is simpler to work with and requires less HTTP requests, but introduces additional latency while the server is processing the request.

To request comments using the composite feed, use the following URL when requesting an event feed:

https://www.google.com/calendar/feeds/userID/private/composite

This will return a feed containing event entries in the following format:

<entry>
<id>http://www.google.com/calendar/feeds/default/private/composite/a123</id>
<published>2009-12-31T01:42:00.000Z</published>
<updated>2009-12-31T02:42:00.000Z</updated>
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/g/2005#event"/>
<link rel="alternate" type="text/html" href="https://www.google.com/calendar/event?eid=b234" title="alternate"/>
<link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/private/composite/a123"/>
<title type="text">Sample Event</title>
<content type="text">This is a sample event.</content>
<author>
 <name>Test User</name>
 <email>user@gmail.com</email>
</author>
<gd:comments>
 <gd:feedLink href="https://www.google.com/calendar/feeds/default/private/full/a123/comments">
   <feed>
     <id>http://www.google.com/calendar/feeds/default/private/full/a123/comments</id>
     <updated>2009-12-31T01:55:00.000Z</updated>
     <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/g/2005#message"/>
     <title type="text">Comments for: Sample event</title>
     <link rel="alternate" type="text/html" href="https://www.google.com/calendar/feeds/default/private/full/a123/comments" title="alternate"/>
     <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/private/composite"/>
     <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/private/composite"/>
     <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/private/composite/batch"/>
     <entry>
       <id>http://www.google.com/calendar/feeds/default/private/composite/c345</id>
       <published>2009-12-31T01:55:00.000Z</published>
       <updated>2009-12-31T01:55:00.000Z</updated>
       <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/g/2005#message"/>
       <content type="text">Yes, I can attend the event!</content>
       <link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/private/composite/c345"/>
       <author>
         <name>A Different User</name>
         <email>user2@gmail.com</email>
       </author>
     </entry>
   </feed>
 </gd:feedLink>
</gd:comments>
<!-- The rest of the event data has been omitted for brevity. -->
</entry>

To request comments using the full feed, use the following URL instead when requesting entries:

https://www.google.com/calendar/feeds/userID/private/full

This will return a feed in the following format:

<entry>
<id>http://www.google.com/calendar/feeds/default/private/composite/a123</id>
<published>2009-12-31T01:42:00.000Z</published>
<updated>2009-12-31T02:42:00.000Z</updated>
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/g/2005#event"/>
<link rel="alternate" type="text/html" href="https://www.google.com/calendar/event?eid=b234" title="alternate"/>
<link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/default/private/composite/a123"/>
<title type="text">Sample Event</title>
<content type="text">This is a sample event.</content>
<author>
 <name>Test User</name>
 <email>user@gmail.com</email>
</author>
<gd:comments>
 <gd:feedLink href="https://www.google.com/calendar/feeds/default/private/full/a123/comments" />
</gd:comments>
<!-- The rest of the event data has been omitted for brevity. -->
</entry>

Notice that the gd:comments element contains a gd:feedLink, but does not contain an atom:feed or it's associated comment entries. Loading the URL contained inside the feed link will, however, return the missing comments feed.

GeoRSS data (Experimental)

If an event has any location information (see gd:where element), the Calendar server geocodes the event's location as a latitude and longitude and includes this information into the event entry as a georss:where element:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gml="http://www.opengis.net/gml"
  xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" >
  <id>http://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID</id>
  <published>2006-03-30T22:00:00.000Z</published>
  <updated>2006-03-28T05:47:31.000Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/g/2005#event'></category>
  <title type='text'>Lunch with Darcy</title>
  <content type='text'>Lunch to discuss future plans.</content>
  <link rel='alternate' type='text/html'
    href='https://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
    title='alternate'></link>
  <link rel='self' type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID'></link>
  <link rel='edit' type='application/atom+xml'
    href='https://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID/version' />
  <gd:where valueString='Saint Petersburg' />
  <georss:where>
    <gml:Point>
      <gml:pos>59.939039 30.315785</gml:pos>
    </gml:Point>
  </georss:where>
</entry>

The georss:where element is optional in the event feed and read-only. It is not guaranteed that GeoRSS information will be present in every event entry, even if the event location is set.

If the georss:where element is present, it contains a gml:Point nested element with latitute/longtitude data. More information about the GeoRSS format can be found here: http://georss.org.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.