Skip to content

Build an app

Ship an app that lets other people sign in with SweatStack and queries the API on their behalf. About fifteen minutes for the framework paths. Pick your stack at the first code block and the choice carries through.

Using an AI coding agent?

Install the SweatStack agent skill, then paste this prompt:

Build a FastAPI app that lets users sign in with SweatStack and shows their last ten activities. Use the sweatstack[fastapi] package and the sweatstack.fastapi helpers (configure, instrument, AuthenticatedUser, OptionalUser, urls). Read SWEATSTACK_CLIENT_ID, SWEATSTACK_CLIENT_SECRET, and SWEATSTACK_SESSION_SECRET from environment variables. Set the redirect URI to http://localhost:8000/auth/sweatstack/callback. Follow https://docs.sweatstack.no/getting-started/build/.

Swap FastAPI for Streamlit if that's your stack. The agent skill knows the rest.

1. Sign up

Skip if you already have an account. Otherwise: app.sweatstack.no/register. Free, no credit card.

2. Register an app

Go to app.sweatstack.no/applications/new, name your app, and set the redirect URI to:

http://localhost:8000/auth/sweatstack/callback
http://localhost:8501

Whatever URL in your app handles the OAuth2 callback, e.g. http://localhost:3000/auth/callback.

Save the resulting client_id and client_secret. Treat the secret like a password.

3. Install and configure

uv add 'sweatstack[fastapi]'

Put your credentials in a .env file (or your shell):

SWEATSTACK_CLIENT_ID="..."
SWEATSTACK_CLIENT_SECRET="..."
SWEATSTACK_SESSION_SECRET="..."  # see below

Generate a SWEATSTACK_SESSION_SECRET once, used to encrypt the session payload stored in the user's cookie:

uv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
uv add 'sweatstack[streamlit]'

Put your credentials in a .env file (or your shell):

SWEATSTACK_CLIENT_ID="..."
SWEATSTACK_CLIENT_SECRET="..."

Pick the HTTP and OAuth2 libraries you (or your AI coding agent) prefer. SweatStack uses standard OAuth2 over HTTPS, so anything that speaks the spec works. Put your client_id, client_secret, and redirect URI in environment variables.

4. Build it

Create app.py:

import os

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from sweatstack.fastapi import (
    configure, instrument, AuthenticatedUser, OptionalUser, urls,
)

configure(
    client_id=os.environ["SWEATSTACK_CLIENT_ID"],
    client_secret=os.environ["SWEATSTACK_CLIENT_SECRET"],
    session_secret=os.environ["SWEATSTACK_SESSION_SECRET"],
    app_url="http://localhost:8000",
)

app = FastAPI()
instrument(app)


@app.get("/")
def home(user: OptionalUser):
    if user:
        return HTMLResponse(
            f"Welcome, {user.user_id}! "
            f"<a href='/activities'>My activities</a>"
        )
    return HTMLResponse(f"<a href='{urls.login()}'>Login with SweatStack</a>")


@app.get("/activities")
def activities(user: AuthenticatedUser):
    return user.client.get_activities(limit=10)

Run it:

uv run fastapi dev app.py

Open http://localhost:8000, click Login with SweatStack, authorize the app, and you're redirected back signed in. Click My activities and you see your last ten activities returned as JSON.

Create app.py:

import os

import streamlit as st
from sweatstack.streamlit import StreamlitAuth

auth = StreamlitAuth(
    client_id=os.environ["SWEATSTACK_CLIENT_ID"],
    client_secret=os.environ["SWEATSTACK_CLIENT_SECRET"],
    redirect_uri="http://localhost:8501",
)

with st.sidebar:
    auth.authenticate()

if not auth.is_authenticated():
    st.write("Please log in to continue.")
    st.stop()

st.write("Welcome to SweatStack.")
activities = auth.client.get_activities(limit=10)
st.dataframe(activities)

Run it:

uv run streamlit run app.py

Open http://localhost:8501, click login in the sidebar, authorize the app, and your last ten activities render in a dataframe.

SweatStack speaks OAuth2 authorization-code flow. Three calls get you a working integration. See OAuth2 & OpenID Connect for PKCE (recommended for SPAs and mobile), refresh tokens, scope reference, and OIDC discovery.

Step A. Send the user to the authorize endpoint.

https://app.sweatstack.no/oauth/authorize
    ?response_type=code
    &client_id=YOUR_CLIENT_ID
    &redirect_uri=YOUR_REDIRECT_URI
    &scope=data:read

The user authenticates and is redirected to your redirect_uri with a ?code=... query parameter.

Step B. Exchange the code for an access token.

curl -X POST https://app.sweatstack.no/oauth/token \
  -d "grant_type=authorization_code" \
  -d "code=THE_CODE" \
  -d "redirect_uri=YOUR_REDIRECT_URI" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"
const res = await fetch("https://app.sweatstack.no/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "authorization_code",
    code: THE_CODE,
    redirect_uri: YOUR_REDIRECT_URI,
    client_id: YOUR_CLIENT_ID,
    client_secret: YOUR_CLIENT_SECRET,
  }),
});
const { access_token } = await res.json();

Step C. Call the API with the token.

curl https://app.sweatstack.no/api/v1/activities/latest \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
const res = await fetch(
  "https://app.sweatstack.no/api/v1/activities/latest",
  { headers: { Authorization: `Bearer ${accessToken}` } },
);
const activity = await res.json();

You get back the user's most recent activity as JSON.

What's next

You have authentication and a working API call. The next steps depend on what you're building.

  • Browse every endpoint. The API reference covers every route, parameter, and response schema. Run requests live against your account in the API playground.
  • Add real features. See Activities, Dailies, Tests, and Metabolic profile.
  • Drop the SweatStack signup requirement. SweatStack Connect lets users authenticate with the wearable account they already have.
  • React to data changes. Webhooks fire when activities or tests are created, updated, or deleted.
  • Store per-user state without a database. App metadata lets you attach JSON to activities, traces, tests, and users.
  • Skip running infrastructure. SweatStack Pages hosts your app's static frontend.
  • Go commercial. Pricing. Free for community apps.