I’ve been using TeamworkPM as my project management software for the last year. I’ve used Assembla, Basecamp, FogBugz, JIRA, Trac, and many others in the past, but TeamworkPM is my favorite. Why? There are lots of reasons, but I’m not going to write about all of that in this article. Learn more about TeamworkPM here (referral free link).

I received a request from a few co-workers: They wanted their complete task list visible to everyone in the company. Not full details or even links, just an overview of their current workload. The easist solution is to add everyone to their projects or give everyone admin access, but neither of those options are acceptable. So, I finally had an excuse to try out the TeamworkPM API!

I read the documentation and wrote an initial implementation using the TeamworkPM API written by loduis. The class worked well, but the API was requiring one call for each project. I contacted TeamworkPM (They respond quickly!) about how to make it more efficient and they told me of a new currently-undocumented API call: tasks.json. I wish I knew about this yesterday. Haha! Since the TeamworkPM API doesn’t support tasks.json, I rewrote the code using curl. Instead of looping through all projects for tasks assigned to the user, I can simply request all tasks assigned to the user.

This example is written in PHP and requires php5_curl to make the HTTP requests. You’ll need to put it on web server everyone in the organization can access. Add some security if the server is publically accessible. The code makes two HTTP calls, one to get information about the user, and one to get their task list. The response is formatted as a table. I highly recommend John Sardine’s Simple Little Table CSS3 to make the table look much better. Note: This is a simple demostration implementation. It needs additional error checking and caching for heavy use in a larger organization, but is probably fine as-is for a smaller organization.

// Define company/organization TeamworkPM URL.
define('TW_API_URL', 'your-company-api-url-here');
// Define the API Token of the user.
define('TW_API_TOKEN', 'your-api-token-here');

 * Runs a Teamwork GET Action
 * @param string $action
 * @param array $options (optional)
 * @todo Error checking!
 * @return JSON response as an associative array
function TeamworkGet($action, $options = array()) {
  $curl = curl_init();

  // Convert options array into param list.
  $params = empty($options) ? '' : '?' . http_build_query($options);
  // Set curl options
  curl_setopt($curl, CURLOPT_URL, TW_API_URL . $action . '.json' . $params);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_HTTPHEADER,
    array('Authorization: BASIC ' . base64_encode(TW_API_TOKEN . ':xxx'))

  // Run the HTTP request and decode the result.
  $output = curl_exec($curl);
  return json_decode($output, true);

// Get data about the current user.
$me = TeamworkGet('me');
$me = $me['person'];

// Store the user's full name for display.
$full_name = $me['first-name'] . ' ' . $me['last-name'];

// Set option to filter tasks by current user.
$options = array(
  'responsible-party-id' => $me['id'],
// Get current user's tasks.
$tasks = TeamworkGet('tasks', $options);
$tasks = $tasks['todo-items'];

// Reformat the due date string for readablility.
foreach ($tasks as &$task) {
  if (!empty($task['due-date'])) {
    $task['due-date'] = date("D n/j/Y", strtotime($task['due-date']));
    <title>TeamworkPM Task List for <?php print $full_name; ?></title>
    <h2>TeamworkPM Task List for <?php print $full_name; ?></h2>
          <th>Due Date</th>
          <th>Task List</th>
      $format = '<td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>';
      foreach($tasks as $task) {
        printf($format, $task['due-date'], $task['project-name'],
          $task['todo-list-name'], $task['content'], $task['description']);