Skip to content

Sandbox Certification

Certification is the gate between sandbox and production: you demonstrate the five scenarios below against the sandbox, submit your evidence, and FSRI reviews it before issuing production credentials. It exists to protect both sides — a partner who passes certification won't discover auth, isolation, or completion bugs in front of live learners.

Prerequisites: a completed sandbox integration (you can run the Quick Start end-to-end), and your technical contact registered with FSRI.

How Certification Works

  1. Build against sandbox until the five scenarios below all pass in your integration.
  2. Record evidence as you run each scenario — request/response logs with credentials redacted, or a screen recording of your test suite.
  3. Submit the evidence bundle to your FSRI integration contact.
  4. FSRI reviews — verifying your API interactions server-side against our logs, not just your submission.
  5. Outcome: pass → production credentials issued; gaps → you get a specific list to fix and resubmit. Partial passes carry over; only failed scenarios are re-reviewed.

Timeline

Review typically completes within 5 business days of submission; resubmissions within 3. Plan certification at least two weeks before your target production date to absorb a fix cycle.

Scenario 1 — Authentication

Proves: you handle the full credential lifecycle correctly.

# Demonstrate Pass criteria
1.1 Obtain a token via client_credentials 200 from the token endpoint; JWT with scope containing partner-api/read partner-api/write
1.2 Scope verification Decoded token's scope matches what you requested; an authenticated call succeeds with it
1.3 Token refresh behavior Your integration re-mints before/at expiry without minting per-request (logs showing one token reused across calls, then a refresh)
1.4 Dual-credential handling A request without x-api-key fails 403; with both headers it succeeds

Fail examples: minting a token for every call · retrying 401 in an infinite loop · API key present on some requests but not others.

Scenario 2 — User Registration & Lifecycle

Proves: learner identity management is correct, including the privacy paths.

# Demonstrate Pass criteria
2.1 Register a new user 201 with UUID; UUID persisted on your side
2.2 Duplicate registration Registering the same email again returns the same user — no duplicate local records
2.3 Profile update PATCH with application/merge-patch+json changes only the sent fields
2.4 Deactivate + reactivate status: inactive → user-scoped calls rejected → status: active restores them

Fail examples: treating a duplicate registration as an error state · PATCH with application/json worked around by re-sending whole profiles.

Scenario 3 — Content Access

Proves: catalog consumption and the content-delivery model work end to end.

# Demonstrate Pass criteria
3.1 Catalog listing Organizations, categories, and courses listed with correct pagination handling
3.2 Module access GET /modules/{id}/content with a registered UUID returns a content URL; content renders in your embed
3.3 Progress auto-creation After 3.2, GET /course-progresses shows the auto-created in_progress record — without you creating anything
3.4 URL expiry handling Show how your player handles expires_at (refresh-url during playback, or a documented click-time-fetch policy)

Fail examples: persisted/cached content URLs · hardcoded module IDs that break after a sandbox refresh.

Scenario 4 — Progress & Transcripts

Proves: you read the learning record correctly and deliver credentials.

# Demonstrate Pass criteria
4.1 Progress query GET /course-progresses displayed/consumed for a user with activity; delta-sync used for scheduled polling
4.2 Completion reporting Video/document module: your "Mark as Complete" calls POST /modules/{id}/complete202; repeat call → 202 with no error surfaced to the learner
4.3 Transcript PDF GET /transcript/pdf retrieved and served as a valid PDF
4.4 Certificate PDF For a transcript with certificateAvailable: true: certificate retrieved via GET /transcripts/{id}/certificate/pdf

Fail examples: calling /complete for SCORM modules · writing progress state locally and letting it drift from the API's record.

Scenario 5 — Error Handling

Proves: your integration degrades safely instead of amplifying failures.

# Demonstrate Pass criteria
5.1 401 handling Induce one (expired/garbage token): your client refreshes and retries once, then surfaces the failure — no retry storm
5.2 404 handling A nonexistent/foreign UUID is handled as "not found" without retries
5.3 429 handling Demonstrate exponential backoff (test-harness simulation acceptable if sandbox limits are impractical to hit)
5.4 Validation errors A 400 with violations[] maps to actionable feedback in your system, not a generic crash

Fail examples: unbounded retry loops on any 4xx · credentials appearing in logged error output.

Evidence Format

For each numbered item, capture: timestamp (with timezone) · request (method, URL, headers minus secrets, body) · response (status + body; PDFs by filename/size). A structured log export or annotated Postman Collection Runner results both work.

Redact your credentials

Redact Authorization, x-api-key, and all secrets everywhere. Submissions containing live credentials are failed on the spot and the credentials rotated.

After Certification

  • Production credentials are issued over the same secure channel as sandbox's.
  • Go-live is coordinated with your FSRI contact — see the Go-Live Runbook (partner area).
  • Re-certification is only required for material integration changes (new endpoints consumed, auth handling rewritten) — routine feature work on your side doesn't need it.