Why a server endpoint? You cannot call Edpire directly from the browser: your API key would sit in the JavaScript bundle for anyone to read. The token endpoint lets your server verify the learner from your own session, mint a short-lived single-use token, and send only that to the browser.
Step 1. Mint tokens on your server
Every integration needs this, whatever your frontend is.- Next.js App Router
- Express / Vite dev server
- Any other runtime
The token expires after 2 hours and is consumed when the learner submits. Mint a fresh one each time the learner opens the assessment. Minting does not invalidate a token already in use, so a learner with the assessment open in another tab is unaffected.
Step 2. Mount the player
- React
- Vue, Svelte, Angular, plain JS
- Script tag, no build step
<EdpireAssessmentPlayer> handles token fetching, mounting, unmounting and StrictMode double-invoke cleanup for you.React version support
Container sizing
The player fills its container, so you are responsible for sizing it. A container with no explicit height, or one constrained by centering utilities, collapses to zero and hides the player.Allowed origins
The embed player is origin-scoped: it only loads from domains you explicitly allow. A blank player, orORIGIN_NOT_ALLOWED in onError, almost always means this list.
- Go to edpire.com → Integrations → Security → Allowed Embed Origins
- Add every origin your app runs on, including staging and local development:
http://localhost:3000(Next.js dev)http://localhost:5173(Vite dev)https://yourapp.com(production)
- Save and reload
capacitor://localhost. Both are handled, so there is nothing to register for mobile.
Reference
EdpireAssessmentPlayerProps (React)
MountOptions (imperative)
Everything above applies, minus the React-only props. mount() takes the token directly rather than a tokenEndpoint.
mediaHandler
Required only if your assessment contains OpenResponse questions with file-upload or audio/video recording. Without it, those question types silently fail to submit.
upload receives (file, type) and must resolve to { url, mimeType? }. There is no progress callback. If you want a progress bar, track it in your own upload code and render it outside the player.EmbedInstance
onComplete: the SDK defers the actual React unmount so it never fires mid-render.
EmbedResult
Passed to onComplete. Note the fields are snake_case, mirroring the API response.
If
awaiting_manual_grading is true, the visible score is provisional: open-response answers still need a teacher. Listen for the submission.grading.completed webhook for the final score.EmbedError
Advanced: bring your own data with AssessmentShell
EdpireAssessmentPlayer fetches the assessment client-side after mount and handles everything. Drop down to AssessmentShell only when you need to control data loading yourself: server-rendering the assessment for a faster first paint, pre-fetching before the learner navigates, or plugging into your own caching layer.
AssessmentShell expects data in the runtime shape (AssessmentContent), not the raw REST Assessment. That conversion is yours.
onSubmit grades the attempt and returns a SubmitResult. Note that client.submit() returns GradeResult in snake_case while the shell expects SubmitResult in camelCase, so map between them on the server:
client.submit() returns per-question scores (exercise_results) but not the per-node visual feedback (exerciseFeedback) the shell uses to highlight answers inline. If you need both, use the Embedded Player above, which gets the full response automatically.AssessmentShellProps
exerciseFeedback drives the inline per-question feedback. See the type catalog for ExerciseFeedbackData, QuestionFeedback and NodeFeedback.
Next steps
Custom Flow
Question-by-question instead, with your own UI around it.
Webhooks
Receive results server-side, which you want as the primary path.
Mobile and WebView
The same player in React Native, Flutter or native.
Troubleshooting
Blank player, token errors, styles behaving oddly.