Import Harvest Data to Google Sheets

Harvest is a popular time tracking and invoicing tool that provides numerous integrations, but no official integration for Harvest and Google Sheets. In this guide, we’ll walk through how to pull data from the Harvest API directly into Google Sheets, using the API Connector add-on. We’ll first get a personal access token from Harvest, and then set up a request to pull in data from Harvest to your spreadsheet.

PART 1: GET YOUR HARVEST PERSONAL ACCESS TOKEN

If you are using API Connector’s new OAuth2 connections manager (paid feature), you can skip this entire section. Instead of getting an access token, just click Harvest on the Connections menu and go directly to Part 2 of this tutorial.
harvest-img7
  1. Sign into Harvest and navigate to their Developer Tools page (https://id.getharvest.com/developers)
  2. Click “Create New Personal Access Token”
    harvest-img1
  3. Give it a name and click “Create Personal Access Token”. You can name it anything, but we’ll call it ‘Google Sheets’ here.
    harvest-img2
  4. You should now see a page containing all your API access details. Congrats! You’re now ready to access the Harvest API. Keep these details handy as we’ll need them in a moment.
    harvest-img3

PART 2: CREATE YOUR HARVEST API REQUEST URL

We’ll follow the Harvest API documentation to get time entries.

  • API root: https://api.harvestapp.com/v2
  • Endpoint: /time_entries
  • Parameters: ?page=PAGE_NUMBER
    Parameters Example: ?page=1

The ‘page’ parameter is optional but we’ll include it to show how parameters work. Putting it all together, we get the full API Request URL:

https://api.harvestapp.com/v2/time_entries?page=1

PART 3: PULL HARVEST API DATA INTO SHEETS

We can now enter all our values into API Connector and start importing Harvest data into Google Sheets.

  1. Open up Google Sheets and click Add-ons > API Connector > Open.
  2. In the Create screen, enter the Request URL we just created:
    harvest-img4
  3. Under Headers, enter the following key-value pairs (again, if you’re connecting through the OAuth2 connections manager, you only need to enter the Harvest-Account-Id header.):
    Harvest-Account-IdYOUR_ACCOUNT_ID
    AuthorizationBearer YOUR_TOKEN
    User-AgentYOUR_TOKEN_NAME (YOUR_EMAIL)

    Just substitute in your own values using the values from your API access details page and your own email address. The whole thing should look something like this:

    harvest-img5
  4. If you’re using the OAuth2 connection manager, choose “Harvest” from the drop-down authentication menu. Otherwise, just leave it as “None”.
  5. Create a new tab and click ‘Set current’ to use that tab as your data destination.
  6. Name your request and click Run. A moment later you’ll see Harvest data populate your Google Sheet:harvest-img6

PART 4: MORE EXAMPLE API URLS

You can check the documentation for the full list of available API requests,  but if you just want to jump in, you can play around with the URLs you enter in the API URL path field. Try the following (one at a time):

https://api.harvestapp.com/v2/time_entries
https://api.harvestapp.com/v2/clients
https://api.harvestapp.com/v2/invoices
https://api.harvestapp.com/v2/tasks
https://api.harvestapp.com/v2/expenses
https://api.harvestapp.com/v2/projects

PART 5: HANDLE FILTERING

You may want to limit your pulls for certain client IDs. You can combine parameters like this: https://api.harvestapp.com/v2/time_entries?client_id=1234567&page=1 (you can find your client ID in the “clients” table).

PART 6: HANDLE PAGINATION

Harvest limits the number of records returned in each request. By default, only 100 records will be returned unless you use the ‘page’ parameter as described in their documentation.
harvest-sheets-img5

Each page contains 100 records. To access more than 100 records, edit the “page” parameter to your URL path, like this:

https://api.harvestapp.com/v2/time_entries?page=1
https://api.harvestapp.com/v2/time_entries?page=2

With API Connector, you can either set these up as separate requests or loop through them automatically with pagination handling (paid feature), like this:

harvest-img8

Following the above steps, you will now be able to import data from the Harvest API directly into Google Sheets. By setting Google Sheets as a data source, you can also use this method to create Harvest data visualizations and dashboards in Google Data Studio.

18 thoughts on “Import Harvest Data to Google Sheets”

  1. Great help, pulls data in! Is it possible to set a data range of the data pulled in however, i’m unclear how much data this is pulling

    Reply
    • Most of Harvest’s API responses sort by recency (e.g. the ‘spent_date’ or ‘created_at’ fields) and are limited to 100 records. You can see the specific default sort field in the documentation, but generally this means that if you run a Harvest API query without any parameters, it will return most recent 100 records. If you wanted to get data for, say, February, you’d add parameters like https://api.harvestapp.com/v2/time_entries?from=2019-02-01&to=2019-02-28

      Reply
      • Hi Ana,
        is it planned to expand the record limit in the near future? with only 100 records we’re very limited in all requests we do. 🙁

      • I’m not sure if I totally understand your question. The 100 record per page limit comes from Harvest, not API Connector, and the article explains two different methods of getting more than 100 records by requesting additional pages.

  2. I’m getting a “Failed to run request” error when coping the above (but with my token info).
    Can you explain what “Bearer” in the Authorization key is for?

    Reply
    • Hi Shawn, the string “Bearer” is required by Harvest. More generally, “Bearer” authentication is an HTTP authentication scheme. If you’re still having trouble feel free to email over a screenshot and I’ll take a look.

      Reply
  3. Hello my data got pulled in, but it didn’t pull in Header information to the Gsheet, and some fields that are text , are showing as numbers. Can you help me ?

    Reply
    • Can you please click the ‘Output Options’ button and check what mode you’re in? Overwrite mode will print out headers, while Append mode won’t (info).
      As for fields showing up as numbers instead of text, formats are automatically assigned by Google based on its best guess of what the data is. If it has guessed incorrectly, please try changing the format using Sheets built-in format functions. You can also create a new sheet where you assign the correct data formats to each column, and then populate those columns by querying your API data sheet (e.g. =QUERY(Harvest!A:Z, “select A, B,C”)

      Reply
  4. Hi.
    I can’t use a token at harvest because my client prefer the authentication by using email&password.

    client = harvest.Harvest(f”https://{account}.harvestapp.com”, email, password)
    client.who_am_i

    My client wants to make an arbitrary query to the harvest API to get a report on how the user spent their time.
    But in that case, I don’t find any solution in harvest API v2 documentation.
    Please help me with this problem.

    Kind regards.
    Mark.

    Reply
    • Sorry, I don’t think I can help you here, since as you found in the documentation, Harvest V2 API only provides 2 methods of authentication, and neither involves email & password. However you can check the V1 version of their API, I’m not really familiar with that but a quick scan shows it uses Basic Authentication, which basically means encoding your email address and password to base64 and adding it to a header. Maybe that works for you? (V1 documentation).

      Reply
  5. Hello,

    I created a new tab/sheet and when the sheet is selected I click ‘Set’ and I get

    ScriptError: Authorization is required to perform that action.

    Do you know what I need to fix here? I have written out the three headers according to your format. I don’t see any issues there or with the API URL.

    Any ideas? I appreciate your help.

    Reply
      • Hello Ana, Thank you for the prompt reply. What I’m trying to do is get the Time Entries with the Tasks name “Admin”. Did try to add the parameters after the URL name=Admin and still it doesn’t work. Can youp please help?

      • If you’re looking to filter the time_entries endpoint, you need to use the task_id parameter, like this: https://api.harvestapp.com/v2/time_entries?task_id=YOUR_TASK_ID, where you substitute in your own task ID. If you don’t know your task ID, you can find it by querying the endpoint https://api.harvestapp.com/v2/tasks/.

  6. Any idea how to get a custom column to stay when the API runs? For example, Harvest has a date column but in order to keep my pivots flowing I need a month column. I made one off to the side but it disappears whenever the API runs. Thoughts?

    Reply
    • Hi John, you can’t include custom columns in the destination sheet since all data will be overwritten each time the request runs. I suggest using a Sheets function like QUERY() to pull all your data into a second sheet, and then creating any custom columns and calculations in that second sheet. 

      Reply

Leave a Comment