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):
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 uuid — persist 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).