Protocol Reference

Warning: This page is about Google's older APIs, the Google Data APIs; it's relevant only to the APIs that are listed in the Google Data APIs directory, many of which have been replaced with newer APIs. For information about a specific new API, see the new API's documentation. For information about authorizing requests with a newer API, see Google Accounts Authentication and Authorization.

This document describes the Google Data Protocol used by many Google APIs, including information about what a query looks like, what results look like, and so on.

For more information about the Google Data Protocol, see the Developer's Guide overview page and the Protocol Basics document.

Audience

This document is intended for anyone wanting to understand the details of the XML format and protocol used by the APIs that implement the Google Data Protocol.

If you just want to write code that uses one of these APIs, then you don't need to know these details; instead, you can use the language-specific client libraries.

But if you want to understand the protocol, read this document. For example, you may want to read this document to help you with any of the following tasks:

  • evaluating the Google Data Protocol architecture
  • coding using the protocol without using the provided client libraries
  • writing a client library in a new language

This document assumes that you understand the basics of XML, namespaces, syndicated feeds, and the GET, POST, PUT, and DELETE requests in HTTP, as well as HTTP's concept of a "resource." For more information about those things, see the Additional resources section of this document.

This document doesn't rely on any particular programming language; you can send and receive Google Data Protocol messages using any programming language that lets you issue HTTP requests and parse XML-based responses.

Protocol details

This section describes the Google Data Protocol document format and query syntax.

Document format

The Google Data Protocol and Atom share the same basic data model: a container that holds both some global data and any number of entries. For each protocol, the format is defined by a base schema, but it can be extended using foreign namespaces.

Atom is the default format for the Google Data Protocol. To request a response in another format, use the alt query parameter; for more information, see Query requests.

Note: Most Google Data Protocol feeds in Atom format use the Atom namespace as the default namespace by specifying an xmlns attribute on the feed element, as seen in the examples given in Protocol Basics. Thus, the examples in this document don't explicitly specify atom: for elements in an Atom-format feed.

The following tables show the Atom representation of the elements of the schema. All data not mentioned in these tables is treated as plain XML. Unless indicated otherwise, the XML elements in a given column are in the Atom namespace.

Note: This summary uses standard XPath notation: in particular, slashes show the element hierarchy, and an @ sign indicates an attribute of an element.

In each of the following tables, the highlighted items are required.

The following table shows the elements of a Google Data Protocol feed:

Feed Schema Item Atom Representation
Feed Title /feed/title
Feed ID /feed/id
Feed HTML Link /feed/link[@rel="alternate"]\
[@type="text/html"]/@href
Feed Description /feed/subtitle
Feed Language /feed/@xml:lang
Feed Copyright /feed/rights
Feed Author

/feed/author/name
/feed/author/email

(Required in certain cases; see Atom specification.)

Feed Last Update Date /feed/updated
(RFC 3339 format)
Feed Category /feed/category/@term
Feed Category Scheme /feed/category/@scheme
Feed Generator /feed/generator
/feed/generator/@uri
Feed Icon /feed/icon
Feed Logo /feed/logo

The following table shows the elements of a Google Data Protocol search-results feed. Note that the protocol exposes some of the OpenSearch 1.1 Response elements in search-results feeds.

Search Result Feed Schema Item Atom Representation
Number of Search Results /feed/openSearch:totalResults
Search Result Start Index /feed/openSearch:startIndex
Number of Search Results Per Page /feed/openSearch:itemsPerPage

The following table shows the elements of a Google Data Protocol entry:

Entry Schema Item Atom Representation
Entry ID /feed/entry/id
Entry Title /feed/entry/title
Entry Link /feed/entry/link
Entry Summary

/feed/entry/summary

(Required in certain cases; see Atom specification.)

Entry Content

/feed/entry/content

(If no content element, then entry must contain at least one <link rel="alternate"> element.)

Entry Author

/feed/entry/author/name
/feed/entry/author/email

(Required in certain cases; see Atom specification.)

Entry Category /feed/entry/category/@term
Entry Category Scheme /feed/entry/category/@scheme
Entry Publication Date /feed/entry/published
(RFC 3339)
Entry Update Date /feed/entry/updated
(RFC 3339)

Queries

This section describes how to use the query system.

Query model design tenets

The query model is intentionally very simple. The basic tenets are:

  • Queries are expressed as HTTP URIs, rather than as HTTP headers or as part of the payload. One benefit of this approach is that you can link to a query.
  • Predicates are scoped to a single item. Thus, there's no way to send a correlation query such as "find all emails from people who sent me at least 10 emails today."
  • The set of properties that queries can predicate on is very limited; most queries are simply full text search queries.
  • Result ordering is up to the implementation.
  • The protocol is naturally extensible. If you want to expose additional predicates or sorting in your service, you can do so easily through the introduction of new parameters.

Query requests

A client queries a Google service by issuing an HTTP GET request. The query URI consists of the resource's URI (called FeedURI in Atom) followed by query parameters. Most query parameters are represented as traditional ?name=value[&...] URL parameters. Category parameters are handled differently; see below.

For example, if the FeedURI is http://www.example.com/feeds/jo, then you might send a query with the following URI:

http://www.example.com/feeds/jo?q=Darcy&updated-min=2005-04-19T15:30:00Z

The Google Data Protocol supports HTTP Conditional GET. APIs that implement the protocol set the Last-Modified response header based upon the value of the <atom:updated> element in the returned feed or entry. A client can send this value back as the value of the If-Modified-Since request header to avoid retrieving the content again if it hasn't changed. If the content hasn't changed since the If-Modified-Since time, then the service returns a 304 (Not Modified) HTTP response.

APIs that implement the Google Data Protocol must support alt queries; support for other parameters is optional. Passing a standard parameter not understood by a given service results in a 403 Forbidden response. Passing an unsupported nonstandard parameter results in a 400 Bad Request response. For information on other status codes, see the HTTP status codes section of this document.

The standard query parameters are summarized in the following table. All parameter values need to be URL encoded.

Parameter Meaning Notes
alt Alternative representation type
  • If you don't specify an alt parameter, the service returns an Atom feed. This is equivalent to alt=atom.
  • alt=rss returns an RSS 2.0 result feed (for reads only). When you request data from a service in RSS format, the service supplies a feed (or other representation of the resource) in RSS format. If there's no equivalent RSS property for a given Data API property, the service uses the Atom property, labeling it with an appropriate namespace to indicate that it's an extension to RSS.
  • alt=json returns a JSON representation of the feed. More information
  • alt=json-in-script Requests a response that wraps JSON in a script tag. More information
  • alt=atom-in-script Requests an Atom response that wraps an XML string in a script tag.
  • alt=rss-in-script Requests an RSS response that wraps an XML string in a script tag.
  • alt=atom-service Requests an Atom service document that describes the feed.
author Entry author
  • The service returns entries where the author name and/or email address match your query string.
category Category query filter
  • An alternative way to perform a category filter. The two methods are equivalent.
  • To do an OR between terms, use a pipe character (|), URL-encoded as %7C. For example: http://www.example.com/feeds?category=Fritz%7CLaurie returns entries that match either category.
  • To do an AND between terms, use a comma character (,). For example: http://www.example.com/feeds?category=Fritz,Laurie returns entries that match both categories.
/-/category Category query filter
  • List each category as if it were part of the resource's URI, in the form /categoryname/—this is an exception to the usual name=value form.
  • List all categories before any other query parameters.
  • Precede the first category with /-/ to make clear that it's a category. For example, if Jo's feed has a category for entries about Fritz, you could request those entries like this: http://www.example.com/feeds/jo/-/Fritz. This allows the implementation to distinguish category-predicated query URIs from resource URIs.
  • You can query on multiple categories by listing multiple category parameters, separated by slashes. The service returns all entries that match all of the categories (like using AND between terms). For example: http://www.example.com/feeds/jo/-/Fritz/Laurie returns entries that match both categories.
  • To do an OR between terms, use a pipe character (|), URL-encoded as %7C. For example: http://www.example.com/feeds/jo/-/Fritz%7CLaurie returns entries that match either category.
  • An entry matches a specified category if the entry is in a category that has a matching term or label, as defined in the Atom specification. (Roughly, the "term" is the internal string used by the software to identify the category, while the "label" is the human-readable string presented to a user in a user interface.)
  • To exclude entries that match a given category, use the form /-categoryname/.
  • To query for a category that has a scheme—such as <category scheme="urn:google.com" term="public"/>—you must place the scheme in curly braces before the category name. For example: /{urn:google.com}public. If the scheme contains a slash character (/) it should be URL-encoded as %2F. To match a category that has no scheme, use an empty pair of curly braces. If you don't specify curly braces, then categories in any scheme will match.
  • The above features can be combined. For example: /A%7C-{urn:google.com}B/-C means (A OR (NOT B)) AND (NOT C).
entryID ID of a specific entry to be retrieved
  • If you specify an entry ID, you can't specify any other parameters.
  • The form of the entry ID is determined by the service.
  • Unlike most of the other query parameters, entry ID is specified as part of the URI, not as a name=value pair.
  • Example: http://www.example.com/feeds/jo/entry1.
fields Response filter
  • Returns only the requested fields, rather than the full resource representation. For example:
    http://www.example.com/feeds?fields=link,entry(@gd:etag,id,updated,link[@rel='edit']))
    When it receives this request, the server returns a response that contains only only link and entry elements for the feed. In addition, the entry elements returned are partial entries that contain only ETag, ID, updated, and edit link relations.
  • The fields value must be URL encoded, as with all query parameter values.
  • For more information, see the Partial response section.
  • This parameter is currently an experimental feature.
max-results Maximum number of results to be retrieved For any service that has a default max-results value (to limit default feed size), you can specify a very large number if you want to receive the entire feed.
prettyprint Returns an XML response with identations and line breaks
  • If prettyprint=true, the XML returned by the server will be human readable (pretty printed).
  • Default: prettyprint=false
published-min, published-max Bounds on the entry publication date
  • Use the RFC 3339 timestamp format. For example: 2005-08-09T10:57:00-08:00.
  • The lower bound is inclusive, whereas the upper bound is exclusive.
q Full-text query string
  • When creating a query, list search terms separated by spaces, in the form q=term1 term2 term3. (As with all of the query parameter values, the spaces must be URL encoded.) The service returns all entries that match all of the search terms (like using AND between terms). Like Google's web search, a service searches on complete words (and related words with the same stem), not substrings.
  • To search for an exact phrase, enclose the phrase in quotation marks: q="exact phrase".
  • To exclude entries that match a given term, use the form q=-term.
  • The search is case-insensitive.
  • Example: to search for all entries that contain the exact phrase "Elizabeth Bennet" and the word "Darcy" but don't contain the word "Austen", use the following query: ?q="Elizabeth Bennet" Darcy -Austen
start-index 1-based index of the first result to be retrieved
  • Note that this isn't a general cursoring mechanism. If you first send a query with ?start-index=1&max-results=10 and then send another query with ?start-index=11&max-results=10, the service cannot guarantee that the results are equivalent to ?start-index=1&max-results=20, because insertions and deletions could have taken place in between the two queries.
strict Strict query parameter checking
  • Set strict=true to verify that each of your query parameters are recognized by the service. An error will be returned if a parameter is not recognized.
  • Default: strict=false
updated-min, updated-max Bounds on the entry update date
  • Use the RFC 3339 timestamp format. For example: 2005-08-09T10:57:00-08:00.
  • The lower bound is inclusive, whereas the upper bound is exclusive.
  • In some cases (such as when using v2.1 or newer of the Calendar Data API), specifying an updated-min that is too far in the past will cause an HTTP 410 (Gone) status to be returned.

About category queries

We decided to provide a slightly unusual format for category queries. Instead of requiring a query like the following:

http://example.com/jo?category=Fritz&category=2006

we made it possible to use:

http://example.com/jo/-/Fritz/2006

This approach identifies a resource without using query parameters, and it produces cleaner URIs. We chose this approach for categories because we think that category queries will be among the most common queries.

The drawback to this approach is that we require you to use /-/ in this type of category queries, so that services can distinguish category queries from other resource URIs, such as http://example.com/jo/MyPost/comments.

Query responses

Queries return an Atom feed, an Atom entry, or an RSS feed, depending on the request parameters.

Query results contain the following OpenSearch elements directly under the <feed> element or the <channel> element (depending on whether results are Atom or RSS):

openSearch:totalResults
The total number of search results for the query (not necessarily all present in the results feed).
openSearch:startIndex
The 1-based index of the first result.
openSearch:itemsPerPage
The maximum number of items that appear on one page. This allows clients to generate direct links to any set of subsequent pages. However, for a possible pitfall in using this number, see the note regarding start-index in the table in the Query requests section.

The Atom response feed and entries may also include any of the following Atom and Data API elements (as well as others listed in the Atom specification):

<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="..."/>
Specifies the URI where the complete Atom feed can be retrieved.
<link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="..."/>
Specifies the Atom feed's PostURI (where new entries can be posted).
<link rel="self" type="..." href="..."/>
Contains the URI of this resource. The value of the type attribute depends on the requested format. If no data changes in the interim, sending another GET to this URI returns the same response.
<link rel="previous" type="application/atom+xml" href="..."/>
Specifies the URI of the previous chunk of this query result set, if it is chunked.
<link rel="next" type="application/atom+xml" href="..."/>
Specifies the URI of the next chunk of this query result set, if it is chunked.
<link rel="edit" type="application/atom+xml" href="..."/>
Specifies the Atom entry's EditURI (where you send an updated entry).

Here's a sample response body, in response to a search query:

<?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:gd='http://schemas.google.com/g/2005'
        gd:etag='W/"C0QBRXcycSp7ImA9WxRVFUk."'>
  <id>http://www.example.com/feed/1234.1/posts/full</id>
  <updated>2005-09-16T00:42:06Z</updated>
  <title type="text">Books and Romance with Jo and Liz</title>
  <link rel="alternate" type="text/html" href="http://www.example.net/"/>
  <link rel="http://schemas.google.com/g/2005#feed"
    type="application/atom+xml"
    href="http://www.example.com/feed/1234.1/posts/full"/>
  <link rel="http://schemas.google.com/g/2005#post"
    type="application/atom+xml"
    href="http://www.example.com/feed/1234.1/posts/full"/>
  <link rel="self" type="application/atom+xml"
    href="http://www.example.com/feed/1234.1/posts/full"/>
  <author>
    <name>Elizabeth Bennet</name>
    <email>liz@gmail.com</email>
  </author>
  <generator version="1.0"
    uri="http://www.example.com">Example Generator Engine</generator>
  <openSearch:totalResults>2</openSearch:totalResults>
  <openSearch:startIndex>0</openSearch:startIndex>
  <entry gd:etag='W/"C0QBRXcycSp7ImA9WxRVGUo."'>
    <id>http://www.example.com/feed/1234.1/posts/full/4521614025009481151</id>
    <published>2005-01-09T08:00:00Z</published>
    <updated>2005-01-09T08:00:00Z</updated>
    <category scheme="http://www.example.com/type" term="blog.post"/>
    <title type="text">This is the title of entry 1009</title>
    <content type="xhtml">
      <div
        xmlns="http://www.w3.org/1999/xhtml">This is the entry body of entry 1009</div>
    </content>
    <link rel="alternate" type="text/html"
      href="http://www.example.com/posturl"/>
    <link rel="edit" type="application/atom+xml"
      href="http://www.example.com/feed/1234.1/posts/full/4521614025009481151"/>
    <author>
      <name>Elizabeth Bennet</name>
      <email>liz@gmail.com</email>
    </author>
  </entry>
  <entry gd:etag='W/"C0QBRXrurSp7ImA9WxRVGUo."'>
    <id>http://www.example.com/feed/1234.1/posts/full/3067545004648931569</id>
    <published>2005-01-07T08:00:00Z</published>
    <updated>2005-01-07T08:02:00Z</updated>
    <category scheme="http://www.example.com/type" term="blog.post"/>
    <title type="text">This is the title of entry 1007</title>
    <content type="xhtml">
      <div
        xmlns="http://www.w3.org/1999/xhtml">This is the entry body of entry 1007</div>
    </content>
    <link rel="alternate" type="text/html"
      href="http://www.example.com/posturl"/>
    <link rel="edit" type="application/atom+xml"
      href="http://www.example.com/feed/1234.1/posts/full/3067545004648931569"/>
    <author>
      <name>Elizabeth Bennet</name>
      <email>liz@gmail.com</email>
    </author>
  </entry>
</feed>

If the requested feed is in the Atom format, if no query parameters are specified, and if the result doesn't contain all the entries, the following element is inserted into the top-level feed: <link rel="next" type="application/atom+xml" href="..."/>. It points to a feed containing the next set of entries. Subsequent sets contain a corresponding <link rel="previous" type="application/atom+xml" href="..."/> element. By following all the next links, a client can retrieve all entries from a feed.

HTTP status codes

The following table describes what various HTTP status codes mean in the context of the Data APIs.

Code Explanation
200 OK No error.
201 CREATED Creation of a resource was successful.
304 NOT MODIFIED The resource hasn't changed since the time specified in the request's If-Modified-Since header.
400 BAD REQUEST Invalid request URI or header, or unsupported nonstandard parameter.
401 UNAUTHORIZED Authorization required.
403 FORBIDDEN Unsupported standard parameter, or authentication or authorization failed.
404 NOT FOUND Resource (such as a feed or entry) not found.
409 CONFLICT Specified version number doesn't match resource's latest version number.
410 GONE Requested change history is no longer available on the server. Refer to service-specific documentation for more details.
500 INTERNAL SERVER ERROR Internal error. This is the default code that is used for all unrecognized server errors.

Resource versioning (ETags)

Sometimes you need to be able to refer to a specific version of a particular entry.

This is important in two cases in particular:

  • Doing a "conditional retrieval," in which your client requests an entry, and the server sends the entry only if it has changed since the last time the client requested it.
  • Ensuring that multiple clients don't inadvertently overwrite one another's changes. The Data APIs do this by making updates and deletes fail if the client specifies an old version identifier for the entry.

The Google Data APIs handle both of these cases using ETags, a standard part of HTTP.

An ETag is an identifier that specifies a particular version of a particular entry. The server attaches an ETag to entry and feed elements that it sends to clients. When an entry or feed changes, its ETag changes as well.

The Google Data APIs provide ETags in two places: in an ETag HTTP header, and in a gd:etag attribute of <feed> and <entry> elements.

In the Google Data APIs, an ETag is usually a string of letters and numbers, sometimes also including hyphens and periods; the string is usually enclosed in quotation marks. (The quotation marks are part of the ETag.) For example, here's an ETag from a Data API entry: "S0wCTlpIIip7ImA0X0QI".

There are two kinds of ETags: strong and weak. Strong ETags identify a specific version of a specific entry, and can be used to avoid overwriting other clients' changes. Weak ETags, in the context of the Google Data APIs, are used only for conditional retrieval. A weak ETag always starts with W/. For example: W/"D08FQn8-eil7ImA9WxZbFEw."

Not all Google Data APIs support strong ETags. For those that do, the strong ETags are used only for entries; ETags on feeds are always weak.

Here's an example of a feed (including some of the HTTP headers) retrieved from a service that supports strong ETags:

GData-Version: 2.0
ETag: W/"C0QBRXcycSp7ImA9WxRVFUk."
...
<?xml version='1.0' encoding='utf-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'
    gd:etag='W/"C0QBRXcycSp7ImA9WxRVFUk."'>
  ...
  <entry gd:etag='"CUUEQX47eCp7ImA9WxRVEkQ."'>
    ...
  </entry>
</feed>

The client libraries that support version 2 of the Data APIs handle ETags for you, transparently. The following information is for clients that don't use client libraries, and for readers interested in how versioning is handled at the protocol level.

Note: For information about the resource-versioning system used in version 1.0 of the Data APIs, see 1.0 reference guide.

Conditional retrieval

If you want to retrieve an entry that you've retrieved before, you can improve efficiency by telling the server to send the entry 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 entry's ETag.

Here's an example of an If-None-Match header:

If-None-Match: W/"D08FQn8-eil7ImA9WxZbFEw."

When the server receives this request, it checks to see whether the entry that you requested has the same ETag as the ETag you specified. If the ETags match, then the entry hasn't changed, and the server returns an HTTP 304 Not Modified status code.

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

Updating entries

The easiest way to avoid overwriting another client's changes is for the server to make sure that when your client sends an updated entry, the version of the entry that your client started with is the same as the current version stored by the server. If a second client makes an update before your client does, then your client's update is denied, because your client is no longer basing its modifications on the latest version.

When your client retrieves data from a service that supports strong ETags, each entry has an ETag that acts as a unique version identifier for that version of that entry.

Note: Updating using ETags works only with strong ETags. For services that supply weak ETags, all updates succeed, regardless of whether someone else has updated the entry since you retrieved it; the newest update always overwrites any other prior updates. So don't send weak ETags when updating or deleting; you'll get an error message if you do.

So when your client sends an update to a strong-ETags service, it needs to specify what version of the entry it's updating. There are two ways to do that:

  • Use an If-Match HTTP header.
  • Use the gd:etag attribute in the <atom:entry> element.

We recommend the If-Match approach where possible.

To update an entry using If-Match, start by acquiring the entry you're updating. Make any desired changes to the entry, then create a new PUT request containing the modified entry. (For details of URLs to use, see service-specific documentation.)

Before sending the PUT, add an HTTP If-Match header containing the ETag from the original entry:

If-Match: "S0wCTlpIIip7ImA0X0QI"

Then send the PUT request.

If the update succeeds, then the server returns an HTTP 200 OK status code, and a copy of the updated entry.

If the update fails because the ETag you specified doesn't match the current ETag on the entry (which implies that the entry has changed on the server since you last retrieved it), then the server returns an HTTP 412 Precondition Failed status code.

If you can't easily write HTTP headers, or have some other reason to avoid using the If-Match header, then you can use the gd:etag attribute instead.

If you don't send an If-Match header, then the server uses the updated entry's gd:etag attribute value as an implied If-Match value.

To override the versioning system and update the entry regardless of whether someone else has updated it since you retrieved it, use If-Match: * instead of specifying the ETag in the header.

For information about which services support strong ETags, see the Migration Guide.

Deleting entries

Deleting entries that use strong ETags works much like updating them.

To delete an entry that has a strong ETag, first you retrieve the entry you want to delete, then you send a DELETE request to the entry's edit URL.

If you want to make sure that you don't delete an entry that has been changed by another client since you retrieved it, then include an HTTP If-Match header that contains the original entry's ETag value.

If you want to override the versioning system and delete the entry regardless of whether someone else has updated it since you retrieved it, use If-Match: * instead of specifying the ETag in the header.

If an entry does not have a strong ETag, then a DELETE request always succeeds.

Partial response (Experimental)

By default, the server sends back the full representation of the target resource after processing requests. Partial response lets you request only the elements or attributes of interest, instead of the full resource representation. This lets your client application avoid transferring, parsing, and storing unneeded fields, so it can use network, CPU, and memory resources more efficiently.

To find out if partial response is available for the product you are using, see its API documentation.

To request a partial response, use the fields query parameter to specify the elements or attributes you want returned. Here's an example:

http://www.example.com/feeds?fields=link,entry(@gd:etag,id,updated,link[@rel='edit']))

The server's response contains only only link and entry elements for the feed; the entry elements contain only ETag, ID, updated, and edit link information. The fields query parameter syntax is covered in the following sections. For more details about the response, see Handling partial responses.

Note: You can use the fields query parameter with any request that returns data. In addition to GET, this includes POST, and PUT (as well as PATCH, which is used for making partial updates). However, the fields query parameter only affects the response data; it does not affect the data that you must provide or which fields are updated or created.

Fields parameter syntax summary

The format of the fields query parameter value is based on XPath syntax; however, it supports only a subset of valid XPath expressions. The supported syntax is summarized below, and additional examples are provided in the following section.

  • Use a comma-separated list to select several fields.
  • Use a/b to select an element b that is nested within element a; use a/b/c to select an element c nested within b.
  • Use '@' prefix to identify an attribute with the given name; omit the '@' prefix to refer to an element.
  • Apply field conditions to select elements that match certain criteria, by placing expressions in brackets "[ ]" after the element you want to restrict.

    For example, fields=entry[author/name='Elizabeth'] returns only feed entries for which Elizabeth is the author.

  • Specify field sub-selectors to request only specific attributes or sub-elements, by placing expressions in parentheses "( )" after any selected element.

    For example, fields=entry(id,author/email) returns only the ID and the author's email for each feed entry.

  • You can delimit strings using either double or single quotes.

    To escape a double or single quote, repeat the quote. For example, """Hello,"" he said" produces the string "Hello," he said, and '''Hello,'' he said' produces the string 'Hello,' he said.
  • You can use wildcards in field selections.

    For example, entry/gd:* selects all child elements of entry in the gd namespace, and entry/@gd:* selects child element attributes in the same namespace.

The fields query parameter acts as an output filter. This means that the partial response is computed only after processing the rest of the query. For example, if you also specify a max-results query parameter to indicate that you want 20 results per page, then the first 20 results are generated and the partial response is computed from that. If the fields specification doesn't match any of the first 20 entries selected by the query, then you get back an empty feed; you do not get back the first 20 matching entries.

Note: Do not attempt to use field conditions as query selectors. That is, do not attempt to retrieve a full feed and apply field conditions to filter out items of interest from a very large data set. Whenever possible, use other query parameters, such as start-index and max-results, to reduce the results of each query to a manageable size. Otherwise, the performance gains possible with partial response could be outweighed by the serious performance degradation caused by improper use.

Formatting the fields parameter value

The following guidelines explain how to construct the fields query parameter value. Each guideline includes examples and provides descriptions of how the parameter value affects the response.

Note: As with all query parameter values, the fields parameter value must be URL encoded. For better readability, the examples below omit the encoding.

Identify the fields you want returned, or make field selections.
The fields query parameter value is a comma-separated list of elements or attributes (collectively called fields), and each field is specified relative to the root element of the resource representation. Thus, if you are retrieving a feed, fields are specified relative to the <feed> element, and if you are retrieving a single entry, fields are specified relative to the <entry> element. If the element you select is (or is part of) a repeating element in the feed, the service returns all instances of that element.

Here are some feed-level examples:
Examples Effect
entry Returns all <entry> elements and all sub-elements of those entries, but not any other child elements of <feed>.
id,entry Returns both the feed <id> and all <entry> elements.
entry/title Returns the <title> element for all feed entries.

Whenever a nested element is returned, the response includes enclosing tags for any parent elements. The parent tags do not include any other child elements or attributes unless they are also selected explicitly.
entry/author/uri Returns only the <uri> sub-element of the <author> element for all feed entries.
entry/*:rating Returns only sub-elements with local name rating in any namespace for all feed entries.

Here are some entry-level examples:
Examples Effect
author Returns the <author> child element of the target entry.
@gd:etag Returns the etag attribute of the target entry.
author/uri Returns the <uri> sub-element of the <author> element for the target entry.
media:group/media:* Returns all sub-fields of <media:group> in the media namespace for the target entry.
Restrict the response to selected fields that match certain criteria, or use field conditions.
By default, if your request specifies an element that occurs more than once, the partial response will include all instances of that element. However, you can also specify that the response should only include elements that have a particular attribute value or elements that fulfill some other condition using "[ ]" syntax, as shown in the examples below. See the field condition syntax section for more details.
Examples Effect
entry[link/@rel='edit'] Returns any feed entries that contain a <link> element with a rel attribute value of 'edit'.
entry/title[text()='Today'] Returns any <title> elements that occur in feed entries if their content is 'Today'.
entry/author[name='Jo'] Returns any <author> elements that occur in feed entries if they have a <name> sub-element with content 'Jo'.
author[name='Jo'] Returns the <author> element in the target entry if it has a <name> sub-element with content 'Jo'.
Request only parts of the selected elements, or use field sub-selections.
By default, if your request specifies particular elements, the service returns the elements in their entirety. You can specify that the response should include only certain sub-elements within the selected elements. You do this using "( )" sub-selection syntax, as in the examples below.
Examples Effect
entry/author(uri) Returns only the <uri> sub-element for authors in feed entries.
entry/author[name='Jo'](uri) Returns only the <uri> sub-element of <author> for any entries that have an author name of 'Jo'.
entry(link(@rel,@href)) Returns only the values of the rel and href attributes for each <link> element in feed entries.
entry(title,link[@rel='edit']) Returns only <title> and <link> elements with edit rel attributes for each feed entry.
entry(title,author(uri) Returns both <title> elements and author <uri> elements for each feed entry.

More about field condition syntax

You can use field conditions with fields or sub-fields. The condition must evaluate to true for the selected field to be included in the results.  If there is no field condition, then all fields of the selected type are included.

The text value of the selected field is used for comparisons. In this context, if the field is an element, the text value is its contents; if the field is an attribute, the text value is the attribute's value. If the field has no text value, then the comparison fails and the field is not included in the results.

The following table shows the XPath operators that are supported for field conditions and provides some examples.

Operator Syntax Examples
String comparison

= or eq
!= or ne

  • Returns entire entry if it contains a <link> element with an attribute rel set to 'self':
        entry[link/@rel='self']

  • Returns entire entry if it contains a <title> element with content equal to the string 'unknown':
        entry[title eq 'unknown']

  • Returns entire <title> element if its content is not 'unknown':
        title[text() != 'unknown']
Logical comparison and
or
not
  • Returns any link that has an attribute rel set to 'self' or 'edit':
        link[@rel='self' or @rel='edit']

  • Returns any link that has an attribute rel set to 'self' and an attribute type set to 'application/atom+xml':
        link[@rel='self' and @type='application/atom+xml']

  • Returns any link that does not have an attribute rel with value 'self':
        link[not(@rel='self')]

    Note that, as in XPath, not looks like a function call.
Numerical comparison = or eq
!= or ne
> or gt
>= or ge
< or lt
<= or le
  • Returns any <gd:rating> element with a value attribute that can be transformed into the integer 5:
        gd:rating[@value=5]

  • Returns any <gd:rating> element with an average attribute that can be transformed into a float that is bigger than 4.3 :
        gd:rating[@average gt 4.3]
Date comparison Use numerical comparison operators, as shown in examples.

To do date or date/time comparisons, you can cast elements, attributes, or string literals into xs:date or xs:dateTime. For xs:dateTime, the default timezone is UTC, but it is best to specify a timezone explicitly.

  • Returns any <yt:recorded> element that contains a date since Jan. 1, 2005:
        yt:recorded[xs:date(text())>=xs:date('2005-01-01')]

  • Returns any entries that were updated after the time given, specified in the UTC timezone:
        entry[xs:dateTime(updated)>xs:dateTime('2008-07-25T08:19:37.549Z')]
Existence

Use name of element or attribute as shown in examples.

  • Returns any entries that contain a link with an attribute rel:
        entry[link/@rel]

  • Returns any <gd:rating> elements that have an attribute called value:
        entry/gd:rating[@value]
Boolean true()
false()

Booleans can be useful during testing to force field conditions into a true or false state.

  • Returns any <link> elements:
        link[true()]

Handling partial responses

After a server that supports partial response processes a valid request that includes the fields query parameter, it sends back an HTTP 200 OK status code along with the requested attributes or elements. If the fields query parameter has an error or is otherwise invalid, the server returns an HTTP 400 Bad Request status code.

The root element of the response is either <feed> or <entry>, depending on the target URI. The root element's content includes only the selected fields for that feed or entry, along with the enclosing tags for any parent elements.

The value of the the request's fields query parameter can be echoed back in two ways:

  • The root element has a gd:fields attribute that shows value of the fields query parameter specified in the request.
  • If the target URI is a feed, each editable entry has a gd:fields attribute that shows the portion of the fields selection that applies to it.

Note: In order to see these gd:fields attribute values in your partial response, you must include them in your fields query parameter specification. You can do this explicitly, using @gd:fields, or using the more general @gd:*, which also includes ETag information.

The following example query asks the server to return a document that contains only attributes in the gd namespace (at both the feed and entry level), as well as the feed ID, the title, and the edit link for each feed entry:

http://example.com/myFeed?fields=@gd:*,id,entry(@gd:*,title,link[@rel='edit'])

The server returns the following partial response, along with a 200 Successful HTTP status code:

<?xml version='1.0' encoding='utf-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'
    gd:etag='W/"DEAEQH47eCp7IWA9WxBVGUo."'
    gd:fields='@gd:*,id,entry(@gd:*,title,link[@rel='edit'])>
  <id>http://example.com/myFeed</id>
  <entry gd:etag='"EksPTg1Bfyp7IWA6WhJT"'
      gd:fields="@gd:*,title,link[@rel='edit']">
    <link rel='edit' href='http://example.com/myFeed/1/'/>
    <title>This year</title>
  </entry>
  <entry gd:etag='"EksPQA1Cdyp7IWA6WhJT"'
      gd:fields="@gd:*,title,link[@rel='edit']">
    <link rel='edit' href='http://example.com/myFeed/2/'/>
    <title>Last year</title>
  </entry>
  <entry d:etag='"EksPQAxHeCp7IWA6WhJT"'
      gd:fields="@gd:*,title,link[@rel='edit']">
    <link rel='edit' href='http://example.com/myFeed/3/'/>
    <title>Today</title>
  </entry>
</feed>

If the selected fields do not match anything, the service still returns a 200 Successful HTTP status code, but the partial response is an empty feed:

<?xml version='1.0' encoding='utf-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'
  xmlns:gd='http://schemas.google.com/g/2005'
  gd:etag='W/"DEAEQH47eCp7IWA9WxBVGUo."'
  gd:fields='@gd:*,id,entry(@gd:*,title,link[@rel='edit'])>
</feed>

Partial update (Experimental)

Google products that support partial response and editable resources also allow you to use partial update. With partial update, you send only the fields you want to update, rather sending a modified version of the full resource representation. This lets your client application be more efficient when making updates, as well as when using partial response to retrieve data.

Instead of using PUT, however, you must use a PATCH request when making a partial update. The semantics for PATCH are powerful enough to let you add, replace, and delete specific fields for a particular entry, all with a single request.

To find out if partial update is available for the product you are using, refer to the product-specific documentation.

Submitting a partial update request

To submit a partial update request, you send an HTTP PATCH request to the same URL that you would normally use with PUT to update the resource. The body of the PATCH request is a partial <entry> element that specifies the fields you want to add or modify. The entry's gd:fields attribute indicates the fields you want to delete.

The server processes PATCH requests in a specific order:

  1. It first removes from the resource representation the fields specified by the gd:fields attribute.

    The syntax for the gd:fields attribute is the same as for the fields query parameter used when requesting a partial response. See Supported syntax for more details.

  2. It then merges into the existing resource representation the data provided in the body of the request.

    More details on how the data is merged are provided in Adding or updating fields below.

Note: Since the body of a PATCH request is not typically compliant with the Atom Syndication Format, the Content-Type you use with a PATCH request is application/xml.

Here is an example of a partial update request:

PATCH /myFeed/1/1/
Content-Type: application/xml

<entry xmlns='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'
    gd:fields='description'>
  <title>New title</title>
</entry>

This PATCH request makes the following changes to the resource representation stored on the server for the target URI's entry:

  • Removes the <description> element.
  • Updates the <title> element.

Semantics of a partial update request

The instructions below explain how to set up your PATCH request to delete, add, or update specific fields within an entry. A single PATCH request can perform any combination of these operations.

  • Deleting fields. Use the <entry> element's gd:fields attribute to identify any fields you want deleted from the resource. The following sample request deletes the title and summary associated with an entry. However the request does not add or update any other data for the entry.

    PATCH /myfeed/1/1/
    Content-Type: application/xml
    
    <entry xmlns='http://www.w3.org/2005/Atom'
        xmlns:gd='http://schemas.google.com/g/2005'
        gd:fields='title,summary'/>
    
  • Adding or updating fields. Use the body of the <entry> element to specify the data that you want to add or update for a resource. These fields are merged into the existing data for the resource, after any deletions are made, according to the following rules:

    • Fields not already present are added. If the resource data does not already specify a value for a field, then the field is added to the existing data. For example, if an entry does not have a title, and your PATCH request contains a <title> element, then the new title is added to the entry.

    • Fields already present are replaced or appended. The specific behavior for merging fields that are already specified in the resource data depends on the characteristics of the field:

      • Non-repeating fields are replaced. If the resource data already specifies a value for a non-repeating element, then the value you specify in the PATCH request replaces the existing value for that element. For example, in the example below, the new title replaces the existing title.

        PATCH /myFeed/1/1/
        Content-Type: application/xml
        
          <entry xmlns='http://www.w3.org/2005/Atom'
            xmlns:gd='http://schemas.google.com/g/2005'>
          <title>New Title</title>
        </entry>

        A more complex example is given below. For this example, assume that the entry can have only one author, and that the target resource already has values for the author's name and email address. Even though <author> element has two child fields, only the <name> element is present in the data provided. As a result, only that field's value is overwritten. The value of the <email> element, which is missing from the data provided, remains unchanged.

        PATCH /myfeed/1/1/
        Content-Type: application/xml
        
        <entry xmlns='http://www.w3.org/2005/Atom'
            xmlns:gd='http://schemas.google.com/g/2005'>
          <author>
            <name>New Name</name>
          </author>
        </entry>
      • Repeating fields are appended. If the resource data already specifies a value for a repeating element, then the new element you provide is added to the existing set of values.

        Note that there might be times when you want to do something other than add a new instance of a repeating element. For example, you might want to do one of the following:

        • Replace an entire list of repeating elements. You can delete all the repeating fields using the gd:fields attribute (gd:fields='ns:accessControl', for example) and provide a complete set of the replacement fields. Since all the existing elements are deleted first, the set of fields you provide do not conflict with any existing values when they are appended.

        • Replace one value in a set of existing values for a repeating element. In this case, simply remove the single element by defining the gd:fields value narrowly enough to avoid deleting other values that you want to keep. For example, to remove only an access control with an action of embed, you might use gd:fields='ns:accessControl[@action="embed"]'. Then you provide the single field that you want to replace it with in the body of the <entry> element:

          PATCH /myfeed/1/1/
          Content-Type: application/xml
          
          <entry xmlns='http://www.w3.org/2005/Atom'
              xmlns:gd='http://schemas.google.com/g/2005'
              gd:fields='ns:accessControl[@action="embed"]>
            <ns:accessControl action="embed" permission="allowed" />
          </entry>

Handling the response to a partial update

After processing a valid partial update request, the API returns a 200 OK HTTP response code. By default, the body of the response is the complete entry that you updated. The server updates ETag values when it successfully processes a PATCH request, just as it does with PUT.

If a PATCH request results in a new resource state that is syntactically or semantically invalid, the server returns an HTTP 400 Bad Request or 422 Unprocessable Entity HTTP status code, and the resource state remains unchanged. For example, if you attempt to delete a required field and do not provide a replacement, the server returns an error.

Note: It is important to understand how different fields relate to each other. It might be possible to put a resource into an inconsistent state by updating only part of mutually interdependent values. For example, it might be possible to update a start time to a later value than an end time. Although the API should return an error code, we recommend that you fully test these kinds of conditions to ensure consistency.

Alternate notation when PATCH is not supported

If your firewall does not allow PATCH, then do an HTTP POST request and set the override header to PATCH, as shown below:

POST /myfeed/1/1/
X-HTTP-Method-Override: PATCH
Content-Type: application/xml
...

Using partial response with partial update

You can use a partial response as the basis of a subsequent partial update request. If you do this, specify a fields query parameter that includes edit links, as well as @gd:*. This ensures that the partial response includes information like the ETag and gd:fields attribute values, which are important for subsequent requests.

Here is an example that returns a partial response that you could use as the basis for a future partial update:

http://example.com/myFeed/1/1/?fields=@gd:*,link[@rel='edit'](@href),gd:who

The server responds:

<?xml version='1.0' encoding='utf-8'?>
<entry xmlns='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'
    gd:etag='"E0UKRAREeCp7IWA6WhJT"'
    gd:fields="@gd;*,link[@rel='edit'](@href),gd:who">
  <link href='http://example.com/myFeed/1/1/'/>
  <gd:who email='liz@gmail.com'/>
  <gd:who email='jo@gmail.com'/>
  <gd:who email='jane@gmail.com'/>
</entry>

Suppose that you want to remove the user with email 'jane@gmail.com', add a user with email 'will@gmail.com', and change the email for the user currently listed as 'jo@gmail.com' to 'josy@gmail.com'.

You can make these changes simply by starting with the results of the previous response, modifying only the fields that are different, and submitting the modified partial entry as the body of the PATCH request. For this example, the needed modifications are:

  • Delete <gd:who email='jane'/> from the list of elements provided.
  • Add <gd:who email='will@gmail.com'/> to the list of elements provided.
  • Replace <gd:who email='jo@gmail.com'/>with <gd:who email='josy@gmail.com'/>.

The PATCH request based on the pevious partial response is shown below:

PATCH /myFeed/1/1/
Content-Type: application/xml

<entry gd:fields="@gd:*,link[@rel='edit'](@href),gd:who"
    gd:etag="FE8LQQJJeSp7IWA6WhVa">
  <link href='http://example.com/myFeed/1/1'/>
  <gd:who email='liz@gmail.com'/>
  <gd:who email='josy@gmail.com'/>
  <gd:who email='will@gmail.com'/>
</entry>

Note: This approach relies on the gd:fields and gd:etag (if supported) attributes being included in the partial response for the entry. The body of the partial entry must retain all fields and attribute that were present in the partial response — except for those you explicitly want to remove. You can update any of the existing fields in the body with new values, and you can include any new fields you want to add.

Authentication

When a client tries to access a service, it may need to provide the user's credentials to the service, to demonstrate that the user has the authority to perform the action in question.

The approach that a client should use for authentication depends on the type of client:

In the ClientLogin system, the desktop client asks the user for their credentials, and then sends those credentials to the Google authentication system.

If authentication succeeds, then the authentication system returns a token that the client subsequently uses (in an HTTP Authorization header) when it sends Data API requests.

If authentication fails, then the server returns a 403 Forbidden status code, along with a WWW-Authenticate header containing a challenge applicable to the authentication.

The AuthSub system works similarly, except that instead of asking the user for their credentials, it connects the user to a Google service that requests credentials. The service then returns a token that the web application can use; the advantage of this approach is that Google (rather than the web front end) securely handles and stores the user's credentials.

For details about these authentication systems, see the Google Data APIs Authentication Overview or the Google Account Authentication documentation.

Session state

Many business logic implementations require session stickiness—keeping track of the state of a user's session.

Google tracks session state in two ways: using cookies, and using a token that can be sent as a query parameter. Both methods achieve the same effect. We recommend that clients support one of these session-state tracking methods (either one is sufficient). If a client doesn't support either of these methods, then that client will still work with Data APIs, but performance may suffer compared to clients that do support these methods. Specifically, if a client doesn't support these methods, then every request results in a redirect, and therefore every request (and any associated data) is sent to the server twice, which affects the performance of both the client and the server.

The Google client libraries handle session state for you, so if you use our libraries, you don't have to do anything to get session state support.

Additional resources

You may find the following third-party documents useful:

Back to top