Skip to content

Get started

Ship a working SweatStack app in about 15 minutes. The walkthrough is framework-agnostic. Pick your stack at each code block, and your selection carries through the rest of the page.

Info

Just want to query your own data in Python? See the Python client docs instead.

1. Create your SweatStack account

Sign up at app.sweatstack.no/register. Free, no credit card required.

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

uv add 'sweatstack[fastapi]'

Generate a Fernet key for encrypting cookies:

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

Pick the framework you (or your AI coding agent) prefer. SweatStack uses standard OAuth2 and HTTPS, so any HTTP client and any OAuth2 library will do. Install whatever you'd normally reach for.

4. Build it

Create app.py:

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

configure(
    client_id="your-client-id",
    client_secret="your-client-secret",
    session_secret="your-fernet-key",
    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, authenticate with SweatStack, and you're back with a working API call.

Create app.py:

import streamlit as st
from sweatstack.streamlit import StreamlitAuth

auth = StreamlitAuth(
    client_id="your-client-id",
    client_secret="your-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, log in via the sidebar, and you'll see your latest activities.

SweatStack speaks OAuth2 authorization-code flow. The full reference is on the OAuth2 & OpenID Connect page. The minimum dance:

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 back 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"

Step C. Call the API with the token.

curl https://app.sweatstack.no/api/v1/activities/latest \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

For OpenID Connect discovery, JWKS, and the full endpoint reference, see OAuth2 & OpenID Connect.

What's next

  • SweatStack Connect: the productized "Continue with SweatStack" button. Drop-in onboarding so your users don't need a SweatStack signup first.
  • Webhooks: subscribe to real-time events when activities or tests change.
  • The catalog: what's queryable: activities, dailies, tests, metabolic profile, app metadata.
  • SweatStack Pages: host your app's static frontend without standing up infrastructure.
  • Pricing: free for community apps, paid plans for going commercial.