BACK TO TOP

Using PHP and the Harvest API to return project time for a date range and user

Here is some PHP functions and code to return a particular users time entries for a date range from the Harvest API.

Functions

Firstly, there are a couple of functions you will need in order to send requests to the Harvest API and interpret the responses. This could go in a include file if you like and can be reused on other scripts.

<?php

// harvest settings
$username = ""; // your harvest email
$password = ""; // your harvest password

// encode above credentials
$encodedcredentials = base64_encode($username . ":" . $password);

// function to return the headers as an array
function get_headers_from_curl_response($response) {
 $headers = array();

 $header_text = substr($response, 0, strpos($response, "\r\n\r\n"));

 foreach (explode("\r\n", $header_text) as $i => $line)
 if ($i === 0)
 $headers['http_code'] = $line;
 else
 {
 list ($key, $value) = explode(': ', $line);

 $headers[$key] = $value;
 }

 return $headers;
 }

// function to return body as an array
function get_body_from_curl_response($response) {
 
 $body_text = substr($response, strpos($response, "\r\n\r\n"), strlen($response));
 $body = json_decode($body_text, true);
 
 return $body;
 }

// function to GET, POST or PUT to the Harvest API
function harvest_curl($url, $json, $encodedcredentials, $type) {

 $curl = curl_init();

 curl_setopt_array($curl, array(
 CURLOPT_URL => $url,
 CURLOPT_RETURNTRANSFER => 1,
 CURLOPT_ENCODING => "",
 CURLOPT_MAXREDIRS => 10,
 CURLOPT_HEADER => true,
 CURLOPT_TIMEOUT => 30,
 CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
 CURLOPT_CUSTOMREQUEST => $type,
 CURLOPT_POSTFIELDS => $json,
 CURLOPT_HTTPHEADER => array(
 "accept: application/json",
 "authorization: Basic " . $encodedcredentials . "",
 "cache-control: no-cache",
 "content-type: application/json"
 ),
 ));

 $response = curl_exec($curl);
 $err = curl_error($curl);
 
 curl_close($curl);
 
 if ($err) {
 echo "cURL Error #:" . $err;
 } else {
 return $response; 
 }

}

The Code

Now for the code, the only real thing you need to customise is $userprojects_url varible with your Harvest account url, the project ID and date range.

// API url and JSON request, if required
$userprojects_url = "https://YOURACCOUNT.harvestapp.com/projects/{PROJECT_ID}/entries?from=YYYYMMDD&to=YYYYMMDD"; 
$userprojects_json = ''; // none are required for this one

// run the API request
$userprojects = harvest_curl($userprojects_url, $userprojects_json, $encodedcredentials, 'GET');

// create varibles from the API response for the header and body
$headers = get_headers_from_curl_response($userprojects);
$body = get_body_from_curl_response($userprojects);
 
// check headers for status code
if ($headers['Status'] == "200 OK") {
 
 // loop through each day
 foreach($body as $value) {
 
 // loop through all entries and display the results
 foreach($value as $key => $val) { 
 echo 'Task ID: ' . $val['task_id'] . '<br>';
 echo 'Notes: ' . $val['notes'] . '<br>';
 echo 'Time: ' . $val['hours'] . '<br>';
 echo '--------<br>';
 }
 
 }
 
} else {
 
 // display the error
 echo 'Status: ' . $body['status'] . '<br>';
 echo 'Error: ' . $body['error'] . '<br>';
 
}

There are a bunch of other parameters which can be output, for a full reference see the Harvest API documentation.

Please note: I am publishing this code as a personal reference and in the hopes it may help someone out in the future. So basically use it at your own risk and I don’t take any responsibility for its use.