Hey everyone, I’m trying to set up an automatic invoice generation in Harvest when someone moves a card to a specific list in Trello. I tried using Zapier but it doesn’t have built-in invoice features for Harvest.
I know I need to code this myself using either JavaScript or Python. I’ve got the JSON request ready, but I’m not sure how to send it properly. Here’s what I’ve tried so far:
function sendInvoiceRequest() {
const invoiceData = {
invoice: {
dueDate: 'NET 15',
clientId: 4567890,
currency: 'EUR',
issueDate: '2023-05-01',
title: 'Monthly Project Invoice',
comments: 'Thanks for your business!',
invoiceNumber: '2023-001',
type: 'time-based',
projectId: '987654',
includeTime: true,
includeExpenses: true,
billingStart: '2023-04-01',
billingEnd: '2023-04-30'
}
};
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://myaccount.harvestapp.com/invoices');
xhr.setRequestHeader('Authorization', 'Basic ' + btoa('myemail:mypassword'));
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(invoiceData));
}
Can someone help me figure out what I’m doing wrong? I can’t get it to work outside of Postman. Any tips on basic authentication or improving this code would be great. Thanks!
hey jackhero77, looks like ur on the right track! for basic auth, try using a token instead of email/password. also, make sure to handle the response with xhr.onload. here’s a quick example:
xhr.setRequestHeader('Authorization', 'Bearer YOUR_TOKEN_HERE');
xhr.onload = () => console.log(xhr.responseText);
hope this helps! lmk if u need more info
I’ve encountered similar issues with Harvest’s API. One key thing to note is that Harvest now recommends using their API v2 endpoints. The URL you’re using seems outdated. Try updating your request to ‘https://api.harvestapp.com/v2/invoices’ instead.
Also, for authentication, Harvest prefers OAuth 2.0. You’ll need to set up an OAuth 2.0 application in your Harvest account settings to get the necessary credentials. Then, use the access token in your request header like this:
xhr.setRequestHeader(‘Authorization’, ‘Bearer YOUR_ACCESS_TOKEN’);
xhr.setRequestHeader(‘Harvest-Account-ID’, ‘YOUR_ACCOUNT_ID’);
These changes should resolve your authentication issues and allow you to successfully create invoices programmatically.
I’ve actually implemented something similar for my business. One thing I found crucial was error handling. Your current code doesn’t account for failed requests or API limits. Here’s a snippet that might help:
xhr.onerror = function() {
console.error('Request failed. Please check your network connection.');
};
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 201) {
console.log('Invoice created successfully!');
} else if (xhr.status === 429) {
console.warn('Rate limit exceeded. Try again later.');
} else {
console.error('Error creating invoice:', xhr.status, xhr.statusText);
}
}
};
Also, consider using the Fetch API instead of XMLHttpRequest. It’s more modern and easier to work with, especially when dealing with promises and async/await syntax. Good luck with your integration!