API v3


Tracker provides an API that can be used to create, retrieve, update, and delete project, story, and task resources. This interface incorporates several elements of the REST tradition, making access to these actions consistent and intuitive.

In a nutshell: collections are accessed via a URL ending in a plural noun such as '/stories', and to target an individual record, append its numerical id (/stories/85). To tell the API whether you are viewing, updating, or deleting the record, make use of the "HTTP verbs", GET, PUT, and DELETE (respectively). To create a new record, send a POST request to the collection's URL (/stories). The API will respond with an XML document reflecting your changes.

Note: This version of the Tracker API is deprecated, and will be removed on Dec. 31, 2017. Applications using this version will no longer work after this date. Please use the latest API version instead.

Available API Actions

Here are some examples of supported API commands, and the corresponding responses. These examples are shown in the form of 'curl' commands. Curl is a command line utility used to perform HTTP requests, and is available on most Unix systems, but you can use any tool or language which can submit a corresponding HTTP request.

API Logistical Details

This is some information you may need while consuming the API or writing software that does.

Available API Actions

Retrieve User Token

Via Basic Auth

Note: This API action requires SSL. While we recommend basic authentication, it is also possible to send the username and password parameters in a POST request.

  curl -u $USERNAME:$PASSWORD -X GET https://www.pivotaltracker.com/services/v3/tokens/active

  <?xml version="1.0" encoding="UTF-8"?>
    <id type="integer">1</id>


Note: This API action requires SSL. We recommend basic authentication.

   curl -d username=$USERNAME -d password=$PASSWORD -X POST https://www.pivotaltracker.com/services/v3/tokens/active

  <?xml version="1.0" encoding="UTF-8"?>
    <id type="integer">1</id>

The above approach can be used allow a third-party application using the Tracker API to retrieve and store an API token using a username and password entered by a user. However, some security-conscious users may not want to enter their username and password. So, you may also want to allow users the option of entering (pasting) their token directly, in addition to allowing them to enter their username/password to retrieve and store their token. This allows users to disable access via third-party applications by simply regenerating their token, and avoids requiring them enter their username/password (or be concerned that it might have been stored by a third-party app).

Activity Feed

All activity

Allows you to retrieve the recent activity of all your projects.

Activity API accepts the following optional URL parameters to alter the query

  • limit - you can limit the number of activity feed items to a desired number. Note the default value is 10, and there is a upper cap of 100
  • occurred_since_date - allows restricting the activity feed to only those items that occurred after a supplied date (example format: 2009/12/18 21:00:00 UTC)
  • newer_than_version - allows restricting the activity feed to only those items that have a greater than supplied version
  curl -H "X-TrackerToken: $TOKEN" -X GET "http://www.pivotaltracker.com/services/v3/activities?newer_than_version=134"
(show response)

Project activity

Allows you to retrieve the recent activity of a specific project, with an optional limit parameter (Note: the number of entries will be capped at 100).

  curl -H "X-TrackerToken: $TOKEN" -X GET "http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/activities?limit=50"
(show response)

You can also retrieve all activites which have occurred since a given date (but you are still capped at a max limit of 100). Note the date format, which contains URL-escaped spaces:

  curl -H "X-TrackerToken: $TOKEN" -X GET "http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/activities?limit=100&occurred_since_date=2010/3/15%0000:00:00%20PST"
(show response)

If you need to retrieve more than 100 activity entries, you could use Tracker's Activity Web Hook support to collect and store activity entries locally.

Get Projects

Get a single project

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID
(show response)

All my projects

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects
(show response)

Manage Projects

Add a new project

When adding a new project, you can specify the project attributes in the HTTP post body, or as URL parameters. This example shows how to use the curl "-d" option to pass XML in the post body:

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<project><name>Cardassian War Plans</name><iteration_length type=\"integer\">2</iteration_length><point_scale>0,1,3,9,27</point_scale></project>" \
(show response)

If you have multiple accounts, you can specify which account to create the project on by including the account id parameter. You can verify the project was created on the correct account by looking at the account name returned in the response. You can find the account id by going to the account's settings page.

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<project><name>Cardassian War Plans</name><account_id type=\"integer\">123</account_id><iteration_length type=\"integer\">2</iteration_length><no_owner type=\"boolean\">true</no_owner></project>" \
(show response)

When a point_scale value is supplied, it must be a comma/whitespace-delimited list of numbers in ascending order containing no white space. If it exactly matches one of the point-scale sets built into Pivotal Tracker (see the "Point Scale" drop-down box in the Project Settings page of a project you own), then that built-in point scale will be used. If it doesn't match, it will be treated as a "custom" point scale.

Note: By default, the user whose credentials are supplied will be added as a project owner. To leave the project without this owner, supply the no_owner element in the post data. For example:

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<project><name>Cardassian War Plans</name><iteration_length type=\"integer\">2</iteration_length><no_owner type=\"boolean\">true</no_owner></project>" \
(show response)

All memberships

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/memberships
(show response)

Get a single membership

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/memberships/$MEMBERSHIP_ID
(show response)

Add membership

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<membership><role>Member</role><person><name>Jadzia Dax</name><initials>JD</initials><email>jadzia@trill.ufp</email></person></membership>" \
(show response)

Remove membership

  curl -H "X-TrackerToken: $TOKEN" -X DELETE http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/memberships/$MEMBERSHIP_ID
(show response)

Get Iterations

Get stories by iteration. The example below shows how to retrieve all iterations, with stories.

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/iterations
(show response)

In most cases, you'll probably want to work with the done, current, backlog, or current_backlog group of iterations only. Iteration group can be specifying at the end of the URL. The first example below retrieves iterations from current and backlog:

    curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/iterations/current_backlog

This example retrieves only iterations in the backlog:

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/iterations/backlog

Get iterations with limit and offset

Optionally, you can specify offset and limit as parameters (except for current, because there is always only one current iteration). The limit parameter controls the max number of iterations returned, and the offset parameter controls the number of iterations to skip from the beginning of the result. Given the previous example, the example below will only return iteration 2 and iteration 3 from our project:

  curl -H "X-TrackerToken: $TOKEN" -X GET "http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/iterations?offset=1&limit=2"
(show response)

For done iterations, offset should be negative, relative to the most recent done iteration. The following examples retrieves the last 6 done iterations:

  curl -H "X-TrackerToken: $TOKEN" -X GET "http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/iterations/done?offset=-6"

Get iterations via ActiveResource

  require 'rubygems'
  require 'active_resource'

  class Iteration < ActiveResource::Base
    self.site = "http://www.pivotaltracker.com/services/v3/projects/:project_id"
    headers['X-TrackerToken'] = '$TOKEN'

  Iteration.find(:all, :params => {:project_id => $PROJECT_ID, :group => "current"})

Get Stories

Get a single story

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID
(show response)

Get all stories for a project

This command retrieves all stories for a project. Note that for very large projects with hundreds or thousands of stories, you might need to use the curl "-o" option to write directly to a file instead of standard output.

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories
(show response)

A Note on Limits

For performance reasons, the API will return a maximum of 3000 stories per request. This is a temporary limit and should be removed as the API matures. If you encounter this limit, try reducing your result set by using filters.

Get stories by filter

Note that labels or strings with a space must be quoted, and multiple filters must be separated with a space, and everything must be URL-escaped (see the section on HTML Escaping and URL Encoding). So, in this example, the un-URL-escaped filter parameter is 'filter=label:"needs feedback" type:bug'. You can also search on multiple values within the same search term, for example, 'filter=id:1,2,3' will return stories with the id 1, 2 or 3.

Also note that you must specify the 'includedone:true' filter option to include 'Done' stories from previous iterations. 'Done' stories from previous iterations are not included by default.

Please see the FAQ entry on searching for more information on searching and supported filters.

  curl -H "X-TrackerToken: $TOKEN" -X GET \
(show response)

Get stories with pagination

You can paginate through stories by optionally passing a limit and offset.

  curl -H "X-TrackerToken: $TOKEN" -X GET "http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories?limit=10&offset=20"
(show response)

Manage Stories

Add a new story

When adding a new story, you can specify the story attributes in the HTTP post body, or as URL parameters. This example shows how to use the curl "-d" option to pass XML in the post body:

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<story><story_type>feature</story_type><name>Fire torpedoes</name><requested_by>James Kirk</requested_by></story>" \
(show response)

Here is an example of adding a new story with the attributes specified as URL parameters. Notice that there is some special escaping required by curl - you must quote the URL, escape square brackets, and URL-escape spaces (see the section on HTML Escaping and URL Encoding).

  curl -H "X-TrackerToken: $TOKEN" -X POST \
(show response)

Update a story

When updating a story, you can specify the story attributes in the HTTP post body, or as URL parameters. This example shows how to use the curl "-d" option to pass XML in the PUT body:

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-type: application/xml" \
    -d "<story><estimate>2</estimate><labels>tribbles, phaser</labels></story>" \
(show response)

Here is an example of editing a story with the attributes specified as URL parameters. You must set the Content-Length header to zero when using PUT with URL parameters. Notice that there is some special escaping required by curl - you must quote the URL, escape square brackets, and URL-escape spaces (see the section on HTML Escaping and URL Encoding). Also note that you do not have to quote labels with spaces when you are adding them, only when they are used as part of a filter.

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-Length: 0" \
(show response)

Below is an example of moving a story from one project to another by updating the story's project_id attribute to indicate it belongs to the new (destination) project. This example shows an update changing only the project to which the story belongs, but additional attribute changes can be performed simultaneously.

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-type: application/xml" \
    -d "<story><project_id>$DESTINATION_PROJECT_ID</project_id></story>" \
(show response)

To clear, or empty fields, provide the field with no content. The examples below show how to remove all labels using these methods. You must set the Content-Length header to zero when using PUT with URL parameters:

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-Length: 0" \

This is the equivalent POST body command:

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-type: application/xml" \
        -d "<story><labels></labels></story>" \

Add note (comment)

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
      -d "<note><text>new note via API</text></note>" \
(show response)

Delete a story

  curl -H "X-TrackerToken: $TOKEN" -X DELETE http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID
(show response)

Deliver all finished stories

This action allows you to take all finished stories and mark them as delivered. This could be used to automate a demo deploy process. The updated stories are returned as the result.

  curl -H "X-TrackerToken: $TOKEN" -X PUT http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/deliver_all_finished -d ""
(show response)

Move Stories (Change priorities)

This action allows you to move a story before or after another story. The moved story is returned in the response.

  curl -H "X-TrackerToken: $TOKEN" -X POST \
    "http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID/moves?move\[move\]=after&move\[target\]=$TARGET_STORY_ID" -d ""


  curl -H "X-TrackerToken: $TOKEN" -X POST \
    "http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID/moves?move\[move\]=before&move\[target\]=$TARGET_STORY_ID" -d ""
(show response)

Note: When moving stories to and from the icebox or a planned iteration, a story will be placed in the same group as the target story. For example, lets say Story A is at the bottom of the backlog and story B is a the top of the icebox. When moving story C 'after' story A, story C will be placed in the backlog. But when moving story C 'before' story B, it will be placed in the icebox.

Link a story to an external integration tool

To link a story to external tools, for example Lighthouse, you can specify the 'lighthouse_id' attribute in the HTTP post body, or as URL parameters when updating a story.

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-type: application/xml" \
    -d "<story><lighthouse_id>54</lighthouse_id></story>" \
(show response)

If your project has multiple integrations of the same type, you will need to include 'integration_id' to specify which integration to associate with the story. You can find the integrations and integration_ids for a project with a Get Projects API call.

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-type: application/xml" \
    -d "<story><other_id>56</other_id><integration_id>2</integration_id></story>" \
(show response)


Get a single task

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID/tasks/$TASK_ID
(show response)

Get all tasks for a story

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID/tasks
(show response)

Add a task

When adding a task, you can specify the task description in the HTTP post body, or as a URL parameter. This example shows how to use the curl "-d" option to pass XML in the POST body:

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<task><description>clean shields</description></task>" \
(show response)

Here is an example of adding a task with the description specified as a URL parameter. Notice that there is some special escaping required by curl - you must quote the URL, escape square brackets, and URL-escape spaces (see the section on HTML Escaping and URL Encoding).

  curl -H "X-TrackerToken: $TOKEN" -X POST \
(show response)

Update a task

When editing a task, you can specify the attributes in the HTTP post body, or as URL parameters. This example shows how to use the curl "-d" option to pass XML in the PUT body:

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-type: application/xml" \
    -d "<task><description>count shields</description><complete>true</complete></task>" \
(show response)

Here is an example of editing a task with the attributes specified as URL parameters. You must set the Content-Length header to zero when using PUT with URL parameters. Notice that there is some special escaping required by curl - you must quote the URL, escape square brackets, and URL-escape spaces (see the section on HTML Escaping and URL Encoding).

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-Length: 0" \
(show response)

Delete a task

  curl -H "X-TrackerToken: $TOKEN" -X DELETE http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID/tasks/$TASK_ID
(show response)


Import XML Format

Tracker can integrate with external services through its Integrations feature. The Other Integration takes a URL that should return XML describing your remote stories in a way that Tracker can import them. Example XML that might be returned is below:

  <?xml version="1.0" encoding="UTF-8"?>
  <external_stories type="array">
      <name>More power to shields</name>
      <description>Klingons are attacking</description>
      <requested_by>James Kirk</requested_by>
      <created_at type="datetime">2008/12/10 00:00:00 UTC</created_at>
      <estimate type="integer">1</estimate>
      <name>Warp Core Breach</name>
      <description>Plasma Conductors Have Failed</description>
      <created_at type="datetime">2009/12/10 00:00:00 UTC</created_at>
      <estimate type="integer">2</estimate>


Upload an attachment

You can upload an attachment. IMPORTANT NOTE: The value of the "name" field and attribute in the content-disposition header MUST be 'Filedata'. The header entry should look something like this: Content-Disposition: form-data; name="Filedata"; filename="test.txt"

For more info, see http://www.ietf.org/rfc/rfc1867.txt. Here's a curl example:

  curl -H "X-TrackerToken: $TOKEN" -X POST -F Filedata=@/path/to/file http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories/$STORY_ID/attachments
(show response)

Source Control Management Post-Commit Hook Integration

SCM Post-Commit Hook Overview

The Tracker API supports integration with post-commit hooks of Source Control Management (SCM) systems such as Subversion, Git, etc. When a commit is made to the SCM, a trigger can call the Tracker API to add a story comment with the commit ID, author and message. It can also optionally change story state.

SCM Post-Commit Message Syntax

To associate an SCM commit with a specific Tracker story, you must include a special syntax in the commit message to indicate one or more story IDs and (optionally) a state change for the story. Your commit message should have square brackets containing a hash mark followed by the story ID. If a story was not already started (it was in the "not started" state), a commit message will automatically start it. For example, if Scotty uses the following message when committing SCM revision 54321:

  [#12345677 #12345678] Diverting power from warp drive to torpedoes.

...it will result in the following comment being added to Tracker stories 12345677 and 12345678, and the stories will be started if they were not yet started:

  Commit: Scotty

  [#12345677 #12345678] Diverting power from warp drive to torpedoes.

To automatically finish a story by using a commit message, include "fixed", "completed" or "finished" in the square brackets in addition to the story ID. You may also use different cases or forms of these verbs, such as "Fix" or "FIXES", and they may appear before or after the story ID. Note: For features, this will put the story in the 'finished' state. For chores, it will put the story in the 'accepted' state. For example:

  [Fixes #12345678] Torpedoes now sufficiently powered.

In some environments, code that is committed is automatically deployed. For this situation, include "delivers" and the story will be put in the 'delivered' state:

  [Delivers #12345679] Scotty can beam up Captain Kirk.

Generic Curl Example

Here is a simple, generic example of using the curl "-d" option to pass XML in the POST body for triggering a commit hook comment:

  curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<source_commit><message>$MESSAGE</message><author>$AUTHOR</author><commit_id>$REVISION</commit_id><url>$URL</url></source_commit>" \

NOTE: Project activity created by commit hook integration will be attributed to the user whose API Token is passed. We advise creating a separate, dedicated tracker user for this purpose, such as "Subversion", "Git" or "GitHub".

Subversion Example

Here is an example of a Subversion post-commit hook script (don't forget to make it executable with 'chmod a+x'):

  set -e


  AUTHOR=`/usr/bin/svnlook author $REPO -r $REV`
  MESSAGE=`/usr/bin/svnlook log $REPO -r $REV`

  # You must HTML-escape the XML post data
  # This is just a simple example.  You also need to handle the AUTHOR, as well as quotes, backticks, etc...
  # If you have a better one, please let us know, and we'll add it to the list of Tracker 3rd Party Tools
  # at http://www.pivotaltracker.com/integrations.

  RESPONSE=`curl -H "X-TrackerToken: $TOKEN" -X POST -H "Content-type: application/xml" \
    -d "<source_commit><message>$MESSAGE</message><author>$AUTHOR</author><commit_id>$REV</commit_id><url>$URL</url></source_commit>" \
  echo $RESPONSE >> /tmp/tracker_post_commit.log

For more details, see the Subversion Book section on Implementing Repository Hooks.

Git Example

If you are using a Git repository hosted on GitHub, you can easily integrate it with Tracker by Configuring GitHub Post-Receive URLs

If you don't use GitHub to host your git repository, it is possible to write a git post-receive server script, similar to the Subversion Example above, although you'll want to make sure you handle each commit separately. There are various examples of git post commit hooks, including this one. If you do create one for Tracker, and would like to share it, please let us know, and we'll add it to the list of Tracker 3rd Party Tools.

Other SCM Tool Hooks

We welcome the Tracker community to contribute integration support for other Source Control Management systems and tools. If you have created something you would like to share, please let us know at tracker@pivotal.io and we might add it to the list of Tracker Third Party Tools.

GitHub Post-Receive Hooks

GitHub and Pivotal Tracker both support integration between them. Pivotal Tracker can accept the update format used by GitHub Post-Receive Hooks. And GitHub provides direct support for sending to Pivotal Tracker on post-receive.

To configure GitHub's post-receive hook for Pivotal Tracker: Log in to the GitHub web site and go to the repo that you want to integrate with Tracker. Click on the "Admin" link from the repository page, select "Service Hooks" from the options on the left of the Administration page, scroll down the list of pre-defined hooks to "PivotalTracker" and select it. In the form for the Tracker hook (back near the top of the page) enter your Tracker API Token (see above) into the "Token" box, check "Active", and click "Update Settings".

GitHub integration supports all of the same keywords syntax and functionality described above for SCM Post-Commit Message Syntax. The comments created by GitHub integration will also include the URL of the associated commit. For example:

  Commit: Scotty
  [Fixes #12345677 #12345678] Torpedoes now sufficiently powered

API Logistical Details

API Location

The Pivotal Tracker API resides at:


Warning: You must include www. to avoid a redirect.

Access Control

Token-based Authentication

Tracker uses a token mechanism to authenticate API users, and access control to projects and stories is based on the user's project memberships. Every API request must include the "X-TrackerToken". The token may be added a s an HTTP header field or a normal HTTP parameter, for security reasons it is recommended to add it as an HTTP header field. To generate a token, use the "Create New Token" link on your Profile page (accessible via the drop-down menu under your name in the top right corner). To remove an existing token, click the "remove" link next to the token. It's also possible to generate or obtain a user token using the API, by specifying a username and password.

Disabling API Access for a Project

By default, API access is enabled for all projects. Project owners can disable API Access for their projects on the Project Settings page.


It is recommended to send API calls via SSL (Secure Sockets Layer). Sending all API calls via SSL will ensure that all information, including the user's token, is sent encrypted, and not in plain text.


Project ID

Project-specific API calls must provide a project ID. You can find the ID of a project on the Project Settings page.

Story ID

For API calls that are specific to a feature, chore, bug or release, a Story ID must be provided. You can find the Story ID at the bottom of any expanded story.


Some API calls accept a filter parameter. This can be any valid search string which works in the Search box (with the magnifying glass) of a Tracker Project Page. For more details, see the FAQ entry on searching. If you use a multi-word label in a filter, remember that it must be enclosed in double-quotes, and the double-quotes may have to be escaped as well, depending on the language/tool you use to invoke the API. See the examples for more details.

API Token

You must use a token to access the API. A token is a large hexadecimal hash (e.g. 3b6cc1410da3bb4a17ab0ac5aebfa024) and is user-specific. See the Access Control section for more details on tokens.

HTML Escaping and URL Encoding

Tracker supports passing data to the API as XML in the post body, or as URL parameters. You must properly escape your data depending on the method you use - HTML-escaping for XML, and URL-encoding for URL parameters. If you are using the 'curl' command line tool to pass data via URL parameters, it requires some additional special escaping. You must also set the Content-Length header to zero when using PUT with URL parameters.

Here's an example of passing the string '<special & needs escaping>' as XML, which requires HTML-escaping:

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-type: application/xml" \
    -d "<story><labels>&lt;special &amp; needs escaping&gt;</labels></story>" \

Here's an example of passing passing the string '<special & needs encoding>' as a URL parameter, which requires URL-encoding. Notice that there is also some special escaping required by curl - you must quote the URL, and escape square brackets.

  curl -H "X-TrackerToken: $TOKEN" -X PUT -H "Content-Length: 0" \

Warning: You should only pass parameters either by the POST body OR by the query parameters. If you pass parameters using both methods simultaneously, the query parameters will override those in the POST body.

Error Reporting

If there is an error in your API request, the following response will be returned with an non-success HTTP status code:

    <?xml version="1.0" encoding="UTF-8"?>
      <error>The provided requested_by user 'James Kirk' is not a valid member of the project.</error>

(If you are using ActiveResource to access the Pivotal Tracker API, this is the standard format for errors).

Some errors will not return XML as the response content. For example, if you use an invalid token or credentials, a "401 Unauthorized" HTTP status code will be returned, with 'Access Denied.' as the response content. So, ensure that the HTTP status code of the response is "200 OK" or that the response contains XML before trying to parse it as XML.

Return Dates in UTC

By default, all dates are returned in the user's timezone, which can be configured on the Profile page (accessible via the drop-down menu under your name in the top right corner). If you prefer dates to be returned in UTC, add the X-Tracker-Use-UTC header.

  curl -H "X-TrackerToken: $TOKEN" -X GET -H "X-Tracker-Use-UTC: true" \
(show response)

Invoking the API from different clients

The Tracker API can be invoked from any language or tool which can issue the proper HTTP requests. Here are some examples. HTTP Client is a useful application for testing and experimenting.

Curl Command Line

  curl -H "X-TrackerToken: $TOKEN" -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories


  curl -X GET http://www.pivotaltracker.com/services/v3/projects/$PROJECT_ID/stories?token=$TOKEN


  require 'rubygems'
  require 'net/http'
  require 'uri'

  resource_uri = URI.parse("http://www.pivotaltracker.com/services/v3/projects/#{$PROJECT_ID}")
  response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
    http.get(resource_uri.path, {'X-TrackerToken' => '$TOKEN'})

  doc = Nokogiri(response.body).at('project')

  @project = {
    :name             => doc.at('name').innerHTML,
    :iteration_length => doc.at('iteration_length').innerHTML,
    :week_start_day   => doc.at('week_start_day').innerHTML,
    :point_scale      => doc.at('point_scale').innerHTML


  require 'rubygems'
  require 'active_resource'
  class Story < ActiveResource::Base
    self.site = "http://www.pivotaltracker.com/services/v3/projects/:project_id"
    headers['X-TrackerToken'] = '$TOKEN'

  # Create a story
  Story.create(:name => "Warp Speed ", :requested_by => "James Kirk", :description => "do it now", :project_id => $PROJECT_ID)

  # Find stories
  Story.find($STORY_ID, :params => {:project_id => $PROJECT_ID})
  Story.find(:all, :params => {:project_id => $PROJECT_ID})
  Story.find(:all, :params => {:filter => "label:'needs feedback' type:bug", :project_id => $PROJECT_ID})

  # Update a story
  story = Story.find($STORY_ID, :params => {:project_id => $PROJECT_ID})
  story.name = "More speed Scotty"


  import urllib
  import urllib2
  from xml.dom import minidom

  url = "http://www.pivotaltracker.com/services/v3/projects/%s" % $PROJECT_ID

  req = urllib2.Request(url, None, {'X-TrackerToken': '$TOKEN'})
  response = urllib2.urlopen(req)
  dom = minidom.parseString(response.read())

  doc = dom.getElementsByTagName('project')[0]

  project = {
    'name'              : doc.getElementsByTagName('name')[0].firstChild.data,
    'iteration_length'  : doc.getElementsByTagName('iteration_length')[0].firstChild.data,
    'week_start_day'    : doc.getElementsByTagName('week_start_day')[0].firstChild.data,
    'point_scale'       : doc.getElementsByTagName('point_scale')[0].firstChild.data