How to sync Breathe HR and Tempo using MuleSoft Composer

Photo of Olga Kepa, MuleSoft Developer Written by Olga Kepa, MuleSoft Developer,   Jan 30, 2023

In this blog, I will describe the API-based integration between Breathe HR and Tempo with MuleSoft Composer. Breathe HR is a cloud-based HR software, and Tempo is a time-planning and logging app integrated with our Jira.

If previously the request for process automation came from our Ops team, this time, the Project Delivery asked for help. While creating project plans in Tempo, the team had to check constantly for approved leaves in Breathe HR; otherwise, they could face a severe problem by assigning a person to a project only to discover later that this employer was on holiday. You can imagine how tedious this task was, manually checking and copy-pasting between two software tools.

The Project Delivery team was clear on what good looks like - the booked and approved holiday or days off should be synchronised between Breathe HR and Tempo. Here again, MuleSoft Composer comes to the rescue!

I want to share how I used MuleSoft Composer to pull approved leave requests from Breathe HR and then create the appropriate leave plans in Tempo. This synchronisation ensured our hard-working Project Delivery team had a single source of truth for annual leave plans.

Please note that this exercise aims to demonstrate the Composer's capabilities rather than an attempt to create a full synchronisation between two platforms. So, let's start.

Extract employee data

Firstly, we create a scheduler in Composer to trigger our synchronisation daily.


Secondly, we pull all holiday submissions starting today or later from Breathe HR using the HTTP Connector. We also use a query parameter to filter out rejected requests.


We get all holiday submissions but still miss employee information associated with each holiday record. We iterate over the list of leave requests from Breathe HR and use the returned account ID to make another call to Breathe HR to retrieve the person's full name.Picture3

The example below shows that we are only interested in the person's ID, first, middle and last name.


Then, we iterate over the array of employee objects returned from Breathe HR endpoint. Using the employee's first and last name, we call Jira to get the associated accountId required by the Tempo API.


Below is an example response that we set to map data coming from Jira.


Synchronise half-day days off

We are ready to retrieve the holiday info from Tempo, passing the accountId identifier and the start and end dates.


It is time to check if a person has requested and got approval for a half-day leave:

  • if the Results array from Tempo is empty - there is no holiday booked for this employee,
  • if the field Half Start from Breathe HR is not empty - the person requested leave for half a day,
  • if the Leave Request status from Breathe HR is approved.

If the above conditions are satisfied, we will create a plan for half a day in Tempo.


To create a plan in Tempo, we will use a POST request.


Let's create an example holiday request with input fields, as shown below. Our new plan has a meaningful description to indicate that the plan was created by MuleSoft Composer, start and end dates and userId value previously returned by Jira. We also set the planned time to 14400 seconds (4 hours). 


Our 4-hour leave has been successfully created in Tempo, and it's time to send a notification message to a Slack channel.


Synchronise full days off

Back to the result received from the Tempo tool, but this time we iterate the array searching for an approved leave day:

  • the Results array from Tempo is empty - no leave plan has been created,
  • the Half Start is empty from Breathe HR - we are only interested in full-day leaves,
  • the Leave Request status from Breathe HR is approved.


If all conditions are satisfied, we should create the same leave plan in Tempo using a POST request.


As in the previous step, we will add an example request with input fields (see below). To create a plan, we use the start and end dates extracted from the leave request object (from Breathe HR) and userId from the Users array (from Jira). This time, we want to create a plan for the full day, so we set the planned time to 28800 seconds (= 8 hours). We also set a meaningful description to indicate that the plan was created by MuleSoft Composer.


As in a previous step, if the request is successful, we will send a message to a Slack channel.


Holidays waiting for approval

And next, we have another if block. This time we check the following:

  • If the Results array from Tempo is empty, which means no plan has been created.
  • If the leave request status from Breathe HR is other than approved. In this case, we don't create a new leave plan in Tempo as we are only interested in approved leave requests.


If the above conditions are true, we send a notification to our Slack channel:



Existing holiday plans in Tempo

Finally, we have a last-if block, where I check if the Results array from Tempo is not empty, which means the holiday plans have already been created in Tempo.


If there are already holiday plans in Tempo, we send a message to the Slack channel informing about the existing leave plans.


The final testing of my Breathe HR - Tempo integration.

I am ready to check the results of my synchronisation. We have two requests in Breathe HR  - a full day off on the 13th and a half day off on the 14th of December. There are currently no leave plans in Tempo for that days.


Let’s run the test, and now we see two plans successfully created in Tempo - for 8 hours on the 13th of December and 4 hours on the 14th of December.


As easy as that! Furthermore, there are two messages in the Slack Tempo channel notifying us about the newly created holiday plans.

Now, let’s create another leave request in Breathe HR for the 15th of December, but this time, it will not be approved. According to our logic, no leave plan should be created in Tempo for the 15th December.

Let’s click on the test and see what happens. In our Tempo, we have only two plans, as expected!


And I can see the following messages in the Slack channel:


It's time for the final test - I approve the leave request and expect to see a new leave plan created in Tempo for the 15th of December. And there shouldn't be any duplicate plans for the 13th and 14th of December. Let’s test our integration and see the result.

Ta-da! We have a new plan created for the 15th of December, with NO duplicates of the old holidays.



The Slack channel shows the expected messages informing about the existing plans.



And that’s it!

With a few system connectors and a couple of logic blocks, I've created an integration that could solve the problem of our Project Delivery team - switching between Tempo and Breathe HR for a full picture of the holiday booked. Obviously, to complete the synchronisation between these platforms, I should consider more complex cases, for example, the original request is deleted, or its dates are changed. But for now, it is a good demonstration of how you can approach integration with MuleSoft Composer.

Let me know what you think about this exercise and what other case you would consider.

We’d love to hear your opinion on this post