My favorites | English | Sign in

Faster apps faster - GWT 2.0 with Speed Tracer New!

Google Spreadsheets APIs and Tools (Labs)

Developer's Guide: Protocol

The Google Spreadsheets Data API allows client applications to view and update Spreadsheets content in the form of Google Data API feeds.

Your client application can request a list of a user's spreadsheets, edit or delete content in an existing Spreadsheets worksheet, and query the content in an existing Spreadsheets worksheet.

Contents

Audience

This document is intended for programmers who want to write client applications that can interact with Google Spreadsheets. 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 sections of this developer's guide.

For Spreadsheets Data API reference information, see the reference guide.

This document assumes that you understand the general ideas behind the Google Data APIs protocol.

Getting started

Assume you're creating a client application that needs to communicate with Spreadsheets. You want your client to be able to get a list of rows or a collection of individual cells from a worksheet, and to be able to add a row or cell to that worksheet. This developer guide will walk you through these actions.

Note: If you don't already have a Spreadsheets account, you may want to create one for testing purposes. To follow the examples in this document, you'll also have to manually create a sample spreadsheet, as described in the Creating a spreadsheet section.

You can, of course, interact with Spreadsheets in other ways too: update an entry, delete an entry, and so on, all using the Data API protocol or the client libraries.

Note: The size limits described in How big can each document/spreadsheet be? (in the Google Docs & Spreadsheets Help Center) also apply to spreadsheets that you interact with using the Google Data protocol. In addition to the limits outlined in the article, Google Data imposes a usage limit: you can't send more than twenty data updates per second.

For general information about Google Data APIs and more example code that you can adapt for use with Spreadsheets, see the list of Client Libraries.

Creating a spreadsheet

It is possible to create a new spreadsheet by uploading a spreadsheet file via the Google Documents List Data API. The Spreadsheets Data API does not currently provide a way to delete a spreadsheet. For testing purposes, you may create a spreadsheet manually or upload one.

The examples in this document use a spreadsheet containing the following data. Note that the Items Per Minute (IPM) row uses a formula: =FLOOR(R[0]C[-1]/(R[0]C[-2]*60),.0001).

A B C D
1 Name Hours Items IPM
2 Bingley 10 2 0.0033
3 Captain Carter 200 75360 6.28
4 Dawson 200 100000 8.3333
5 Colonel Forster 50 300 0.1
6 William Goulding 100 25842 4.307
7 Lady Lucas 100 25670 4.2783
8 Sir William 190 98765 8.6635
9 Charlotte 60 18000 5

Authenticating to the Spreadsheets service

To request or edit spreadsheet data for an unpublished spreadsheet, your client needs an authorization header. The following sections explain how to authenticate for different types of client applications.

Note: You don't need to authenticate to request data from a published spreadsheet. (A published spreadsheet is one that the user has marked as published using the Spreadsheets GUI.)

Your choice of authentication method should be determined by the kind of client you're writing: single-user desktop applications should use the ClientLogin system, while multi-user web apps should use the AuthSub system.

Whichever method you choose, you can either send raw HTTP requests, or have Google's client libraries handle the authentication for you.

For more information on AuthSub and ClientLogin, see the Google Data APIs authentication documentation.

Single-user "installed" client authentication

To authenticate the user using ClientLogin (also called "Authentication for Installed Applications"), send a POST request to the following URL:

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

Include the relevant parameters in the body of the POST request, as described in the ClientLogin documentation. The service name for Spreadsheets is wise.

If the request succeeds, then the response contains an alphanumeric string labeled Auth.

Note: As described in the ClientLogin documentation, the authentication request may fail and request a CAPTCHA challenge. If you want Google to issue and handle the CAPTCHA challenge, then send the user to https://www.google.com/accounts/DisplayUnlockCaptcha?service=wise (rather than to the CAPTCHA-handling URL given in the ClientLogin documentation).

After a successful authentication request, use the Auth value to create an Authorization header for each request:

Authorization: GoogleLogin auth=yourAuthValue

Multiple-user web application client authentication

AuthSub proxy authentication is used by web applications that need to authenticate their users to Google accounts. Your client application does not need access to the username and password for the Google Spreadsheets user—instead, it uses special AuthSub tokens.

To acquire an AuthSub token for a given Google Spreadsheets user, your application must redirect the user to the AuthSubRequest URL, which prompts them to log into their Google account.

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 authorization header to the next URL, as the value of the token query parameter. Your application then uses that authorization header in subsequent interactions with Spreadsheets.

The below example shows a request to authorize foo.com:

https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Fspreadsheets.google.com%2Ffeeds%2F&session=1&secure=0&next=http%3A%2F%2Fwww.foo.com%2Fhandletoken.pyc

Upgrading to a session token

By default, the AuthSub token can only be used for one request. To receive a token which can be used for multiple requests it must be upgraded by making an HTTP GET request which contains the single use token as an Authorization header. A token may only be upgraded if the initial AuthSub request included session=1 as a URL parameter.

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

If the token was upgraded successfully, the server's response contains the new token information in the HTTP headers. Here's an example response:

Token=DQAA...7DCTN
Expiration=20061004T123456Z

Use the authorization header to create an Authorization header for each request:

Authorization: AuthSub token="yourAuthToken"

For details, including information on registering your application with Google and other topics, see the AuthSub documentation.

Note: The token value in the Authorization header should be surrounded by quotation marks.

Specifying a version

Every request that you send using the Spreadsheets Data API should specify version 3.0 of the API.

To specify a version number, use the GData-Version HTTP header:

GData-Version: 3.0

Alternatively, if you can't set HTTP headers, you can specify v=3.0 as a query parameter in the URL. But the HTTP header is preferred where possible.

Note: The client libraries supply appropriate version headers automatically, so don't use the v=3.0 query parameter when you're using a client library.

Retrieving a list of spreadsheets

You can request a feed containing a list of the currently authenticated user's spreadsheets by sending an authenticated GET request to the following URL:

http://spreadsheets.google.com/feeds/spreadsheets/private/full

The result is a "metafeed," a feed that lists all of that user's feeds of a particular type; in this case, each entry in the feed represents a spreadsheet associated with the user.

This feed is accessible only using an authorization header.

An entry in the spreadsheets metafeed might resemble the following. The following example has been edited a little to make it a little more readable by humans; in particular, a real spreadsheets metafeed contains actual spreadsheet IDs where the following listing says key.

<entry gd:etag='"BxAUSQUJRCp7ImBq"'>
  <id>http://spreadsheets.google.com/feeds/spreadsheets/private/full/key</id>
  <updated>2006-11-17T18:24:18.231Z</updated>
  <title type="text">Groceries R Us</title>
  <content type="text">Groceries R Us</content>
  <link rel="http://schemas.google.com/spreadsheets/2006#worksheetsfeed"
    type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/worksheets/key/private/full"/>
  <link rel="alternate" type="text/html"
    href="http://spreadsheets.google.com/ccc?key=key"/>
  <link rel="self" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/spreadsheets/private/full/key"/>
  <author>
    <name>Fitzwilliam Darcy</name>
    <email>fitz@gmail.com</email>
  </author>
</entry>

Note that the key value that appears here is the same as the key value that appears in the URL displayed in the address bar of your browser window when you open the spreadsheet manually.

The URI given in the <link> element with rel="http://schemas.google.com/spreadsheets/2006#worksheetsfeed" is the URI of the worksheets metafeed for that spreadsheet, which lists all the worksheets the user has access to in that spreadsheet. If that URI ends with /private/values, that indicates that the current authenticated user can only view the spreadsheet, not edit it. If it ends with /private/full, that indicates that the current authenticated user is authorized to add and edit data in the worksheets.

Note: User access levels are set in the GUI. If a user owns a given worksheet or is listed as an editor, then they have read/write access; if they're listed only as a viewer, then they have read-only access. In addition, if the worksheet is published then even unauthenticated users and users not listed as viewers have read access.

For further information about the spreadsheets metafeed, see the Spreadsheet metafeed reference documentation.

If the metafeed contains no entries, it means there are no spreadsheets created or shared by this account. Create a spreadsheet manually and request the metafeed again.

Working with worksheet-based feeds

A given spreadsheet may contain multiple worksheets. For each spreadsheet, there's a worksheets metafeed listing all the worksheets in that spreadsheet.

The following sections describe how to get a worksheet-based feed, add a worksheet to a spreadsheet, update the metadata of a worksheet, and remove a worksheet from the spreadsheet.

Retrieving a worksheet-based feed

To determine the URL of a given spreadsheet's worksheets metafeed, find that spreadsheet's entry in the spreadsheets metafeed, as described in the previous section. Then examine the <link> element that has rel="http://schemas.google.com/spreadsheets/2006#worksheetsfeed". That element's href value provides the URL for that spreadsheet's worksheets metafeed.

To request a list of worksheets in a given spreadsheet, issue a GET request to that URL, with an appropriate authorization header:

GET http://spreadsheets.google.com/feeds/worksheets/key/private/full

There are several other visibility and projection values that you can use instead of private and full; for more information, see Spreadsheets feed types in the reference document.

Spreadsheets returns an Atom feed resembling the following. This example has been edited a little to make it a little more readable by humans; in particular, a real worksheets metafeed contains actual spreadsheet IDs where the following listing says key. Note that the string worksheetId, which appears several times in the example, is the permanent unique ID of a specific worksheet within the spreadsheet.

<feed xmlns="http://www.w3.org/2005/Atom"
    xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006"
    xmlns:gd="http://schemas.google.com/g/2005"
    gd:etag='W/"D0cERnk-eip7ImA9WBBXGEg."'>
  <id>http://spreadsheets.google.com/feeds/worksheets/key/private/full</id>
  <updated>2006-11-17T18:23:45.173Z</updated>
  <title type="text">Groceries R Us</title>
  <link rel="alternate" type="text/html"
    href="http://spreadsheets.google.com/ccc?key=key"/>
  <link rel="http://schemas.google.com/g/2005#feed"
    type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/worksheets/key/private/full"/>
  <link rel="self" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/worksheets/key/private/full"/>
  <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/worksheets/key/private/full"/>
  <author>
    <name>Fitzwilliam Darcy</name>
    <email>fitz@gmail.com</email>
  </author>
  <openSearch:totalResults>1</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>1</openSearch:itemsPerPage>
  <entry gd:etag='"YDwqeyI."'>
    <id>http://spreadsheets.google.com/feeds/worksheets/key/private/full/worksheetId</id>
    <updated>2006-11-17T18:23:45.173Z</updated>
    <title type="text">Sheet1</title>
    <content type="text">Sheet1</content>
    <link rel="http://schemas.google.com/spreadsheets/2006#listfeed"
      type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full"/>
    <link rel="http://schemas.google.com/spreadsheets/2006#cellsfeed"
      type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full"/>
    <link rel="self" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/worksheets/key/private/full/worksheetId"/>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/worksheets/key/private/full/worksheetId/version"/>
    <gs:rowCount>100</gs:rowCount>
    <gs:colCount>20</gs:colCount>
  </entry>
</feed>

For further information about the worksheets metafeed, see the Worksheet-based feed section of the reference document.

Retrieving a feed again

If you want to retrieve a feed that you've retrieved before, you can improve efficiency by telling Spreadsheets to send the feed only if it has changed since the last time you retrieved it.

To do this sort of conditional retrieval, send an HTTP GET request that includes an HTTP If-None-Match header. In the header, specify the feed's ETag, which you can find in the <feed> element's gd:etag attribute.

For example:

If-None-Match: W/"D0cERnk-eip7ImA9WBBXGEg."

When Spreadsheets receives this request, it checks to see whether the feed that you requested has the same ETag as the ETag you specified. If the ETags match, then the feed hasn't changed, and Spreadsheets returns either an HTTP 304 Not Modified status code or an HTTP 412 Precondition Failed status code. Both of those status codes indicate that the feed you've already retrieved is up-to-date.

If the ETags don't match, then the feed has been modified since the last time you requested it, and Spreadsheets returns the feed.

For more information about ETags, see the Google Data APIs reference guide.

Adding a worksheet

To add a worksheet to the spreadsheet, start by creating an <entry> element containing the relevant data:

<entry xmlns="http://www.w3.org/2005/Atom"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006">
  <title>Expenses</title>
  <gs:rowCount>50</gs:rowCount>
  <gs:colCount>10</gs:colCount>
</entry>

From within the worksheets feed, you then need to then look for the POST URL. This URL will be the value of the href attribute of the <link> element that has the rel value, set to http://schemas.google.com/g/2005#post:

<link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' \
    href='http://spreadsheets.google.com/feeds/worksheets/key/private/full' />

Note: From the spreadsheets feed, this <link> element would have its rel attribute set to http://schemas.google.com/spreadsheets/2006#worksheetsfeed.

Next, do any necessary authentication, and create an Authorization header for a new POST request as described in the authentication sections of this document.

In the body of the POST request, place the Atom <entry> element you created above, using the application/atom+xml content type.

Now send the request to the POST URL:

POST http://spreadsheets.google.com/feeds/worksheets/key/private/full

Spreadsheets inserts the new worksheet immediately after the last worksheet that appears in Spreadsheets UI.

Updating a worksheet's metadata

To change the metadata of a worksheet, begin by getting the desired worksheet from the worksheet feed. Then update the worksheet's metadata and send a PUT request with the desired entry contents to the URL provided in an edit link. The edit URL is highlighted in the XML below.

<entry>
  <id>
    http://spreadsheets.google.com/feeds/worksheets/key/private/full/worksheetId
  </id>
  <updated>2007-07-30T18:51:30.666Z</updated>
  <category scheme="http://schemas.google.com/spreadsheets/2006"
    term="http://schemas.google.com/spreadsheets/2006#worksheet"/>
  <title type="text">Income</title>
  <content type="text">Expenses</content>
  <link rel="http://schemas.google.com/spreadsheets/2006#listfeed"
    type="application/atom+xml" href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full"/>
  <link rel="http://schemas.google.com/spreadsheets/2006#cellsfeed"
    type="application/atom+xml" href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full"/>
  <link rel="self" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/worksheets/key/private/full/worksheetId"/>
  <link rel="edit" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/worksheets/key/private/full/worksheetId/version"/>
  <gs:rowCount>45</gs:rowCount>
  <gs:colCount>15</gs:colCount>
</entry>

Note: Metadata includes the title of the worksheet and the number of rows and columns. Setting the number of rows or columns to less than the original will delete the cells and contents that do not exist within the new boundaries WITHOUT WARNING.

Deleting a worksheet

To delete a worksheet, perform a DELETE request on the edit URL after obtaining it as described above.

Note: If you delete a worksheet, that worksheet is completely removed from the spreadsheet and all data contained on that worksheet is discarded.

Working with table feeds

A table feed is a feed that allows you to treat part or all of a worksheet somewhat like a table in a database—that is, as a set of structured data items.

A table feed is like a list-based feed in that it shows data in rows, which in a table feed are called records. However, a table feed is more flexible than a list-based feed. The table shown in a table feed can be a subset of the data in the worksheet; it can even use a set of disjoint columns, and you can define multiple tables in a single worksheet. Also, table data can come from anywhere in the worksheet; a table doesn't have to start at the top left corner of the worksheet.

On the other hand, unlike list-based feeds, tables don't exist until you explicitly create them—before you can use a table feed, you have to explicitly define where the table data comes from, using the Data API.

Creating a table

Before creating a table using the Data API, look at the worksheet and determine the rows and columns from the worksheet that you want to make up the table.

Note: You can't create a table using the Spreadsheets GUI; you can create a table only by using the Data API.

To create the table, start by creating an <entry> element containing the relevant data:

<entry xmlns="http://www.w3.org/2005/Atom"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006">
  <title type='text'>Table 1</title>
  <summary type='text'>This is a list of all who have registered to vote and
    whether or not they qualify to vote.</summary>
  <gs:worksheet name='Sheet1' />
  <gs:header row='1' />
  <gs:data numRows='0' startRow='2'>
    <gs:column index='B' name='Birthday' />
    <gs:column index='C' name='Age' />
    <gs:column index='A' name='Name' />
    <gs:column index='D' name='CanVote' />
  </gs:data>
</entry>

You can specify the header row, the start row for the data, the number of rows, and the columns (and order of columns) to use. Thus, the table can consist of a header row, any number of data rows that are adjacent in the worksheet, and any set of columns, in any order.

Now determine the appropriate URL to send the entry to, known as the POST URL. You can find the POST URL in the table feed's <link> element that has rel="http://schemas.google.com/g/2005#post".

Next, do any necessary authentication, and create an Authorization header for a new POST request as described in the authentication sections of this document.

In the body of the POST request, place the Atom <entry> element you created above, using the application/atom+xml content type.

Now send the request to the POST URL:

POST http://spreadsheets.google.com/feeds/key/tables

Spreadsheets creates a new table. The table is not visible in the GUI, but you can operate on it using the table and record feeds as if the table were a contiguous region of data.

Retrieving a table

To retrieve a table feed, send the following GET request, using the table feed's URI and an appropriate authorization header:

GET http://spreadsheets.google.com/feeds/key/tables

Google Spreadsheets returns an Atom feed resembling the following:

<?xml version='1.0' encoding='utf-8'?>
<feed xmlns="http://www.w3.org/2005/Atom"
    xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006"
    xmlns:gd="http://schemas.google.com/g/2005"
    gd:etag='W/"DEQHQn84fCt7ImA9WxJTGEU."'>
  <id>
    http://spreadsheets.google.com/feeds/key/tables</id>
  <updated>2009-04-28T02:38:53.134Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/spreadsheets/2006#table' />
  <title>Sample table and record feed</title>
  <link rel='alternate' type='text/html'
    href='http://spreadsheets.google.com/ccc?key=key' />
  <link rel='http://schemas.google.com/g/2005#feed'
    type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/tables' />
  <link rel='http://schemas.google.com/g/2005#post'
    type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/tables' />
  <link rel='self' type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/tables' />
  <author>
    <name>Liz</name>
    <email>liz@gmail.com</email>
  </author>
  <openSearch:totalResults>2</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <entry gd:etag='"HBcUVgtWASt7ImBq"'>
    <id>
      http://spreadsheets.google.com/feeds/key/tables/0</id>
    <updated>2009-04-28T01:20:32.707Z</updated>
    <app:edited xmlns:app="http://www.w3.org/2007/app">
      2009-04-28T01:20:32.707Z</app:edited>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/spreadsheets/2006#table' />
    <title>Table 1</title>
    <summary>This is a list of all who have registered to vote and
      whether or not they qualify to vote.</summary>
    <content type='application/atom+xml;type=feed'
      src='http://spreadsheets.google.com/feeds/key/records/0' />
    <link rel='self' type='application/atom+xml'
      href='http://spreadsheets.google.com/feeds/key/tables/0' />
    <link rel='edit' type='application/atom+xml'
      href='http://spreadsheets.google.com/feeds/key/tables/0' />
    <gs:worksheet name='Sheet1' />
    <gs:header row='1' />
    <gs:data insertionMode='overwrite' numRows='2' startRow='2'>
      <gs:column index='B' name='Birthday' />
      <gs:column index='C' name='Age' />
      <gs:column index='A' name='Name' />
      <gs:column index='D' name='CanVote' />
    </gs:data>
  </entry>
  <entry gd:etag='"HBcUVgdCGyt7ImBq"'>
    <id>
      http://spreadsheets.google.com/feeds/key/tables/1</id>
    <updated>2009-04-28T01:20:38.313Z</updated>
    <app:edited xmlns:app="http://www.w3.org/2007/app">
      2009-04-28T01:20:38.313Z</app:edited>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/spreadsheets/2006#table' />
    <title>Table 2</title>
    <summary>This is a list of detailed information about each voter.</summary>
    <content type='application/atom+xml;type=feed'
      src='http://spreadsheets.google.com/feeds/key/records/1' />
    <link rel='self' type='application/atom+xml'
      href='http://spreadsheets.google.com/feeds/key/tables/1' />
    <link rel='edit' type='application/atom+xml'
      href='http://spreadsheets.google.com/feeds/key/tables/1' />
    <gs:worksheet name='Sheet1' />
    <gs:header row='30' />
    <gs:data insertionMode='overwrite' numRows='10' startRow='34'>
      <gs:column index='C' name='Last' />
      <gs:column index='B' name='First' />
      <gs:column index='D' name='DOB' />
      <gs:column index='E' name='Driver License?' />
    </gs:data>
  </entry>
</feed>

Note that in this example, there are two different tables defined in the same worksheet.

Updating a table's metadata

To change the rows and columns that a table is composed of, first you retrieve the table you want to update, then you modify it as desired, and then you send a PUT request, with the updated table in the message body, to the table's edit URL.

To make sure that your update doesn't overwrite another client's changes, include an HTTP If-Match header that contains the original table's ETag value. You can determine the original table's ETag value by examining the <entry> element's gd:etag attribute.

If you want to update the table regardless of whether someone else has updated it since you retrieved it, then use If-Match: * and don't include the ETag.

For more information about ETags, see the Google Data APIs reference guide.

Be sure that the <id> value in the entry you PUT exactly matches the <id> of the existing entry.

Deleting a table

To delete a table, first you retrieve the table you want to delete, then you send a DELETE request to the table's edit URL. This is the same URL used to update the table.

If you want to make sure that you don't delete a table that has been changed by another client since you retrieved it, include an HTTP If-Match header that contains the original table's ETag value. You can determine the original table's ETag value by examining the <entry> element's gd:etag attribute.

If you want to delete the table regardless of whether someone else has updated it since you retrieved it, then use If-Match: * and don't include the ETag. (In this case, you don't need to retrieve the table before deleting it.)

For more information about ETags, see the Google Data APIs reference guide.

Note: If you delete a table, the data contained in the table remains in the worksheet. Deleting a table doesn't change how the worksheet looks in the GUI; it merely means that the Spreadsheets Data API no longer treats those particular rows and columns as a single entity.

Working with record feeds

A table consists of a set of records. For a given table, you can retrieve that table's record feed to see the contents of the records.

Note that the order of items in each record is the same as the order of columns in the table definition, which may not match the order of columns in the GUI.

Creating a table record

To insert a new record into a table, start by creating a new <entry> element containing the relevant data:

<entry xmlns="http://www.w3.org/2005/Atom"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006">
  <title>Darcy</title>
  <gs:field name='Birthday'>2/10/1785</gs:field>
  <gs:field name='Age'>28</gs:field>
  <gs:field name='Name'>Darcy</gs:field>
  <gs:field name='CanVote'>No</gs:field>
</entry>

Then determine the appropriate URL to send the entry to, known as the POST URL. You can find the POST URL in the record feed's <content> element that has type="application/atom+xml;type=feed".

Next, do any necessary authentication, and create an Authorization header for a new POST request as described in the authentication sections of this document.

In the body of the POST request, place the Atom <entry> element you created above, using the application/atom+xml content type.

Now send the request to the POST URL:

POST http://spreadsheets.google.com/feeds/key/records/tableId

When you insert a new record, Spreadsheets adds the new data to a row in the worksheet, then adds a new record to the table using the newly added data.

The choice of which worksheet row to put the data in is determined by the table's mode:

  • If the table is set to use insert mode, then Spreadsheets adds a new row to the worksheet, and puts the new data in that new row.
  • If the table is set to use overwrite mode, then Spreadsheets uses the next unused row from the worksheet. If there are no unused rows in the worksheet, then Spreadsheets adds a new row to the worksheet, as if the table were set to use insert mode.

Retrieving a table record

To retrieve a table's record feed, send the following GET request, using the record feed's URI and an appropriate authorization header:

GET http://spreadsheets.google.com/feeds/key/records/tableNumber

Google Spreadsheets returns an Atom feed resembling the following:

<?xml version='1.0' encoding='utf-8'?>
<feed xmlns="http://www.w3.org/2005/Atom"
    xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006"
    xmlns:gd="http://schemas.google.com/g/2005"
    gd:etag='W/"DEQHQn84fCt7ImA9WxJTGEU."'>
  <id>http://spreadsheets.google.com/feeds/key/records/0</id>
  <updated>2009-04-28T02:38:53.134Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/spreadsheets/2006#record' />
  <title>Table 1</title>
  <link rel='alternate' type='text/html'
    href='http://spreadsheets.google.com/pub?key=key' />
  <link rel='http://schemas.google.com/g/2005#feed'
    type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/records/0' />
  <link rel='http://schemas.google.com/g/2005#post'
    type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/records/0' />
  <link rel='self' type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/records/0' />
  <author>
    <name>Liz</name>
    <email>liz@gmail.com</email>
  </author>
  <openSearch:totalResults>2</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <entry gd:etag='"UB8DTlJAKSt7ImA-WkUT"'>
    <id>
      http://spreadsheets.google.com/feeds/key/records/0/cn6ca</id>
    <updated>2009-04-28T02:38:53.134Z</updated>
    <app:edited xmlns:app="http://www.w3.org/2007/app">
      2009-04-28T02:38:53.134Z</app:edited>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/spreadsheets/2006#record' />
    <title>Darcy</title>
    <content>Birthday: 2/10/1785, Age: 28, Name: Darcy,
      CanVote: No</content>
    <link rel='self' type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/records/0/cn6ca' />
    <link rel='edit' type='application/atom+xml'
    href='http://spreadsheets.google.com/feeds/key/records/0/cn6ca' />
    <gs:field index='B' name='Birthday'>2/10/1785</gs:field>
    <gs:field index='C' name='Age'>28</gs:field>
    <gs:field index='A' name='Name'>Darcy</gs:field>
    <gs:field index='D' name='CanVote'>No</gs:field>
  </entry>
  <entry gd:etag='"UVBFUEcNRCt7ImA9DU8."'>
    <id>
      http://spreadsheets.google.com/feeds/key/records/0/cokwr</id>
    <updated>2009-04-28T02:38:53.134Z</updated>
    <app:edited xmlns:app="http://www.w3.org/2007/app">
      2009-04-28T02:38:53.134Z</app:edited>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/spreadsheets/2006#record' />
    <title>Jane</title>
    <content>Birthday: 1/6/1791, Age: 22, Name: Jane,
      CanVote: Yes</content>
    <link rel='self' type='application/atom+xml'
      href='http://spreadsheets.google.com/feeds/key/records/0/cokwr' />
    <link rel='edit' type='application/atom+xml'
      href='http://spreadsheets.google.com/feeds/key/records/0/cokwr' />
    <gs:field index='B' name='Birthday'>1/6/1791</gs:field>
    <gs:field index='C' name='Age'>22</gs:field>
    <gs:field index='A' name='Name'>Jane</gs:field>
    <gs:field index='D' name='CanVote'>Yes</gs:field>
  </entry>
</feed>

Reverse-sorting records

By default, records in the feed appear in the same order as the corresponding rows in the GUI; that is, they're in order by row number. To get records in reverse order, send the following request, using the reverse query parameter to specify the sort order:

GET http://spreadsheets.google.com/feeds/key/records/tableNumber?reverse=true

To sort by the values in a particular column, rather than by row number, use the orderby query parameter.

For more information about orderby and reverse, see the Record-feed query parameters reference section.

Sending a structured query for records

You can use the structured query parameter sq to produce a feed with entries that meet the specified criteria.

This works the same way as the list-feed structured query, but with table records instead of rows. For example, to query for employees in a table who have more than 40 hours of experience but are not meeting the 4 items-per-minute minimum, the HTTP request would be as follows:

GET http://spreadsheets.google.com/feeds/key/records/tableNumber?sq=ipm<4%20and%20hours>40

Note: You must always URL-encode your query parameters.

For more information about the structured query syntax, see the Record-feed query parameters reference section.

Updating a table record

To update the contents of an existing record, first you retrieve the record you want to update, then you modify it as desired, and then you send a PUT request, with the updated record in the message body, to the record's edit URL.

To make sure that your update doesn't overwrite another client's changes, include an HTTP If-Match header that contains the original record's ETag value. You can determine the original record's ETag value by examining the <entry> element's gd:etag attribute.

If you want to update the record regardless of whether someone else has updated it since you retrieved it, then use If-Match: * and don't include the ETag.

For more information about ETags, see the Google Data APIs reference guide.

Be sure that the <id> value in the entry you PUT exactly matches the <id> of the existing entry.

Deleting a table record

To delete a record, first you retrieve the record you want to delete, then you send a DELETE request to the record's edit URL. This is the same URL used to update the record.

If you want to make sure that you don't delete a record that has been changed by another client since you retrieved it, include an HTTP If-Match header that contains the original record's ETag value. You can determine the original record's ETag value by examining the <entry> element's gd:etag attribute.

If you want to delete the record regardless of whether someone else has updated it since you retrieved it, then use If-Match: * and don't include the ETag. (In this case, you don't need to retrieve the record before deleting it.)

For more information about ETags, see the Google Data APIs reference guide.

Note: When you delete a record, the cells that comprise the record become empty in the worksheet.

Working with list-based feeds

A given worksheet generally contains multiple rows, each containing multiple cells. You can request data from the worksheet either as a list-based feed, in which each entry represents a row, or as a cell-based feed, in which each entry represents a single cell. For information on cell-based feeds, see Working with cell-based feeds.

The following sections describe how to get a list-based feed, add a row to a worksheet, and send queries with various query parameters.

The list feed makes some assumptions about how the data is laid out in the spreadsheet.

In particular, the list feed treats the first row of the worksheet as a header row; Spreadsheets dynamically creates XML elements named after the contents of header-row cells. Users who want to provide Data API feeds should not put any data other than column headers in the first row of a worksheet.

The list feed contains all rows after the first row up to the first blank row. The first blank row terminates the data set. If expected data isn't appearing in a feed, check the worksheet manually to see whether there's an unexpected blank row in the middle of the data. In particular, if the second row of the spreadsheet is blank, then the list feed will contain no data.

A row in a list feed is as many columns wide as the worksheet itself.

Retrieving a list-based feed

To determine the URL of a list-based feed for a given worksheet, get the worksheets metafeed and examine the <link> element in which rel is http://schemas.google.com/spreadsheets/2006#listfeed. The href value in that element is the list feed's URI.

To retrieve a list-based feed, send the following GET request, using the list feed's URI and an appropriate authorization header:

GET http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full

Google Spreadsheets returns an Atom feed resembling the following:

<feed xmlns="http://www.w3.org/2005/Atom"
    xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/"
    xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended"
    xmlns:gd="http://schemas.google.com/g/2005"
    gd:etag='W/"D0cERnk-eip7ImA9WBBXGEg."'>
  <id>http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full</id>
  <updated>2006-11-17T18:23:45.173Z</updated>
  <title type="text">Sheet1</title>
  <link rel="alternate" type="text/html"
    href="http://spreadsheets.google.com/ccc?key=key"/>
  <link rel="http://schemas.google.com/g/2005#feed"
    type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full"/>
  <link rel="http://schemas.google.com/g/2005#post"
    type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full"/>
  <link rel="self" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full"/>
  <author>
    <name>Fitzwilliam Darcy</name>
    <email>fitz@gmail.com</email>
  </author>
  <openSearch:totalResults>8</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>8</openSearch:itemsPerPage>
  <entry gd:etag='"S0wCTlpIIip7ImA0X0QI"'>
    <id>http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId</id>
    <updated>2006-11-17T18:23:45.173Z</updated>
    <category scheme="http://schemas.google.com/spreadsheets/2006"
      term="http://schemas.google.com/spreadsheets/2006#list"/>
    <title type="text">Bingley</title>
    <content type="text">Hours: 10, Items: 2, IPM: 0.0033</content>
    <link rel="self" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId"/>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId/version"/>
    <gsx:name>Bingley</gsx:name>
    <gsx:hours>10</gsx:hours>
    <gsx:items>2</gsx:items>
    <gsx:ipm>0.0033</gsx:ipm>
  </entry>

  ...

  <entry gd:etag='"AxQDSXxjfyp7ImA0ChJVSBI."'>
    <id>http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId</id>
    <updated>2006-11-17T18:23:45.173Z</updated>
    <category scheme="http://schemas.google.com/spreadsheets/2006"
      term="http://schemas.google.com/spreadsheets/2006#list"/>
    <title type="text">Charlotte</title>
    <content type="text">Hours: 60, Items: 18000, IPM: 5</content>
    <link rel="self" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId"/>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId/version"/>
    <gsx:name>Charlotte</gsx:name>
    <gsx:hours>60</gsx:hours>
    <gsx:items>18000</gsx:items>
    <gsx:ipm>5</gsx:ipm>
  </entry>
</feed>

Each entry represents a row in the worksheet. The <title> element contains the contents of the first cell in the row, and the <content> element contains a textual representation of the data from all the other cells in the row.

Each item in the gsx namespace represents the contents of a cell in the row, with elements in the gsx namespace named after the contents of the header cells—that is, the cells in the first row of the worksheet. If a particular header cell is empty, then a unique column ID is used for the gsx element name. If the header cell's content contains a space, it will be removed in the gsx element name. For more information, see the gsx namespace elements section of the reference document.

Note: In a column with an empty header cell, empty cells don't appear as gsx elements; in such a column, only cells that contain data appear as gsx elements.

The entries are ordered in the same order in which they appear in the worksheet GUI, unless the query includes the orderby query parameter.

For further information about the list feed, see the List-based feed reference section.

Reverse-sorting rows

By default, rows in the feed appear in the same order as the corresponding rows in the GUI; that is, they're in order by row number. To get rows in reverse order, send the following request, using the reverse query parameter to specify the sort order:

GET http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full?reverse=true

To sort by the values in a particular column, rather than by row number, use the orderby query parameter.

For more information about orderby and reverse, see the List-feed query parameters reference section.

Sending a structured query for rows

You can use the structured query parameter sq to produce a feed with entries that meet the specified criteria. Suppose in our example you wanted to determine which workers at Groceries R Us are not meeting the minimum of 4 items per minute, but you realize it is unfair to consider new employees (those with no more than 40 hours). The HTTP request would be as follows:

GET http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full?sq=ipm<4%20and%20hours>40

Note: You must always URL-encode your query parameters.

For more information about the structured query syntax, see the List-feed query parameters reference section.

Adding a list row

To add a row to the worksheet, start by creating an <entry> element containing the relevant data:

<entry xmlns="http://www.w3.org/2005/Atom"
    xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">
  <gsx:hours>1</gsx:hours>
  <gsx:ipm>1</gsx:ipm>
  <gsx:items>60</gsx:items>
  <gsx:name>Elizabeth Bennet</gsx:name>
</entry>

Then determine the appropriate URL to send the entry to, known as the POST URL. You can find the POST URL in the list feed's <link> element that has rel="http://schemas.google.com/g/2005#post".

Next, do any necessary authentication, and create an Authorization header for a new POST request as described in the authentication sections of this document.

In the body of the POST request, place the Atom <entry> element you created above, using the application/atom+xml content type.

Now send the request to the POST URL:

POST http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full

Spreadsheets inserts the new row immediately after the last row that appears in the list-based feed, which is to say immediately before the first entirely blank row.

Updating a list row

To update the contents of an existing row, first you retrieve the row you want to update, then you modify it as desired, and then you send a PUT request, with the updated row in the message body, to the row's edit URL.

To make sure that your update doesn't overwrite another client's changes, include an HTTP If-Match header that contains the original row's ETag value. You can determine the original row's ETag value by examining the <entry> element's gd:etag attribute.

If you want to update the row regardless of whether someone else has updated it since you retrieved it, then use If-Match: * and don't include the ETag.

For more information about ETags, see the Google Data APIs reference guide.

Be sure that the <id> value in the entry you PUT exactly matches the <id> of the existing entry. The edit URL is highlighted in the following row entry:

<entry gd:etag='"S0wCTlpIIip7ImA0X0QI"'>
  <id>http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId</id>
  <updated>2006-11-17T18:23:45.173Z</updated>
  <category scheme="http://schemas.google.com/spreadsheets/2006"
    term="http://schemas.google.com/spreadsheets/2006#list"/>
  <title type="text">Bingley</title>
  <content type="text">Hours: 10, Items: 2, IPM: 0.0033</content>
  <link rel="self" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId"/>
  <link rel="edit" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId/version"/>
  <gsx:name>Bingley</gsx:name>
  <gsx:hours>20</gsx:hours>
  <gsx:items>4</gsx:items>
  <gsx:ipm>0.0033</gsx:ipm>
</entry>

Deleting a list row

To delete a row, first you retrieve the row you want to delete, then you send a DELETE request to the row's edit URL. This is the same URL used to update the row.

If you want to make sure that you don't delete a row that has been changed by another client since you retrieved it, include an HTTP If-Match header that contains the original row's ETag value. You can determine the original row's ETag value by examining the <entry> element's gd:etag attribute.

If you want to delete the row regardless of whether someone else has updated it since you retrieved it, then use If-Match: * and don't include the ETag. (In this case, you don't need to retrieve the row before deleting it.)

For more information about ETags, see the Google Data APIs reference guide.

Note: If you delete a row, that row is completely removed from the worksheet.

Working with cell-based feeds

In a cell-based feed, each entry represents a single cell.

Note that it isn't recommended to interact with both a cell-based feed and a list-based feed for the same worksheet at the same time.

Retrieving a cell-based feed

To determine the URL of a cell-based feed for a given worksheet, get the worksheets metafeed and examine the <link> element in which rel is http://schemas.google.com/spreadsheets/2006#cellsfeed. The href value in that element is the cell feed's URI.

To retrieve a cell-based feed, send the following GET request, using the cell feed's URI and an appropriate authorization header:

GET http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full

Google Spreadsheets returns an Atom feed resembling the following:

<feed xmlns="http://www.w3.org/2005/Atom"
    xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006"
    xmlns:gd="http://schemas.google.com/g/2005"
    gd:etag='W/"D0cERnk-eip7ImA9WBBXGEg."'>
  <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full</id>
  <updated>2006-11-17T18:27:32.543Z</updated>
  <title type="text">Sheet1</title>
  <link rel="alternate" type="text/html"
    href="http://spreadsheets.google.com/ccc?key=key"/>
  <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full"/>
  <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml"
  <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/batch"/>
    href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full"/>
  <link rel="self" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full"/>
  <author>
    <name>Fitzwilliam Darcy</name>
    <email>fitz@gmail.com</email>
  </author>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>36</openSearch:itemsPerPage>
  <gs:rowCount>100</gs:rowCount>
  <gs:colCount>20</gs:colCount>
  <entry gd:etag='"ImA9D1APFyp7"'>
    <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R1C1</id>
    <updated>2006-11-17T18:27:32.543Z</updated>
    <category scheme="http://schemas.google.com/spreadsheets/2006"
      term="http://schemas.google.com/spreadsheets/2006#cell"/>
    <title type="text">A1</title>
    <content type="text">Name</content>
    <link rel="self" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R1C1"/>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R1C1/bgvjf"/>
    <gs:cell row="1" col="1" inputValue="Name">Name</gs:cell>
  </entry>
  <entry gd:etag='"YD0PS1YXByp7Ig.."'>
    <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R1C2</id>
    <updated>2006-11-17T18:27:32.543Z</updated>
    <category scheme="http://schemas.google.com/spreadsheets/2006"
      term="http://schemas.google.com/spreadsheets/2006#cell"/>
    <title type="text">B1</title>
    <content type="text">Hours</content>
    <link rel="self" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R1C2"/>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R1C2/1pn567"/>
    <gs:cell row="1" col="2" inputValue="Hours">Hours</gs:cell>
  </entry>

  ...

  <entry gd:etag='"ImB5CBYSRCp7"'>
    <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R9C4</id>
    <updated>2006-11-17T18:27:32.543Z</updated>
    <category scheme="http://schemas.google.com/spreadsheets/2006"
      term="http://schemas.google.com/spreadsheets/2006#cell"/>
    <title type="text">D9</title>
    <content type="text">5</content>
    <link rel="self" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R9C4"/>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R9C4/srevc"/>
    <gs:cell row="9" col="4" inputValue="=FLOOR(R[0]C[-1]/(R[0]C[-2]*60),.0001)"
      numericValue="5.0">5</gs:cell>
  </entry>
</feed>

Sending a cell range query

Suppose you want the employees to see how everyone is doing, but you do not want to post the employee names. You can request a cell feed containing only the IPM column:

GET http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full?min-row=2&min-col=4&max-col=4

That requests all the data in column 4, which in our example is the IPM column, starting with row 2 (because in our example, row 1 contains the column names).

The request explicitly specifies max-col in case more columns are added after column 4. Note that if any columns are inserted before column 4, the numbering here will no longer be accurate.

For further information about the cell feed, see the Cell-based feed reference section.

Changing contents of a cell

Suppose you want to find out the total hours that the employees of Groceries R Us have worked. You can create a formula for calculating that value, and then add the formula to a cell in the worksheet using a PUT request.

Note: Use PUT change the data in a cell, even if it is empty; the use of POST on empty cells is no longer recommended. To clear a cell, send an entry with an empty content element in your PUT request instead of using DELETE.

To add data to the worksheet, start by creating an <entry> element containing the relevant data, which in this case is a formula:

<entry xmlns="http://www.w3.org/2005/Atom"
    xmlns:gs="http://schemas.google.com/spreadsheets/2006">
  <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R2C4</id>
  <link rel="edit" type="application/atom+xml"
    href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R2C4"/>
  <gs:cell row="2" col="4" inputValue="300"/>
</entry>

Find the edit URL for the desired cell by performing a GET request. The edit URL is in the href attribute of a <link> element which has a rel attribute set to "edit".

Next, do any necessary authentication, and create an Authorization header for a new PUT request as described in the authentication sections of this document.

In the body of the PUT request, place the Atom <entry> element you created above, using the application/atom+xml content type.

Now send the PUT request to the appropriate Spreadsheets edit URL (replacing key, worksheetId, and cell with their appropriate values):

PUT http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/cell

The new data is placed in the specified cell in the worksheet. If the specified cell contains data already, it will be overwritten.

Updating multiple cells with a batch request

Suppose you want to update an entire column, row, or other set of cells. You could simply use a for loop and update the cells one by one as described in the previous section, or you could minimize the number of HTTP requests by batching the updates together.

Begin by creating a cells feed and setting the feed <id> to the href value of the POST link, appending /batch. A sample URL may look like:

http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/batch

Refer to the Adding a list row section above). Then append all the entries to be updated to the feed as per the XML shown below and set the <batch:operation> to "update". Finally, post the feed to the cells feed post link.

<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:batch="http://schemas.google.com/gdata/batch"
      xmlns:gs="http://schemas.google.com/spreadsheets/2006">
  <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full</id>
  <entry>
    <batch:id>A1</batch:id>
    <batch:operation type="update"/>
    <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R2C4</id>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R2C4/version"/>
    <gs:cell row="2" col="4" inputValue="newData"/>
  </entry>
  ...
  <entry>
    <batch:id>A2</batch:id>
    <batch:operation type="update"/>
    <title type="text">A2</title>
    <id>http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R2C5</id>
    <link rel="edit" type="application/atom+xml"
      href="http://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R2C5/version"/>
    <gs:cell row="2" col="5" inputValue="moreInfo"/>
  </entry>
</feed>

Please note that each entry element that you append to the feed element must contain the following elements:

batch:id
A batch:id element, uniquely identifying each individual cell update within the batch update request.
batch:operation
A batch:operation element, whose 'type' attribute determines the type of request to be performed (update or delete).
id
An id element containing the full URL to the cell to be updated. Be sure to examine the output XML when requesting the cellsFeed for more details.
link
A link element whose 'rel' attribute is set to "edit". The link's 'type' attribute must be set to "application/atom+xml" and the 'href' attribute must contain the full path to the cell's id (as in the 'id' element discussed above), in the following format: http://google.com/feeds/cells/key/worksheetId/private/full/R1C1CellIdentifier. Refer to the contents of the cells feed for more details.
gs:cell
A gs:cell element, whose 'row' attribute corresponds to the row being updated, whose 'col' attribute corresponds to the column being updated and whose 'inputValue' attribute contains the same information as the value of the content element discussed above.

For more information, including status handling, read Batch Processing.

Note: Only GET and PUT operations are supported for cells feed batch processing. Each element in the batch request should contain <batch:operation type="query"> and <batch:operation type="update"> respectively.

Back to top