Skip to content
This repository


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

A thin client for the Pivotal Tracker API

branch: master

Fetching latest commit…


Cannot retrieve the latest commit at this time

Octocat-spinner-32 examples
Octocat-spinner-32 pivotal
Octocat-spinner-32 .gitignore
Octocat-spinner-32 CHANGES.rst
Octocat-spinner-32 LICENSE.txt
Octocat-spinner-32 README.rst


Pivotal-Py is a very thin wrapper built on top of httplib2 to make requests against the Pivotal Tracker API.


Install from PyPI with easy_install or pip:

pip install pivotal-py


Pivotal-Py requires httplib2 0.6.0 or later.


This Pivotal Tracker API client uses the token to authenticate with Pivotal Tracker. You can get a token by going to your user profile and creating an API token.

Once you have an API token making requests against the APIs follows a simple pattern of chainable methods, for example:

import pivotal

pv = pivotal.Pivotal('TOKEN')

# Assuming a base URL of ''

# Perform a GET at /projects and processes content via ElementTree.
etree = pv.projects().get_etree()

# Perform the same GET at /projects but return the response and
# content direct from httplib2.
response, content = pv.projects().get()

Note: As seen above, there are two ways to get the content of a request:

  1. Call get_etree() to return the content as ElementTree object.
  2. Call get() to return the tuple containing both the response and content direct from httplib2.

Any positional arguments get pushed onto the URL:

# Perform a GET at /projects/[id]/stories where [id] is a project ID.
etree = pv.projects(id).stories().get_etree()

Any keyword arguments get mapped to the URL query string and appended at the end of the URL:

# Perform a GET at /projects/[id]/stories and filter stories by those that
# are not started.
etree = pv.projects(id).stories(filter='state:unstarted').get_etree()
# Results in a URL of: /projects/[id]/stories?filter=state%3Aunstarted

Note: POSTs are currently not implemented, but the plan is to implement a post method that takes a body argument which is the body of the POST:

# TODO: POST to /projects to create a new project
etree = pv.projects().post(xml_body)
Something went wrong with that request. Please try again.