How to sync Oura ring sleep entries to Google Calendar

In this guide, I’ll show you how to auto-sync sleep entries from Oura to Google Calendar. Every morning, the automation will create an event with last night’s key sleep metrics, such as resting HR, HRV, and time spent per sleep stage. Luckily, Oura exposes an open API so connecting it to a calendar through Zapier is straightforward. I use Google Calendar, but any alternative that has a Zapier integration or an API should work. Building this automation will require an Oura ring, a paid Zapier plan, and about 30 mins.

A sleep entry in Google Calendar


I’ll use Zapier to poll for new entries via a JavaScript trigger that fetches Oura’s API and create a new calendar event if it’s a new entry. The Zap will contain three steps:

  1. A JavaScript trigger to get the latest sleep entry and decide if it should be added to the calendar. The criteria is the current time being between 4h and 4h 20m after the end of the sleep period. This is because Oura calculates sleep metrics within 4h from the period end, but it may trigger sleep analysis multiple times for one sleep period (such as when you wake up and open the app but then sleep back). Therefore a sleep period should be considered “completed” after 4h from the period end. I added the 4h 20m upper limit to avoid excessive task usage on Zapier — the starter plan has Zaps check for new data every 15 mins, so the trigger should be guaranteed to execute at least once within this interval. Professional and larger plans have 2 and 1 minute update times, so you could adjust this limit to 4h 4m and 4h 2m respectively to avoid needless task usage.
    Note: one limitation of this setup is that if analyzed sleep data doesn’t get synced within 4h, then the Zap can miss it, causing the sleep period to be omitted from the calendar. This can happen if your ring is in offline mode or if you don’t open the app within a few hours after wake up. In this case, you can hardcode lastNight.add_to_calendar = true in the zap to manually add the missing entry. This aspect could be improved down the line.
  2. A “Filter by Zapier” action to only continue if a new sleep event should be created in the calendar.
  3. A “Find or Create Event in Google Calendar” action to create the actual event. This action will first search for the sleep event and only create it if it doesn’t exist yet. This is to make sure that only one event is created even if the Zap runs multiple times (eg. twice within the 4m time limit assuming a professional plan).
The three steps in the Zap


1. Trigger: Run JavaScript
  • Create a new Zap and choose “Code by Zapier” as the app. Select “Run JavaScript” as the trigger event.
  • Generate an access token on Oura Developer under “Personal Access Tokens.” You’ll need it for the next step. Add a note “oura_google_calendar_zap” or similar.
  • For the trigger, use the code from this gist.
2. Action: Only continue if…
  • Select “Filter by Zapier” as the app.
  • For the criteria, select “Add To Calendar” and “(Boolean) is true”.
3. Action: Find or Create Event in Google Calendar
  • Select “Google Calendar” as the app.
  • Select “Find Event” as the action event.
  • Select the account and calendar you’ll want to use.
  • For the Search Term, enter “💤💤💤”.
  • For Start Time, select “Bedtime Start” from the trigger.
  • Leave End Time blank.
  • Check “Create Google Calendar Detailed Event if it doesn’t exist yet?”
  • For the new event, set Start Date & Time to “Bedtime Start” from the trigger and End Date & Time to “Bedtime End”.
  • For the Summary, enter “💤💤💤” or your title of choice.
  • Select a Color for the new event. I used ■ #7AE7BF which looked nice in Google Calendar.
  • Fill out the description to include sleep metrics. Oura’s API doc describes the returned metrics so you can add more if you want. Here’s my version:

After this, test your Zap for one or two sleep entries and it should be ready to go. You're done.

December 27, 2020
I send out occasional emails about new posts, learnings, scientific discoveries, and combinations of insights that I found interesting. No promotions.
Thank you. You are now subscribed.
An unexpected error occured