Archiving a Basecamp Project Using cURL and PHP

cURLOk, this is another slightly technical post, but I hacked and hacked and finally got it to work so I wanted to share.

We use Basecamp for our project management here, and we recently started a large reporting project where we created nearly 200 projects to manage each of the reports. After several months, the projects are done and ready to be archived. As the account owner, I can archive those projects, but doing each manually via the web would be a pain in the you know where.

Enter Basecamp’s API.

I use it to do some reporting and measurement, but I only GET data from Basecamp, I don’t POST or DELETE. Here’s the wrinkle: to archive a project you have to use cURL‘s PUT functionality. While not impossible, it’s slightly trickier.

Here’s code that worked to allow me to archive 200 projects this morning. A few caveats about Basecamp’s API:

  • You’ll need to PUT to the specific project’s json URL. It can be found by querying the project’s information using the GET api.
  • You will need to PUT the data in json format. You can see below, I’m creating a PHP array, then using json_encode to format that into json that Basecamp wants.
  • You need to specify a USER-AGENT with the name of your app and contact information.
  • All calls made to the Basecamp API must be made over SSL.
$appName = 'Your App Name';
$appContact = 'example@contact.com';
$basecampUsername = 'XXXXX';
$basecampPassword = 'XXXXX';
$url = "https://basecamp.com/XXX/api/v1/projects/XXX.json";
$credentials = "$basecampUsername:$basecampPassword";
$helloHeader = "User-Agent: $appName ($appContact)";
$data = json_encode(array("archived" => true));

$xheaders = array(                                                                          
    'Content-Type: application/json',                                                         
    'Content-Length: ' . strlen($data)
 );

$ch = curl_init($url);
    curl_setopt($ch, CURLOPT_USERPWD, $credentials);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);  
    curl_setopt($ch, CURLOPT_USERAGENT, $helloHeader);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $xheaders);

    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    curl_close($ch);

    echo "
<pre>";
    print_r($response);
    echo "</pre>

";

If you get a 200 response, your project is now archived. Congrats!

Basecamp Response