Embed the Hosted UI
Integrate VRPlatform-hosted UI into your product
Embedding keeps accounting views inside VRPlatform while your product owns authentication, navigation, and the iframe shell. The embedded surface is financial reports. Your backend selects the embedded-application origin and the exact parent-page origin for every session; the embedded origin must be allowed by the API's code-managed CORS policy.
A session moves through six phases. Each section below covers one:
| Phase | Who acts | Contract |
|---|---|---|
| Set up | Partner admin, once | POST /api-tokens |
| Issue | Your backend | POST /partner/embed-sessions |
| Mount and exchange | Parent page, then iframe | iframe src, POST /embed-sessions/exchange |
| Connect | Iframe and parent | channel.request, channel.connect, ready |
| Renew | Iframe, parent, and backend | session.expiring, the renewals endpoint, session.renew |
| Revoke | Your backend | DELETE /partner/embed-sessions/{id} |
The bearer token exists only inside the iframe; your backend holds the partner key and the revocable session ID, and your parent page only ever handles one-time bootstrap URLs and lifecycle messages.
Create the Partner API Token
Contact VRPlatform to register your team as a partner. A signed-in admin of
the partner team creates the API token through POST /api-tokens, restricts
it to the required bundles, and declares allowedEmbedParentOrigins for the
exact pages that will host your iframes. Store the returned secret only in
your backend. Issue Sessions shows the full
token example; Authentication defines the
credential rules.
Embedded sessions require an existing managed team. Provisioning teams is covered in Team Setup.
Issue a Session
When your signed-in user opens an embedded view, your backend authorizes the
user in your own product, then calls
POST /partner/embed-sessions
with the user's stable sub, the managed teamId, the smallest bundles,
both origins, and the view path. The response contains a 60-second,
single-use embedUrl, a revocable session id, a stable channelId, and
the approved parentOrigin, never a bearer token. Keep the id associated
with your user session for later revocation.
Mount and Exchange
Your parent page sets embedUrl directly as the iframe src before the
60-second deadline. The iframe exchanges the fragment code through
POST /embed-sessions/exchange from the embedded origin and holds its
15-minute bearer in memory. The parent page and your backend never see it.
See Iframe & Token Lifecycle.
Establish the Channel
After exchange, the iframe and parent perform the channel.request and
channel.connect handshake over one dedicated MessageChannel, validating
window, origin, channel ID, and request IDs on both sides. The iframe sends
ready once the report renders. Shell behavior for loading and failures is
covered in UI States.
Renew in Place
Before the bearer expires, the iframe sends session.expiring. Your parent
page asks your backend, your backend calls
POST /partner/embed-sessions/{id}/renewals,
and your parent page forwards the successor embedUrl through
session.renew. The iframe exchanges the new code without navigating; route,
filters, and rendered report state survive. Re-authorize the user in your own
product on every renewal request.
Revoke on Logout
When your user logs out, switches accounts, or loses access, call
DELETE /partner/embed-sessions/{id}.
Every bearer request re-checks the session record, so revocation applies
immediately. Removing the iframe only discards its in-memory token.
Common Mistakes
- Extracting the bootstrap code in the parent page or calling the exchange endpoint outside the iframe. The bearer must never exist in parent context.
- Logging or persisting
embedUrl. It contains a one-time credential. - Using the partner API key in the browser. It belongs on your backend only.
- Expecting an iframe reload to restore access. The code is single-use and the cleared URL holds no session; renew in place through the lifecycle channel.
- Sending
autoProvision: truefor users your product has not authorized. Provisioning creates a real membership on the team; see User Provisioning. - Forwarding a browser-supplied
teamIdwithout checking it against the signed-in user's access in your own product.
To render the product workflows yourself instead, use Build your own UI.
