curl plus a tiny shell snippet so you can see exactly what’s happening on the wire.
Prerequisites
- A Flexslot account (sign up if you don’t have one)
openssl,curl, and a Unix shell- A redirect URI you control. For this guide we’ll use
http://localhost:8765/callbackand run a one-line Python listener.
Step 1 — Register your client
Open the partner admin
Sign in at flexslot.gg and open Account → API access (the canonical link is flexslot.gg/account?section=api-access; the
/settings URL redirects to /account). In the OAuth applications card, click New application.Fill in the application
- Name:
Quickstart Test(whatever you like) - Application type:
Public(no client secret) for a CLI/native app, orConfidentialfor a server app - Redirect URIs:
http://localhost:8765/callback - Allowed scopes: check
decks:readfor now
Step 2 — Generate PKCE values
PKCE binds the authorization code to your client. Every authorization request needs a freshly generatedcode_verifier and code_challenge.
Keep the
verifier somewhere your callback handler can read it. We’ll need it in step 4. The challenge goes on the wire; the verifier stays secret in your app.Step 3 — Send the user to /authorize
Open this URL in your browser. ReplaceCLIENT_ID and use the CHALLENGE you just generated.
http://localhost:8765/callback?code=...&state=...&iss=https://api.flexslot.gg.
Step 4 — Capture the code with a one-line listener
Run this in a second terminal before you click Allow:state matches the value you sent, and that iss equals https://api.flexslot.gg. If either check fails, stop — that’s an attack signal, not an error.
Step 5 — Exchange the code for tokens
Step 6 — Call the API
Step 7 — Identify the connected user
To render “Connected as: …” in your UI, call the user probe with the same access token. It returns the bare Firebase id and the user’s Flexslot handle:user.id is the bare Firebase id and is identical to author.id on that user’s public decks — use it to correlate the connected account with the deck data you fetch. user.username is the same handle shown on the consent screen. No extra scope (no profile/email) is required: identity here is exactly what the user already saw and approved at consent. The user’s email is intentionally not returned — it isn’t consistently shown at consent, so it would be undisclosed PII for a partner that only requested resource scopes. caller is an opaque composite principal — stable for rate-limiting and audit, but not meant for display.What you just did
Registered a client
The partner admin gave you a
client_id (and optionally a client_secret) that identifies your app.Generated PKCE
The
code_verifier proves your app is the same app that initiated the flow, even if someone intercepts the code.Validated the response
You checked
state (CSRF defense) and iss (mix-up defense, RFC 9207).Exchanged code for tokens
The token endpoint verified the
code_verifier and returned access + refresh tokens.Next steps
Code samples
Production-ready Express and Flask implementations
Authorization Code Flow
The full flow with a sequence diagram
Refresh tokens
How to keep the user logged in
Scopes
Request additional permissions