Skip to main content
Edpire’s REST API and embed token system are designed to work with any platform, including mobile apps that cannot run the JavaScript SDK directly.

How it works

Mobile integration follows a two-part architecture: Your API key never leaves your server. The mobile app only ever sees a short-lived embed token.
You do not register an origin for a native app. The Allowed Embed Origins list exists to constrain browsers, and a WebView loading an inline HTML string has no origin to send. Requests that arrive without an Origin header are accepted on that basis, and the embed token — signed, scoped to one organization, assessment and learner, and valid for 2 hours — is what authorizes them.Register origins only for the web player, where a real browser origin exists. Ionic and Capacitor are the exception: they serve your app from a real origin (capacitor://localhost, ionic://localhost or an https:// host), so that origin does need to be registered.

The WebView HTML template

This is the universal mobile player. Load it in any WebView with the embed token injected:
Serve this HTML from your own backend (or build it as a string in your app) with {{EMBED_TOKEN}} replaced server-side.
Never embed your API key in the WebView HTML. The embed token is short-lived (2 hours), consumed on submit, and scoped to a single learner and assessment — it is safe to put in client code.

Drag-and-drop needs a short press-and-hold

On a touch screen, drag-and-drop questions start after the learner holds the item still for about 120 ms. A tap-and-flick does not pick it up. This is deliberate. A finger landing on a draggable word is ambiguous: it could be the start of a drag, or the start of a scroll. Without the hold, every attempt to scroll the page that happened to begin on a word would drag the word instead, and a long assessment would be close to unscrollable. Holding still resolves the ambiguity. For comparison, dnd-kit defaults to 250 ms, and both Android and iOS use roughly 500 ms for their own system drag gestures, so Edpire is on the fast end. With a mouse there is no delay at all, just an 8 px movement threshold, because a mouse has no scrolling ambiguity to resolve.
This catches automated tests more often than it catches learners. Synthetic gestures (adb shell input swipe, input draganddrop, Appium’s default swipe) usually begin moving immediately, never satisfy the hold, and report drag-and-drop as broken when it is not. If you are scripting a drag, emit a touch-down, wait at least 150 ms without moving, then emit incremental moves.

React Native

React Native apps can use EdpireClient directly for server-side operations — it uses fetch, which is available natively in React Native. For the player, open a WebView with the HTML template. Server-side (your Node.js backend):
React Native app:

Flutter

Flutter apps call your backend via http or dio to fetch the embed token, then load the player HTML in a WebView. Mint the token from your backend (Dart HTTP call):
Load the player in a WebView (using flutter_inappwebview):

Native iOS / Android

The same HTML template works in any native WebView:
  • iOS: WKWebView — use loadHTMLString(_:baseURL:) and receive messages via WKScriptMessageHandler
  • Android: WebView — use loadDataWithBaseURL() and receive messages via addJavascriptInterface
The pattern is identical in both cases: your backend mints the token, the native code builds the HTML string with the token injected, and the result comes back via the WebView message bridge.

Platform comparison

Ionic and Capacitor apps run in a WebView already. You can use the full @edpire/sdk npm package directly — no need for the HTML template approach.