Skip to content
× FreshBooks App Logo
FreshBooks
Official App
Free - Google Play
Get it
You're currently on our US site. Select your regional site here:

Getting Started with FreshBooks NodeJS SDK – Expenses & Invoices

In this tutorial, we’ll be looking into the FreshBooks NodeJs SDK and how simple and easy it is to create, update and fetch Invoices, Expenses, Clients, Items, Payments, Projects, Time Entries etc. We have done all the heavy-lifting making it super convenient for you!

We have handled HTTP calls, HTTP retries, Idempotency, consistent request and response structures, and many more. This way you get to focus on your business logic rather than figuring out how the FreshBooks API works.

 

Pre-requisites

  • FreshBooks Developer account. If you don’t have one, you can create one here
  • How to authenticate on the FreshBooks API using Oauth2.0. No idea how to do that, we have an excellent tutorial here
  • Knowledge of Async, Await and Node.js
  • A code editor (eg VS Code, Sublime, Atom, etc)

Let’s get started!

  1. Install the FreshBooks Nodejs SDK
    In your Node project directory, install the FreshBooks NodeJs Client via npm or yarn
     
    npm install @freshbooks/api
    OR
    yarn install @freshbooks/api
  2. Get your FreshBooks Client ID

    Login to the FreshBooks Dashboard, Click on the Settings/Gear Icon, click on Developer Portal, click on your Oauth App and then note the Client ID. You’ll need it

    (By the way, this tutorial assumes you have created an existing Oauth App in the past and understand the dynamics of FreshBooks Authentication. If you haven’t, then this tutorial will guide you on how to create one.)



  3. Instantiate the FreshBooks Client

    Using the block of code, we can instantiate the FreshBooks Client:

    
          const logger = winston.createLogger({
            level: 'error',
            transports: [
                new winston.transports.File({ filename: 'error.log', level: 'error' }),
                new winston.transports.File({ filename: 'combined.log' }),
            ],
        });
        
        const clientId = '';
        
        // Get token from authentication or configuration
        const token = 'BEARER TOKEN';
        
        // Instantiate new FreshBooks API client
        const freshBooksClient = new Client(token, {
            clientId
        }, logger);
        
    Set a value for your Client ID and your Bearer Token. This tutorial assumes you have a helper function that helps generate the bearer tokens and refresh tokens from the /auth/oauth/token endpoints. If you don’t, you can check out authentication tutorial
  4. Confirm Instantiation

    Using the function below, we can confirm the instantiations works

    
          const confirmClientInstantiation = async () => {
            try {
                const { data: { firstName, roles } } = await freshBooksClient.users.me();
                accountId = roles[0].accountId;
                logger.info(`Hello ${firstName}`)
                return {
                    firstName,
                    accountId
                }
            } catch ({code, message }) {
                // Handle error if API call failed
                logger.error(`Error fetching user: ${code} - ${message}`)
                return {
                    error: {
                        code, message
                    }
                }
            }
         }
         console.log(await confirmClientInstantiation());
    
    
    If everything works as expected you should see a response similar to the below when you invoke the function. It also returns some useful information (especially the accountid. Store in a variable, You’ll need it in other method calls)
    
    
    
    {
       "firstName":"John",
       "accountId":"Zz2EMMR"
    }
    
    

    If there is something wrong, you will receive a response that looks like this:

    
    
          {
            error: {
              code: 'unauthenticated',
              message: 'This action requires authentication to continue.'
            }
          }
        
  5. Create A Client

    If everything works as expected, you should be able to create a Client, an Invoice, etc.

    For simplicity, we’ll create a Client. Once we do that, this same Client will be created immediately on the FreshBooks dashboard

    
          const logger = winston.createLogger({
            level: 'error',
            transports: [
                new winston.transports.File({ filename: 'error.log', level: 'error' }),
                new winston.transports.File({ filename: 'combined.log' }),
            ],
        });
        
        const clientId = '';
        
        // Get token from authentication or configuration
        const token = 'BEARER TOKEN';
        
        // Instantiate new FreshBooks API client
        const freshBooksClient = new Client(token, {
            clientId
        }, logger);
        


  6. List Expenses

    We should also be able to list Expenses using the sample block below

    
          //Fetch Expenses
            const fetchExpenses = async () => {
              try {
                  const { ok, data } = await freshBooksClient.expenses.list(accountId);
                  return ok && data
              } catch ({ code, message }) {
                  console.error(`Error fetching expenses for accountid:  ${accountId}. The response message got was ${code} - ${message}`)
              }
            }
    
            console.log(await fetchExpenses());
        

    If everything checks out, you should get a list of expenses These expenses are also listed on the FreshBooks Dashboard

    
          {
            expenses: [
              {
                 …
                id: '7538415',
                taxAmount2: null,
                taxAmount1: null,
                visState: 0,
                status: 0,
                vendor: 'FreshBooks Payments',
                notes: 'CC Payment Transaction Fee Invoice: #2021-09',
                updated: 2021-04-17T06:45:36.000Z,
                ...
              }
            ]
         
     
Conclusion

This implementation simply scratched the surface of the possibilities of the Node.js SDK as there are several use cases that can be achieved with it.

Did you find this tutorial helpful? Did it spark up your imagination? Let us know about the apps you’re creating, or about new ways you’re integrating your business with FreshBooks.


Happy Coding

You can view the entire code on this GitHub.

Still, have questions? Something isn’t working? Raise an issue on our GitHub repo or reach out to newapi@freshbooks.com.

We’ll respond to your request as quickly as we can!