The HarvardMaps API allows you to request data programmatically from HarvardMaps in JSON, JSONP, or XML format. The API provides a RESTful interface, which means that you can query it using simple HTTP GET requests.


Use of this API is governed by a Creative Commons Attribution-Noncommerical 3.0 Unported license, which means that you may use its data for non-commercial purposes so long as you attribute your data to this API, as by including a link to HarvardMaps in your own work. To discuss commercial purposes, contact the author.


To use this API, you must register for an API key.


Usage of this API is limited to 60 queries per minute.

Try it out!

The online documentation allows you, once you sign in, to try out making queries on you own, so be sure to try out some queries and see how it works.

Bug Report

If you find bugs in any CS50 API, email with your bug.


All methods support CORS.


To query the HarvardMaps API for buildings, contact the server via URLs in this format:

Supported parameters include:

parameter description


Optional. Comma-separated list of buildings' roots. If omitted, all buildings will be returned. If this parameter is provided, id should not be.


Optional. Comma-separated list of buildings' IDs. If omitted, all buildings will be returned. If this parameter is provided, root should not be.


Required iff output is *jsonp*. Callback function with which response will be padded.


Required. Format for output. Must be json, jsonp, or xml.

If any parameters are malformed or any required parameters are omitted, an empty response will be returned along with, possibly, HTTP status code 400 Bad Request.

Harvard is in the process of transitioning "building IDs" (aka bids, aka BL_IDs) to "roots" as unique identifies for buildings. This API supports both for backwards compatibility’s sake. Note that buildings' IDs are not strictly numeric; some are alphanumeric. All roots should be 5-digit values. Some building IDs and some roots include leading zeroes.


If you request channels in JSON format (e.g.,,03365&output=json), the response wil be an array of objects, per the below:

      "name":"Mather House",
      "name":"Matthews Hall",


If you request channels in JSONP format (e.g.,,03365&output=jsonp&callback=parseResponse), the response will be a padded array of objects, per the below:

parseResponse([{"root":"03364","id":"991","name":"Mather House","lat":"42.368270","lng":"-71.115270"},{"root":"03365","id":"952","name":"Matthews Hall","lat":"42.374070","lng":"-71.118150"}])


If you request data in XML format (e.g.,,03365&output=xml), the response will be an XML document whose root element is buildings, each of whose children is a building, per the below:

<?xml version="1.0" encoding="utf-8"?>
    <name>Mather House</name>
    <name>Matthews Hall</name>


  • 1.0

  • 1.1

    • Added support for JSONP * 1.2

    • Added support for root.

    • Added support for XML

  • 1.3

    • Fixed bug in CSV format whereby address header was omitted.

  • 2

    • Added API keys

    • Changed backend to python