Skip to main content
This page shows you how to connect a user account to Mio, store tokens safely, and bring personalized Mio Context into your product. You will need Mio dashboard access, a redirect URL, Node.js 18+, and a server environment (Next.js route handler, Express API, etc.).

OAuth & token flow at a glance

  1. User clicks Connect with Mio and gets redirected to the Mio connection flow.
  2. Mio redirects back to your redirectUrl with a short-lived authorization code.
  3. The browser posts that code to your backend exchange endpoint.
  4. The backend calls mio.exchangeCodeForTokens(code), stores the refreshToken, and returns the accessToken to the browser.
  5. You call getContextSummary (or getContext) with the access token.
  6. When the access token expires (after 24 hours), the backend calls mio.refreshTokens(refreshToken) to mint a new one without asking the user to reconnect.

Ship a working flow in six steps

1

Register your app

Visit the Mio dashboard, create an OAuth client, and copy the clientId, clientSecret, and redirect URL you intend to use locally. You need these values before any code changes.
2

Use @mio-xyz/sdk as a project dependency

npm install @mio-xyz/sdk
3

Configure environment variables

Provide Mio credentials on both the browser and the server. Prefix client-side values with NEXT_PUBLIC_ (or your framework equivalent).
Never expose your Mio client secret environment variable to the browser. Keep it next to the server-side Mio instance so tokens are exchanged safely.
4

Initialize Mio in your frontend

Initialize Mio once in your frontend so you can trigger the connection flow and later fetch Mio Context.
  • React
  • Vanilla HTML + JavaScript
app/providers.tsx
'use client';

import type { ReactNode } from 'react';
import { MioProvider } from '@mio-xyz/sdk/react';

const mioConfig = {
  clientId: process.env.NEXT_PUBLIC_MIO_CLIENT_ID!,
  redirectUrl: `${process.env.NEXT_PUBLIC_APP_URL}/api/mio/callback`,
  exchangeTokenUrl: '/api/exchange-token'
};

export function Providers({ children }: { children: ReactNode }) {
  return <MioProvider config={mioConfig}>{children}</MioProvider>;
}
In React, MioProvider memoizes the underlying SDK. In non-React apps, keep the Mio.init call in a shared module so you reuse the same instance everywhere.
5

Create the token exchange endpoint

Your frontend can never store the Mio client secret, so spin up a backend endpoint that trades authorization codes for tokens and hands the short-lived accessToken back to the browser.

What is the exchange token endpoint for?

It is the bridge between the redirect and your stored tokens:
  • The browser posts the code it received from Mio to this endpoint.
  • The backend calls mio.exchangeCodeForTokens(code) with your secret credentials.
  • You store the refreshToken securely, send the accessToken (or a session identifier) back to the browser, and use it to call Mio Context.
  • Next.js route handler
  • Express endpoint
app/api/exchange-token/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { Mio } from '@mio-xyz/sdk/server';

const mio = Mio.init({
  clientId: process.env.MIO_CLIENT_ID!,
  redirectUrl: process.env.MIO_REDIRECT_URL!,
  clientSecret: process.env.MIO_CLIENT_SECRET!
});

export async function POST(request: NextRequest) {
  const { code } = await request.json();
  const tokens = await mio.exchangeCodeForTokens(code);

  // Persist refreshToken before returning it to the client
  // await saveTokensForUser(userId, tokens);

  return NextResponse.json(tokens);
}
Store refreshToken alongside your user record so you can call mio.refreshTokens later without asking the user to reconnect.
Access tokens last 24 hours. Keep refresh tokens on the server and schedule mio.refreshTokens(refreshToken) so you always return a valid access token to the client.
Ensure the redirect URL in your code matches the dashboard configuration exactly; otherwise the exchange fails with invalid_grant.
6

Fetch Mio Context & personalize your experience

Once you have an access token, call getContextSummary to pull ready-to-use context. The React example below uses useMio; adapt the same pattern for other frameworks or use getContext when you need a custom prompt.
  • React
  • Vanilla HTML + JavaScript
app/page.tsx
'use client';

import { useState } from 'react';
import { useMio } from '@mio-xyz/sdk/react';

export default function HomePage() {
  const { connect, handleMioCallback, getContextSummary, isLoading, error } = useMio();
  const [accessToken, setAccessToken] = useState<string | null>(null);
  const [answer, setAnswer] = useState<string | null>(null);

  async function handleConnect() {
    if (!accessToken) {
      await connect();
    }
  }

  async function completeCallback() {
    const tokens = await handleMioCallback();
    setAccessToken(tokens.accessToken);
  }

  async function loadSummary() {
    if (!accessToken) {
      throw new Error('Connect first so we can get an access token');
    }
    const summary = await getContextSummary({ accessToken });
    setAnswer(summary ?? 'No summary returned');
  }

  return (
    <section>
      <button onClick={handleConnect} disabled={isLoading}>
        {isLoading ? 'Connecting…' : 'Connect with Mio'}
      </button>
      <button onClick={completeCallback}>Handle callback</button>
      <button onClick={loadSummary}>Load user summary</button>
      {error ? <p>{error}</p> : null}
      {answer ? <pre>{answer}</pre> : null}
    </section>
  );
}
connect() triggers a full redirect, so avoid calling it inside effects or long chains of updates. Keep it in event handlers.
Run through the full flow, call handleMioCallback, and confirm getContextSummary logs personalized content in the console.

What just happened

  • You registered a Mio OAuth client and installed the SDK.
  • You configured environment variables and stood up a secure token exchange route.
  • You wrapped your React tree with MioProvider, handled the callback, and called both getContext and getContextSummary using a real access token.

Keep building