Get Started with FreshBooks API
Learn about the sign-up process, authentication, and generating access token for a FreshBooks account.
Signing up
Let's visit the sign-up link and create an account on FreshBooks.
Enter your email address and password, check the agreement statement box, and click the "Get Started" button.
You'll receive an email to verify that the entered email is valid and belongs to you. You need to verify your email before using FreshBooks services.
Enter your basic information and click the "Next" button.
Enter details of your company and click the "Save and Finish" button.
Congratulations! The signup process is complete, and you’ll be redirected to the dashboard.
Creating an application
Once we sign up for FreshBooks, the next step is to create an application. Visit the developer page and click on the “Create New App” button. We’ll be redirected to the “Create Application” form. Here, we need to fill in the following fields:
- Application Name: In this field, we need to give a name to our application. This is a required field.
- Application Type: There are three options in the dropdown list of this field: “Test App,” “Private App,” and “Public App.” Select the “Test App” option. This is a required field.
- Upload Logo: We can also add a logo for our application. This is an optional field.
- Description: We need to describe the purpose of our application. This is an optional field.
- Website URL: We need to give our website URL from where users can learn more about our application. It is an optional field.
- Application Settings URL: We need to give the settings link of our application. It is an optional field.
- Scopes: Here, we need to add scopes to our application so it can access the information in our FreshBooks account. We click on the “Add Scope” button to add permissions. We recommend adding all permissions so that the application can access every detail. This is a required field.
- Redirect URIs: Here, we add a URI where we want to redirect users after they select to authenticate our application. This is a required field. We need to add the redirect URI given below:
{{EDUCATIVE_LIVE_VM_URL}}/callback
After filling in these fields, we must follow the steps below:
- Click the “Save” button at the top of the form and create the application. After this, we’ll be redirected to the developer page, where we’ll see the created application.
- Click the name of our application, and get into the application settings.
- Scroll down to the end of the page to find “Client ID” and “Client Secret.” Copy and paste them into the code widget below.
Click the "Edit" button below. Enter the "Client ID" for SECRET_ID
and the "Client Secret" for SECRET_KEY
. Click the "Save" button to use it throughout the course. We define base_url
at line 3 in the code widget below. It'll be used for all the API calls that we are going to see in this course.
console.log("Your Secret ID is: {{SECRET_ID}}");console.log("Your Secret Key is: {{SECRET_KEY}}");console.log("Your base_url is: https://api.freshbooks.com");console.log("Redirect URL is: {{EDUCATIVE_LIVE_VM_URL}}/callback");
Generate an access token
The FreshBooks API uses OAuth 2.0 protocol for authorization. It creates a token that remains valid for a limited time to keep the account secure. The user is asked to grant some permissions to the application if they want to use the application. For this, we have an express
server in the widget below that takes the permissions from the user and generates the access token.
Note: The bearer token for FreshBooks expires after 12 hours. Please use the "Regenerate the Access Token" lesson in the appendix to regenerate the access token.
import express from 'express'; import { stringify } from 'querystring'; import fetch from 'node-fetch'; const app = express(); const port = 8080; const client_id = '{{SECRET_ID}}'; // Your client id const client_secret = '{{SECRET_KEY}}'; // Your client secret const redirect_uri = '{{EDUCATIVE_LIVE_VM_URL}}/callback'; // Your redirect uri var authCode, accessToken, refreshToken; async function fetchTokens(req, res) { const endpointUrl = 'https://api.freshbooks.com/auth/oauth/token'; const auth64 = Buffer.from(client_id + ':' + client_secret).toString( 'base64' ); const headerParameters = { authorization: `Basic ${auth64}`, 'Content-Type': 'application/x-www-form-urlencoded', }; const bodyParameters = new URLSearchParams(); bodyParameters.append('host', 'api.freshbooks.com'); bodyParameters.append('client_id', client_id); bodyParameters.append('client_secret', client_secret); bodyParameters.append('code', authCode); bodyParameters.append('grant_type', 'authorization_code'); bodyParameters.append('redirect_uri', redirect_uri); bodyParameters.append('version', '2'); const options = { method: 'post', headers: headerParameters, body: bodyParameters, }; try { var response = await fetch(endpointUrl, options); try { const jsonContent = await response.json(); console.log(response.status); console.log(jsonContent); accessToken = jsonContent.access_token; refreshToken = jsonContent.refresh_token; res.write( '<body><div style="margin:50px;"><h1> Your Access Token is: </h1><textarea rows="15" cols="150" readOnly>' + accessToken + '</textarea></div></body>' ); res.write( '<body><div style="margin:50px;"><h1> Your Refresh Token is: </h1><textarea rows="2" cols="150" readOnly>' + refreshToken + '</textarea></div></body>' ); res.send(); } catch (err) { console.log(`Error: ${err}`); } } catch (err) { // Printing error message console.log(`Error: ${err}`); } } app.get('/', function (req, res) { // your application requests authorization var scope = 'user:profile:read user:bill_vendors:read user:bill_payments:write user:bills:write user:bills:read user:business:read user:billable_items:write user:bill_vendors:write user:bill_payments:read user:credit_notes:write user:credit_notes:read user:clients:read user:billable_items:read user:expenses:write user:expenses:read user:estimates:read user:clients:write user:journal_entries:write user:journal_entries:read user:invoices:read user:estimates:write user:other_income:read user:online_payments:write user:notifications:read user:projects:write user:teams:read user:taxes:read user:retainers:write user:reports:read user:time_entries:write user:time_entries:read user:taxes:write user:payments:write user:uploads:write user:retainers:read user:payments:read user:invoices:write user:uploads:read user:teams:write user:other_income:write user:online_payments:read user:projects:read'; res.redirect( 'https://auth.freshbooks.com/oauth/authorize?' + stringify({ client_id: client_id, response_type: 'code', redirect_uri: redirect_uri, scope: scope, }) ); }); app.get('/callback', (req, res) => { authCode = req.query.code; console.log('AuthCode:' + authCode); fetchTokens(req, res); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
Click the "Run" button above to execute the code, and click the URL against "Your app can be found at." A new tab opens where consent for the permissions is taken. Click the “Allow” button to use the application. You only need to perform this task for the first time while accessing an application. The next time, access permissions will not be asked. Once the authorization step is completed, you’ll be presented with a page with the access token, and the refresh token. We need to copy and paste them into the widget below to use in the next lessons.
Testing configuration and getting ACCOUNT_ID
First, let’s get details about the user in our FreshBooks account. We’ll use /auth/api/v1/users/me
as an endpoint to get an ACCOUNT_ID
. The account ID is automatically extracted in the widget. Click the “Save” button to use it throughout the course.
// Importing libraries hereconst fetch = require('node-fetch');// Define endpoint URL hereconst endpointUrl = 'https://api.freshbooks.com/auth/api/v1/users/me';const headerParameters = {'Authorization': 'Bearer {{ACCESS_TOKEN}}','Content-Type': 'application/json',}// Setting API call optionsconst options = {method: 'GET',headers: headerParameters,};// Function to make API callasync function testingToken() {try {const response = await fetch(`${endpointUrl}`, options);printResponse(response);} catch (error) {// Printing error messageprintError(error);}}// Calling function to make API calltestingToken();