Skip to content

Sandbox Quick Start

Goal: your first successful API call in under 5 minutes. Everything below is copy-paste ready.

Your credentials (fills every code sample on this site)

Stored only in this browser. Your client secret is deliberately never asked for here — keep it in your secret manager and substitute it in your terminal.

1. Get credentials  →  2. Get a token  →  3. First API call  →  4. Register a test user  →  5. Build
   (from FSRI)           (curl, ~5s)         (/ping, /courses)     (POST → UUID)                (full docs)

1. Get Your Credentials

FSRI issued you three sandbox values during onboarding, delivered over a secure channel:

export CLIENT_ID='{{clientId}}'          # 26-char alphanumeric
export CLIENT_SECRET='{{clientSecret}}'  # long random string — from your secret manager
export API_KEY='{{apiKey}}'              # ~40-char string

# Fixed sandbox endpoints:
export TOKEN_URL='https://fsri-partner-api-sandbox-357795418386.auth.us-west-2.amazoncognito.com/oauth2/token'
export BASE_URL='https://sandbox.lms.api.fsri.org/api/partner/v1'

Tip

Prefix the export lines with a space (with HISTCONTROL=ignorespace) to keep secrets out of shell history.

Missing credentials? Contact your FSRI integration contact — there is no self-service signup.

2. Get an Access Token

export ACCESS_TOKEN=$(curl -s -X POST "$TOKEN_URL" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&scope=partner-api/read partner-api/write" \
  | jq -r .access_token)

echo "${ACCESS_TOKEN:0:20}..."   # should print the start of a JWT: eyJraWQ...

Tokens last 1 hour. Got null? Your Client ID/Secret is wrong — and make sure you didn't use the API key here; it's a different credential.

3. First API Call

Ping — proves connectivity and your API key (no token needed, by design):

curl -s -w "\nHTTP %{http_code}\n" -H "x-api-key: $API_KEY" "$BASE_URL/ping"

Expect HTTP 200 with "status": "healthy".

Courses — proves the whole auth chain (token + key together):

curl -s -w "\nHTTP %{http_code}\n" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $API_KEY" \
  "$BASE_URL/courses?page=1&itemsPerPage=3"

Expect HTTP 200 and JSON containing real course data. 🎉 That's your first API call.

A passing /ping doesn't prove your token

/ping deliberately skips JWT authentication so you can test connectivity in isolation. /courses returning 200 is the real green light. (401 → token problem · 403 with empty body → API key problem · full decision table in Error Handling.)

4. Register a Test User

Learners in your LMS get an FSRI identity (a UUID) via one registration call:

curl -s -X POST "$BASE_URL/users/register" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "quickstart-test@yourcompany.example",
    "firstName": "Quick",
    "lastName": "Start"
  }' | jq '{uuid, email, status}'

Expect 201 with a uuidpersist that UUID; it's the learner's identity in every user-scoped call (sent as the X-User-ID header). Registration is idempotent: same email → same user back, so re-running is safe.

Try a user-scoped call with it:

export USER_UUID='(uuid from above)'
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" -H "x-api-key: $API_KEY" \
  -H "X-User-ID: $USER_UUID" \
  "$BASE_URL/course-progresses" | jq '."hydra:totalItems"'

5. Next Steps

Next Where
Understand the full integration flow Workflows
Every endpoint's contract API Reference + interactive docs
Skip the curl — ready-made clients PHP / JavaScript / Python
Explore in a GUI Postman collection (token handling automated)
Something's failing Error Handling · FAQ
Get certified for production Sandbox Certification

Two sandbox facts worth knowing now

Sandbox content refreshes from production monthly — don't hardcode IDs; discover them from list endpoints. And your token expires hourly — cache it and re-mint proactively (the example clients already do).