WellAlly Logo
WellAlly康心伴
Development

Connecting Wearables: A Developer's Guide to Integrating the Oura Ring API

Learn how to build a complete wellness dashboard by connecting to the Oura Ring API. This guide covers the OAuth2 flow in Next.js, fetching sleep and activity data, and visualizing it with React and Recharts.

W
2025-12-12
8 min read

Wearable technology like the Oura Ring provides a wealth of personal health data. For developers, this data is a goldmine for creating personalized wellness applications. The challenge, however, lies in securely accessing and then meaningfully visualizing this data.

In this tutorial, we'll build a wellness dashboard that connects to the Oura Ring API, fetches your daily health metrics, and displays them in a clean, graphical interface. We'll be using a modern web stack: Next.js for our React framework and Recharts for data visualization.

By the end of this guide, you'll have a working web application and a solid understanding of how to integrate wearable tech APIs into your own projects. This is a practical skill for anyone interested in the booming health tech space.

Understanding the Problem

While the Oura app itself is excellent, you might want to correlate your Oura data with other data sources, create custom visualizations, or build a unique wellness application. The official Oura API is the gateway to these possibilities. However, integrating with any API, especially one that uses OAuth2 for authentication, can be tricky.

Our approach will be to create a Next.js application that handles the OAuth2 handshake, securely stores the access tokens, and then uses those tokens to fetch data from the Oura API. We'll then pass that data to our frontend to be rendered into insightful charts.

Prerequisites

  • An Oura Ring and Oura account.
  • Node.js (v18 or later) and npm installed.
  • Basic knowledge of React and Next.js.

Step 1: Setting up your Oura API Application

First, we need to register a new application in the Oura developer portal.

What we're doing

We'll create an OAuth2 application to get a Client ID and Client Secret, which our Next.js app will use to authenticate with the Oura API.

Implementation

  1. Go to the "API Applications" section in your Oura developer portal and click "Create New Application".
  2. Fill in the application details.
  3. Once created, you will be provided with a Client ID and a Client Secret. Keep these safe; we'll need them in a moment.

Step 2: Initializing our Next.js Project

Now, let's get our Next.js application up and running.

What we're doing

We'll create a new Next.js project and set up our environment variables to securely store our Oura API credentials.

Implementation

code
npx create-next-app@latest oura-wellness-dashboard
cd oura-wellness-dashboard
Code collapsed

Next, create a file named .env.local in the root of your project and add your Oura API credentials:

code
OURA_CLIENT_ID=your_client_id
OURA_CLIENT_SECRET=your_client_secret
NEXTAUTH_URL=http://localhost:3000
Code collapsed

How it works

The .env.local file is a special file in Next.js for storing environment variables that are not committed to source control. This keeps your API keys secret and safe.

Step 3: Implementing Oura API Authentication

We'll use Next.js API routes to handle the OAuth2 flow.

What we're doing

We'll create two API routes: one to redirect the user to Oura's authorization page and another to handle the callback from Oura after the user has granted permission.

Implementation

First, let's create the login route. Create a new file at pages/api/auth/login.js:

code
// pages/api/auth/login.js
export default function handler(req, res) {
  const authUrl = `https://cloud.ouraring.com/oauth/authorize?client_id=${process.env.OURA_CLIENT_ID}&redirect_uri=${process.env.NEXTAUTH_URL}/api/auth/callback&response_type=code&scope=daily`;
  res.redirect(authUrl);
}
Code collapsed

Now, let's create the callback route at pages/api/auth/callback.js:

code
// pages/api/auth/callback.js
import { serialize } from 'cookie';

export default async function handler(req, res) {
  const { code } = req.query;

  if (!code) {
    return res.status(400).send('No code provided');
  }

  const tokenResponse = await fetch('https://api.ouraring.com/oauth/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code,
      redirect_uri: `${process.env.NEXTAUTH_URL}/api/auth/callback`,
      client_id: process.env.OURA_CLIENT_ID,
      client_secret: process.env.OURA_CLIENT_SECRET,
    }),
  });

  const tokenData = await tokenResponse.json();

  if (tokenData.error) {
    return res.status(400).json(tokenData);
  }

  const cookie = serialize('oura_token', tokenData.access_token, {
    httpOnly: true,
    secure: process.env.NODE_ENV !== 'development',
    maxAge: tokenData.expires_in,
    sameSite: 'lax',
    path: '/',
  });

  res.setHeader('Set-Cookie', cookie);
  res.redirect('/dashboard');
}```

### How it works

The `/api/auth/login` route simply redirects the user to Oura's authorization page with our `client_id` and `redirect_uri`. Once the user approves, Oura redirects them back to our `/api/auth/callback` route with a temporary `code`.

In the callback, we exchange this `code` for an `access_token`. We then store this `access_token` in an `httpOnly` cookie for secure storage.

## Step 4: Fetching and Displaying Oura Data

Now that we are authenticated, we can fetch the user's data and display it on a dashboard page.

### What we're doing

We'll create a new page at `pages/dashboard.js` that will fetch the Oura data on the server-side using `getServerSideProps` and then pass it to the page component to be rendered. We'll also install the `recharts` library for our charts.

### Implementation

First, install `recharts`:

```bash
npm install recharts
Code collapsed

Now, create the pages/dashboard.js file:

code
// pages/dashboard.js
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';

export default function Dashboard({ sleepData, readinessData, activityData }) {
  return (
    <div>
      <h1>Your Oura Wellness Dashboard</h1>
      <div style={{ width: '100%', height: 300 }}>
        <h2>Sleep Score</h2>
        <ResponsiveContainer>
          <BarChart data={sleepData}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="day" />
            <YAxis />
            <Tooltip />
            <Legend />
            <Bar dataKey="score" fill="#8884d8" />
          </BarChart>
        </ResponsiveContainer>
      </div>
      {/* Add similar charts for readiness and activity data */}
    </div>
  );
}

export async function getServerSideProps(context) {
  const { oura_token } = context.req.cookies;

  if (!oura_token) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    };
  }

  const [sleepResponse, readinessResponse, activityResponse] = await Promise.all([
    fetch('https://api.ouraring.com/v2/usercollection/daily_sleep', {
      headers: {
        'Authorization': `Bearer ${oura_token}`,
      },
    }),
    // ... similar fetch calls for readiness and activity
  ]);

  const sleepJson = await sleepResponse.json();
  // ... similar json parsing for readiness and activity

  return {
    props: {
      sleepData: sleepJson.data,
      // ... readinessData and activityData
    },
  };
}
Code collapsed

Finally, let's create a simple home page at pages/index.js with a login button:

code
// pages/index.js
export default function Home() {
  return (
    <div>
      <h1>Welcome to your Wellness Dashboard</h1>
      <a href="/api/auth/login">Login with Oura</a>
    </div>
  );
}
Code collapsed

How it works

In getServerSideProps, we access the oura_token from the cookies. If it doesn't exist, we redirect the user to the homepage to log in. If it does exist, we use it in the Authorization header to make requests to the Oura API endpoints for sleep, readiness, and activity data. This data is then passed as props to our Dashboard component, which uses Recharts to create a simple bar chart.

Putting It All Together

With all the pieces in place, you can now run your application:

code
npm run dev
Code collapsed

Navigate to http://localhost:3000. You should see the login button. Clicking it will take you through the Oura authentication flow, and you'll be redirected to your dashboard with your sleep data visualized!

Security Best Practices

  • HttpOnly Cookies: We store the access token in an httpOnly cookie, which means it cannot be accessed by client-side JavaScript. This helps to mitigate XSS attacks.
  • Server-Side Data Fetching: By fetching the data in getServerSideProps, our access token is never exposed to the client's browser.

Conclusion

You've now successfully built a Next.js application that can authenticate with the Oura Ring API, fetch user data, and visualize it in a wellness dashboard. This project serves as a great foundation for building more complex and personalized health and wellness applications.

Resources

#

Article Tags

react
api
wearables
nextjs
datavisualization
healthtech
W

WellAlly's core development team, comprised of healthcare professionals, software engineers, and UX designers committed to revolutionizing digital health management.

Expertise

Healthcare Technology
Software Development
User Experience
AI & Machine Learning

Found this article helpful?

Try KangXinBan and start your health management journey