Google Apps Platform

Google Calendar API v1 Developer's Guide: PHP

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.

This document provides detailed examples for using the PHP Client Library to work with the Google Calendar service. You can download the client library as a standalone release (distributed by Zend) or as part of the Zend Framework. For help setting up the client library, see the Getting Started Guide. You will find examples of adding events, updating events, deleting events and querying events. If you're interested in understanding more about the underlying protocol used by the Zend Google Data APIs Client Library to interact with the Calendar Data API, please see the protocol tab.



This document is intended for programmers who want to write client applications in PHP that can interact with Google Calendar.

Getting started

For help setting up the client library, see the Getting Started Guide. The Zend Google Data Client Library is available as part of the Zend Framework and also as a separate download. Please use version 1.0.0 RC2a or later of the client library to work with the Google Calendar Data API. The client library is only available for use with PHP 5.1.4 or later.

A full working copy of this sample is available in the Zend Framework SVN repository. The sample is located at /framework/standard/trunk/demos/Zend/Gdata/Calendar.php. You can run the sample both from the command line (CLI) and also from a web browser. When running through a web browser, only AuthSub and outputting a list of calendars is demonstrated. When running via CLI, all functionality except AuthSub is available and dependent upon the command line options passed. Run this script without any command line options to see usage, e.g.:

php Calendar.php

Before running this sample or developing your own code which uses the Zend Framework, you may need to set the include_path and load the appropriate classes. The include path can be set using either a php.ini setting or using the set_include_path method. This code requests access to the core Zend_Gdata class, the Zend_Gdata_Calendar class for Calendar-specific functionality, as well as the authentication classes — Zend_Gdata_AuthSub and Zend_Gdata_ClientLogin. Depending upon your application, you may require only one of the two authentication classes.

require_once 'Zend/Loader.php';


Throughout the PHP client library, support has been added for magic setters/getters as a convenience to developers. These allow the properties of a class to be accessed either in a safe way using traditional setter/getter methods or by accessing the properties. For example, if $gdataObject were an instance of an object in this library, the following two lines of code are both completely identical:

$gdataObject->foo = "bar";

Likewise, these two lines of code are also completely identical:

$baz = $gdataObject->getFoo();
$baz = $gdataObject->foo;

Similarly, we've implemented a "magic" factory method in all service classes, including Zend_Gdata_Calendar. These shield programmers from having to type the large class names mandated for modules within the Zend Framework. As a result, the following blocks of code would also be identical, assuming that the fictitious class Zend_Gdata_Calendar_Extensions_Object existed:

// Traditional instantiation
$gdataCal = new Zend_Gdata_Calendar();
$gdataObject = new Zend_Gdata_Calendar_Extensions_Object();

// Magic factory instantiation
$gdataCal = new Zend_Gdata_Calendar();
$gdataObject = $gdataCal->newObject();

Both magic setters/getters and magic factories are optional, so feel free to use them or not use them at your convenience.

Other Resources for the Zend Framework Google Data component (Zend_Gdata):

Authenticating to the Calendar service

The Zend PHP client library can be used to work with either public or private feeds. Public feeds are read-only, but do not require any authentication. Private feeds require that you authenticate to the calendar servers. This can be done via ClientLogin username/password authentication or AuthSub proxy authentication. The calendar service also allows authentication to a read-only private feed using magic cookie authentication.

Please see the authentication documentation for more information on AuthSub and ClientLogin.

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 calendar user - only special AuthSub tokens are required. Please see the AuthSub documentation for more detailed information.

When a user first visits your application, they have not yet been authenticated. In this case, you need to print some text and a link directing the user to Google to authenticate your request for access to their calendar. The Zend Google Data client library provides a static function to generate this URL. The code below sets up a link to the AuthSubRequest page with these options:

  • session, indicating this token can be exchanged for a multi-use (session) token;
  • next, the URL of the current page (obtained by examining $_SERVER variables for HTTP_POST, SERVER_PORT, HTTPS and REQUEST_URI)
  • scope, indicating that the application will only access Google Calendar feeds.
function getAuthSubUrl()
  $next = getCurrentUrl();
  $scope = '';
  $secure = false;
  $session = true;
  return Zend_Gdata_AuthSub::getAuthSubTokenUri($next, $scope, $secure,

$authSubUrl = getAuthSubUrl();
echo "<a href=\"$authSubUrl\">login to your Google account"</a> 

The user will then follow the link to Google's site and authenticate to their Google account. The link will look something like:

After the user authenticates, they will be redirected back to the next URL. The URL will also have a token and value appended to it as a query parameter. The URL the user will be redirected to will be like:

The token value in the URL will be accessible to your application using $_GET[[]'token']. This always represents a single-use AuthSub token. Since you specified $session = true above, this token can be exchanged for an AuthSub session token. This is necessary for calendar operation, as the calendar servers only support session tokens. The Zend Google Data client library provides a method called Zend_Gdata_AuthSub::getAuthSubSessionToken which does this exchange for you by calling the AuthSubSessionToken service.

The following code snippet checks whether an AuthSub session token is already present. If it isn't, but a single-use token is specified in the URL, then the getAuthSubSessionToken method is used to retrieve a session token from Google and place this value into the session variable $_SESSION[[]'sessionToken'].

if(! isset($_SESSION[[]'sessionToken']) && isset($_GET[[]'token'])) {
  $_SESSION[[]'sessionToken'] =

When communicating with the calendar servers, you only need access to the $_SESSION[[]'sessionToken'] value. The client library provides a method to get a Zend_Http_Client object which has the Authorization header preset to include AuthSubCredentials.

$client = Zend_Gdata_AuthSub::getHttpClient($_SESSION[[]'sessionToken']);

ClientLogin username/password authentication

ClientLogin authentication is much easier to use than AuthSub because it does not require redirecting the user or doing a token exchange. However, ClientLogin is designed to be used only with installed applications or in cases where only a single calendar is being accessed with hard-coded credentials.

The following code uses the Zend_Gdata_ClientLogin::getHttpClient method to perform a request to the ClientLogin service, retrieve an authentication token and create a Zend_Http_Client object with the appropriate Authentication header.

$user = '';
$pass = 'myPassword';
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; // predefined service name for calendar

$client = Zend_Gdata_ClientLogin::getHttpClient($user,$pass,$service);

Note: You will need to replace the values of $user and $pass with the username and password of the Google Account whose calendar you will access.

Magic cookie authentication

Magic cookie authentication can be used in cases where you want to retrieve a read-only feed containing private calendar events. A magic cookie can be specified in the URL of the feed. In the following example feed URL, 'abcdefg' is the magic cookie:

The appropriate value for a magic cookie can be obtained through the Calendar details' page in the UI for each of your calendars. It is labeled as a 'Private Address'.

The following code retrieves the private magic cookie feed using the Zend_Gdata_Calendar object, setting the following options:

  • user, indicating the username (in e-mail address form) of the calendar which you are accessing
  • visibility, specifying the private visibility feed along with the magic cookie value
  • projection, indicating the use of the full projection (as opposed to the basic projection, composite projection or others)

Unlike AuthSub and ClientLogin authentication, magic cookie authentication credentials are stored entirely within query requests. As a result, it is not necessary to request a special authenticated HTTP client before creating a calendar service object.

Please see the Reference Guide for more information about the Calendar feed types.

$gdataCal = new Zend_Gdata_Calendar();
$query = $gdataCal->newEventQuery();
$eventFeed = $gdataCal->getCalendarEventFeed($query);
foreach ($eventFeed as $event) {
  echo $event->title->text . '<br />';

Retrieving a list of calendars

The calendar service supports retrieving a list of calendars for the authenticated user. This is the same list of calendars which are presented in the UI, except those marked as 'hidden' are also available. You cannot retrieve a list of another user's calendars. The following example presumes that you already have a $client object which has credentials via either the AuthSub or ClientLogin methods.

function outputCalendarList($client)
  $gdataCal = new Zend_Gdata_Calendar($client);
  $calFeed = $gdataCal->getCalendarListFeed();
  echo '<h1>' . $calFeed->title->text . '</h1>';
  echo '<ul>';
  foreach ($calFeed as $calendar) {
    echo '<li>' . $calendar->title->text . '</li>';
  echo '</ul>';

Retrieving events

Retrieving events without query parameters

Like the list of calendars, events are also retrieved using the Zend_Gdata_Calendar class. When invoked with no query parameters, the getCalendarEventFeed method returns the primary calendar of the current user using the private visibility/full projection feed. Please see the Calendar Feed types section of the reference guide for more information on the various feed types available.

function outputCalendar($client)
  $gdataCal = new Zend_Gdata_Calendar($client);
  $eventFeed = $gdataCal->getCalendarEventFeed();
  echo "<ul>\n";
  foreach ($eventFeed as $event) {
    echo "\t<li>" . $event->title->text .  " (" . $event->id->text . ")\n";
    echo "\t\t<ul>\n";
    foreach ($event->when as $when) {
      echo "\t\t\t<li>Starts: " . $when->startTime . "</li>\n";
    echo "\t\t</ul>\n";
    echo "\t</li>\n";
  echo "</ul>\n";

By default, the server limits the result set initially returned, but you can use the setMaxResults query parameter to ask the server to send additional results back. Additionally, you can page through the results returned by using getNextLink then calling getHref on the returned object to get the location of the next set of results. Later sections of the guide will demonstrate how to create detailed queries like this.

Retrieving events for a specified date range

To print out all events between May 1, 2007 and August 1, 2007, a Zend_Gdata_Calendar_EventQuery object is created. This is a subclass of the Google Data query class — Zend_Gdata_Query — which allows developers to modify and refine the results which are generated by the calendar service.

function outputCalendarByDateRange($client, $startDate='2007-05-01',
  $gdataCal = new Zend_Gdata_Calendar($client);
  $query = $gdataCal->newEventQuery();
  $eventFeed = $gdataCal->getCalendarEventFeed($query);
  echo "<ul>\n";
  foreach ($eventFeed as $event) {
    echo "\t<li>" . $event->title->text .  " (" . $event->id->text . ")\n";
    echo "\t\t<ul>\n";
    foreach ($event->when as $when) {
      echo "\t\t\t<li>Starts: " . $when->startTime . "</li>\n";
    echo "\t\t</ul>\n";
    echo "\t</li>\n";
  echo "</ul>\n";

Note that while the startMin is inclusive, startMax is exclusive, so specifying a startMax of '2007-08-01' will include those events up until 2007-07-31 11:59:59PM. Please see the query parameters reference for more information.

Retrieving events matching a full text query

Calendars also allow users to search for events using full-text queries. A full-text query searches both the title and content of an event, but it does not search the value of extended properties at the time of this writing. It searches the default calendar of the authenticated user as contained within the private visibility/full projection feed. Again, please see the query parameters reference for more information about the various feed types used available.

function outputCalendarByFullTextQuery($client, $fullTextQuery='tennis')
  $gdataCal = new Zend_Gdata_Calendar($client);
  $query = $gdataCal->newEventQuery();
  $eventFeed = $gdataCal->getCalendarEventFeed($query);
  echo "<ul>\n";
  foreach ($eventFeed as $event) {
    echo "\t<li>" . $event->title->text .  " (" . $event->id->text . ")\n";
    echo "\t\t<ul>\n";
    foreach ($event->when as $when) {
      echo "\t\t\t<li>Starts: " . $when->startTime . "</li>\n";
      echo "\t\t</ul>\n";
      echo "\t</li>\n";
  echo ">/ul<\n";

Creating Events

Creating single-occurrence events

Events are added to a calendar by creating a Zend_Gdata_Calendar_EventEntry and populating it with the appropriate data. An instance of Zend_Gdata_Calendar is then used to POST the XML to a specific Google Calendar. In this case, the event is posted to the default calendar of the authenticated user.

The following attributes of the event should be set:

  • title, set using setTitle, specifies the headline that will appear above the event in the Google Calendar UI.
  • when, set using setWhen, denotes the time and duration of the event. The start and end times of the event are specified with setStartTime and setEndTime, respectively, using RFC 3339 formatted strings. All day events are created by specifying a date without a time, and zero-duration events are set by omitting the end time entirely. Optionally, up to five reminders for an event can be created by attaching them to a when object. Reminders will be covered in more detail later in this guide.

Other useful functions include but are not limited to:

  • author, retrieved using getAuthor, can be used to access the user who created the event. Note that the calendar API will not accept user-submitted updates to this attribute.
  • content, set using setContent, provides additional information about the event which appears when the event details are requested from within Google Calendar. Optionally, the description's mime-type is set using setType to specify HTML instead of plain text.
  • eventStatus, set using setEventStatus, denotes whether the event is confirmed, tentative, or canceled. See gd:eventStatus in the Google Data Common Elements Reference for a list of possible values.
  • transparency, set using setTransparency, indicates whether the event should consume time on the user's free/busy list.
  • visibility, set using setVisibility, allows an event to be hidden from a user's public feeds.

For a complete list of event attributes, refer to the Google Data package in the Zend Framework API Documentation, the Event Kind in the Google Data APIs Common Elements List. Attribute that can can contain multiple values, such as where, are implemented as arrays and need to be created accordingly. Be aware that all of these attributes require objects as parameters. Trying to instead populate them using strings or primitives will result in errors during conversion to XML.

function createEvent ($client, $title = 'Tennis with Beth',
    $desc='Meet for a quick lesson', $where = 'On the courts',
    $startDate = '2008-01-20', $startTime = '10:00',
    $endDate = '2008-01-20', $endTime = '11:00', $tzOffset = '-08')
  $gdataCal = new Zend_Gdata_Calendar($client);
  $newEvent = $gdataCal->newEventEntry();

  $newEvent->title = $gdataCal->newTitle($title);
  $newEvent->where = array($gdataCal->newWhere($where));
  $newEvent->content = $gdataCal->newContent("$desc");

  $when = $gdataCal->newWhen();
  $when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
  $when->endTime = "{$endDate}T{$endTime}:00.000{$tzOffset}:00";
  $newEvent->when = array($when);

  // Upload the event to the calendar server
  // A copy of the event as it is recorded on the server is returned
  $createdEvent = $gdataCal->insertEvent($newEvent);
  return $createdEvent->id->text;

createEvent($client, 'New Years Party',
    'Ring in the new year with Kim and I',
    'Our house',
    '2006-12-31', '22:00', '2007-01-01', '03:00', '-08' );

Creating Quick Add events

To create an event using Google Calendar's Quick Add feature, store the Quick Add string you'd like to use as the entry's content attribute. Then call setQuickAdd on the new entry, as follows:

function createQuickAddEvent ($client, $quickAddText) {
  $gdataCal = new Zend_Gdata_Calendar($client);
  $event = $gdataCal->newEventEntry();
  $event->content = $gdataCal->newContent($quickAddText);
  $event->quickAdd = $gdataCal->newQuickAdd('true');
  $newEvent = $gdataCal->insertEvent($event);

createQuickAddEvent($client, "Dinner at Joe's on Thursday at 8 PM");

Notice that it is not necessary to set a title or when on the new entry. These fields are automatically generated based on the Quick Add text.

Creating web content events

In addition to standard events, you can also use the calendar API to also insert new web content events into a user's calendar. These are special events which reference external content inside of a small popup display. The procedure for creating a web content event is similar to a regular event, except a Zend_Gdata_Calendar_Extension_WebContent instance is added to the event inside of a Zend_Gdata_Calendar_Extension_Link instance. This link class is similar to Zend_Gdata_App_Extension_Link, except includes support specifically for web content events.

To create a web content event, create a new Zend_Gdata_Calendar_Extension_WebContent instance. This instance's URL should be set by calling setURL, providing the location of the content which should be embedded inside the popup display. The height and width of this panel should specify the dimensions of the popup by calling setHeight and setWidth, respectively.

This object should then be added to a new Zend_Gdata_Calendar_Extension_Link object by calling setWebContent. A 16x16 icon for the event should be provided by calling setHref with the URL of the icon. The title that should appear on the top of the popup display can be set by calling setTitle, and the MIME type for the displayed content can optionally be set by calling setType. Finally, the link's rel value must be set to "" by calling setRel.

Once these two instances are created, the link is added as an array to the event by calling setLink. All other properties of the event may be set as usual before uploading the event to the calendar servers.

Note that Zend_Gdata_Calendar_Extension_Link is identical to Zend_Gdata_App_Extension_Link, except the calendar version supports the addition of web content objects to the event.

function createWebContentEvent ($client, $title = 'World Cup 2006',
        $startDate = '2006-06-09', $endDate = '2006-06-09',
        $icon = '',
        $url = '',
        $height  = '120', $width = '276', $type = 'image/gif'
  $gc = new Zend_Gdata_Calendar($client);
  $newEntry = $gc->newEventEntry();
  $newEntry->title = $gc->newTitle(trim($title));

  $when = $gc->newWhen();
  $when->startTime = $startDate;
  $when->endTime = $endDate;
  $newEntry->when = array($when);

  $wc = $gc->newWebContent();
  $wc->url = $url;
  $wc->height = $height;
  $wc->width = $width;

  $wcLink = $gc->newLink();
  $wcLink->rel = "";
  $wcLink->title = $title;
  $wcLink->type = $type;
  $wcLink->href = $icon;

  $wcLink->webContent = $wc;
  $newEntry->link = array($wcLink);

  $createdEntry = $gc->insertEvent($newEntry);
  return $createdEntry->id->text;

Creating recurring events

To create a recurring event, create an event as usual except instead of setting the event's when property, set its recurrence property by calling setRecurrence.

$gdataCal = new Zend_Gdata_Calendar($client);
$newEntry = $service->newEventEntry();

$recurrence = "DTSTART;VALUE=DATE:20070501\r\n" .
        "DTEND;VALUE=DATE:20070502\r\n" .
$event->recurrence = $service->newRecurrence($recurrence);

In this example, a new event is created and set it to occur all-day, every Tuesday from 2007-05-01 until 2007-09-04. The recurrence is described using an iCalendar (RFC 2445) formatted string and stored inside of a Zend_Gdata_Extension_Recurrence object. This object is then stored within the new event by calling the setRecurrence method. The remainder of the event's properties can then be set and the event uploaded to the calendar servers.

Updating Events

The general methodology for updating an event is to retrieve the existing event from the server, update the properties you wish to change and save the changes. Here's some sample code to retrieve and update an event with a known event ID.

This sample introduces some error handling. The Zend Framework PHP client library for Google Data properties throws PHP exceptions when a HTTP error status code (generally >=400) is returned from the Calendar service. In this example, errors in Zend_Gdata_App_Feed::getEntry are caught and null is returned instead of throwing the exception further up the chain. The most likely cause of an error in this method would be if the eventId specified did not exist. If you want information on the possible errors returned by Google Data services, please see the HTTP status codes section of the Google Data Protocol Reference.

function updateEvent ($client, $eventId, $newTitle)
    $gdataCal = new Zend_Gdata_Calendar($client);
    if ($eventOld = getEvent($client, $eventId)) {
      echo "Old title: " . $eventOld->title->text . "<br />\n";
      $eventOld->title = $gdataCal->newTitle($newTitle);
      try {
      } catch (Zend_Gdata_App_Exception $e) {
        return null;
      $eventNew = getEvent($client, $eventId);
      echo "New title: " . $eventNew->title->text . "<br />\n";
      return $eventNew;
    } else {
      return null;

updateEvent($client, 'ot9j78u2gfklfflnelcdrduz', 'New Years Party');

Deleting Events

There are two different ways to delete an event. The proper method to be used depends upon what information about the event you already have available.

If you already have access to a EventEntry object (such as $eventOld or $eventNew from the previous sections), you can delete the associated event by calling its delete method.

// $event is an instance of Zend_Gdata_Calendar_EventEntry

Alternatively, events can be deleted by passing their edit URL to Zend_Gdata_App::delete. Since this method avoids contacting the Calendar servers to retrieve an event's details, it is preferable when the desired EventEntry instance is not readily available.

// Retrieve the edit URL for an event. When using this method, this URL
// should already be available somewhere locally, such as in a database.
$eventEditUrl = $event->getLink('edit')->href;

// Once the edit URL is available, it can be used to issue the delete request.
// $gdataCal is an instance of Zend_Gdata_Calendar, which inherits from Zend_Gdata_App.

When using Zend_Gdata_App::delete, be sure to provide the edit URL and not the standard event URL stored inside of an EventEntry's id property. Using the wrong URL will result in an HTTP 400/Bad Request error to be returned from the server.

Additional operations

This section describes other Calendar operations you can perform with the Google Data PHP client library.

Extended properties

You can add extended properties (arbitrary name-value pairs) to Calendar events by calling setExtededProperty and providing an array of Zend_Gdata_Extension_ExtendedProperty instances. These can be used to store application-specific IDs or other small amounts of information your application needs when interacting with a Google Calendar. Extended properties are only accessible through the API — they do not appear in the Calendar user interface.

function addExtendedProperty ($client, $eventId,
    $name='', $value='1234')
  $gc = new Zend_Gdata_Calendar($client);
  if ($event = getEvent($client, $eventId)) {
    $extProp = $gc->newExtendedProperty($name, $value);
    $extProps = array_merge($event->extendedProperty, array($extProp));
    $event->extendedProperty = $extProps;
    $eventNew = $event->save();
    return $eventNew;
  } else {
    return null;

Once an extended property has been associated with the entry, the entry needs to be saved to the calendar servers. Note that extended properties cannot be deleted from an event once created, though they can be modified.

Reminders and Notifications

Reminders can be added to events by calling getWhen, selecting the relevant Zend_Gdata_Extension_When object, and attaching the reminder to it by calling setReminders and providing an array of Zend_Gdata_Extension_Reminder instances. Each event may have up to five reminders attached to it.

Reminders contain two fundamental attributes: their method and activation time. The method is set by calling setMethod and may be either 'alert', 'email', or 'sms'. 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.

The activation time is set by calling either setAbsoluteTime, setDays, setHours, or setMinutes and specifies how far in advance of the event the reminder should be triggered. If your reminder has a mixed activation time, convert it to the most precise unit available. For example, '1 hour and 30 minutes' should be stored as simply '90 minutes'. Only reminder time periods found in the Google Calendar web interface are valid to use in the API.

function setReminder($client, $eventId, $minutes=15)
  $gc = new Zend_Gdata_Calendar($client);
  $method = "alert";
  if ($event = getEvent($client, $eventId)) {
    $times = $event->when;
    foreach ($times as $when) {
        $reminder = $gc->newReminder();
        $when->reminder = array($reminder);
    $eventNew = $event->save();
    return $eventNew;
  } else {
    return null;

This example creates an email reminder scheduled for 10 minutes before the event, and associates it with the first time specified for the event. As with any modification, the event should be saved to the calendar service after creating a reminder.

For an event to inherit the default reminder setting of your Google Calendar account, set the reminder's method to 'all'.

To delete a reminder from an event, either remove the reminder from its array or set the reminder's method to 'none'.

Authentication required

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

Signing you in...

Google Developers needs your permission to do that.