On this page

Embed sandbox in an iframe

~8 min Python TypeScript

Goal: Embed a live MIOSA sandbox in your product’s UI without exposing your msk_* key. Your server mints a short-lived preview token; your frontend drops it into an <iframe src>.

What you’ll use: Sandboxes, Preview tokens

How preview tokens work

Browser ──── GET /my-api/preview-token ────► Your server
                                                │
                                          sbx.previewToken(3600)
                                                │
Your server ◄─── { url, expires_at } ──── MIOSA API
     │
     └── token embedded in https://<slug>.miosa.app?mp_...

The URL returned by previewToken is:

https://<sandbox-slug>.miosa.app?mp=<base64url-token>

It is safe to put in an iframe src attribute. It does not contain your API key. When the token expires the sandbox is still alive - you mint a new token and update the src.

Step 1 - Server-side: mint the token

Your backend verifies ownership, then calls previewToken. Return the URL to the frontend.

Step 2 - Frontend: embed the iframe

Fetch the token from your server and use the URL as the src. Set up a refresh timer to re-mint before expiry.

Token refresh strategy

ScenarioRecommendation
Short session (under 1 h)Mint once with expires_in=3600. No refresh needed.
Long sessionMint with expires_in=3600, schedule refresh 60 s before expiry (shown above).
Tab inactivePause the refresh timer using visibilitychange. Mint fresh when the tab comes back.
Token already expiredFetch a new token - the old one is silently rejected by the iframe, not a hard error.

CSP considerations

If your product sets a Content-Security-Policy, add the MIOSA preview domain to frame-src:

Content-Security-Policy: frame-src https://*.miosa.app;

If you use a custom white-label preview domain (configured via client.customDomains.create), add that domain instead.

Was this helpful?