Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.flexslot.gg/llms.txt

Use this file to discover all available pages before exploring further.

Ten minutes from now you’ll have an access token in your terminal and you’ll have called the Flexslot API with it. We’ll use 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/callback and run a one-line Python listener.

Step 1 — Register your client

1

Open the partner admin

Sign in at flexslot.gg and open Settings → Partner Apps → New Application.
2

Fill in the application

  • Name: Quickstart Test (whatever you like)
  • Application type: Public (no client secret) for a CLI/native app, or Confidential for a server app
  • Redirect URIs: http://localhost:8765/callback
  • Allowed scopes: check decks:read for now
3

Save the client_id

You’ll see a client_id like cli_01HX2K…. If you chose Confidential, you also get a client_secret shown once — copy it now.
Confidential client secrets are shown exactly once at creation time. If you lose it, rotate the secret from the admin — there’s no way to retrieve the original value.

Step 2 — Generate PKCE values

PKCE binds the authorization code to your client. Every authorization request needs a freshly generated code_verifier and code_challenge.
# Generate a random 32-byte code_verifier (43 chars base64url, no padding)
VERIFIER=$(openssl rand 32 | base64 | tr '+/' '-_' | tr -d '=\n')

# Derive the SHA-256 challenge
CHALLENGE=$(printf '%s' "$VERIFIER" | openssl dgst -sha256 -binary \
  | base64 | tr '+/' '-_' | tr -d '=\n')

echo "verifier=$VERIFIER"
echo "challenge=$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. Replace CLIENT_ID and use the CHALLENGE you just generated.
STATE=$(openssl rand -hex 16)

open "https://api.flexslot.gg/api/public/v1/oauth/authorize?\
response_type=code&\
client_id=CLIENT_ID&\
redirect_uri=http://localhost:8765/callback&\
scope=decks:read&\
state=$STATE&\
code_challenge=$CHALLENGE&\
code_challenge_method=S256"
You’ll see the Flexslot consent screen. Click Allow and your browser will be redirected to 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:
python3 -c "
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
class H(BaseHTTPRequestHandler):
    def do_GET(s):
        q = parse_qs(urlparse(s.path).query)
        print('CODE=', q.get('code', [''])[0])
        print('STATE=', q.get('state', [''])[0])
        print('ISS=', q.get('iss', [''])[0])
        s.send_response(200); s.end_headers()
        s.wfile.write(b'You can close this tab.')
HTTPServer(('localhost', 8765), H).serve_forever()
"
After approving, your terminal prints the code. Validate that 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

CODE=<paste-the-code-from-step-4>

# For a Confidential client (with secret):
curl -sS -X POST https://api.flexslot.gg/api/public/v1/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d "grant_type=authorization_code" \
  -d "code=$CODE" \
  -d "redirect_uri=http://localhost:8765/callback" \
  -d "code_verifier=$VERIFIER"

# For a Public client (no secret):
curl -sS -X POST https://api.flexslot.gg/api/public/v1/oauth/token \
  -d "grant_type=authorization_code" \
  -d "client_id=$CLIENT_ID" \
  -d "code=$CODE" \
  -d "redirect_uri=http://localhost:8765/callback" \
  -d "code_verifier=$VERIFIER"
You’ll get back something like:
{
  "access_token": "fst_at_01HX2K6F8N9PRSTUVWXYZA…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "fst_rt_01HX2K6F8N9PRSTUVWXYZB…",
  "scope": "decks:read"
}

Step 6 — Call the API

ACCESS_TOKEN=<paste-the-access_token>

curl -sS https://api.flexslot.gg/api/public/v1/decks/ \
  -H "Authorization: Bearer $ACCESS_TOKEN"
You should see a paginated list of the user’s decks. Congratulations, you have a working OAuth integration.

What you just did

1

Registered a client

The partner admin gave you a client_id (and optionally a client_secret) that identifies your app.
2

Generated PKCE

The code_verifier proves your app is the same app that initiated the flow, even if someone intercepts the code.
3

Got user consent

The user saw exactly which scopes you requested and clicked Allow.
4

Validated the response

You checked state (CSRF defense) and iss (mix-up defense, RFC 9207).
5

Exchanged code for tokens

The token endpoint verified the code_verifier and returned access + refresh tokens.
6

Called the API

A Bearer token in the Authorization header is all the API needs.

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
This quickstart used a public client (no secret) to keep things simple. For a server-side app, choose Confidential in step 1 and send the client_secret via HTTP Basic auth as shown in step 5.