On this page

White-label SaaS - end-to-end walkthrough

This walkthrough builds OpenDesigns, a design-tool SaaS where each customer gets an isolated workspace. OpenDesigns’s end users never see the MIOSA brand: the domain is opendesigns.ai, the product name is “OpenDesigns Workspaces”, and the failure pages show the OpenDesigns logo.

Everything here maps directly to working code in examples/whitelabel-saas.


Prerequisites

  • A MIOSA account with a workspace-scoped API key (msk_w_...)
  • DNS access to your domain (for preview domain setup)
  • Python 3.9+ or Node 18+ depending on which code tabs you follow

One-time setup

Run this once after account creation. It is safe to re-run - each step checks the current state and skips if already configured.

Set branding

Register a preview domain

Add two wildcard CNAME records at your DNS provider before continuing:

Record typeNameValue
CNAME*proxy.miosa.ai
CNAME*.sandboxproxy.miosa.ai

Verify after DNS propagates (typically 1-5 minutes):

Register a webhook


Per-user provisioning

Create one sandbox per customer project. Pass your own IDs so you can look up, filter, and bill these resources later.

Field reference:

FieldPurposeExample
external_user_idYour customer’s stable identifier. Used for usage rollup, quota checks, and filtering."user_42"
external_project_idYour project’s identifier within a customer."proj_opendesigns_1"
nameURL-safe slug that appears in preview URLs until a custom domain is set."brand-refresh-2026"
metadataArbitrary key-value pairs returned in webhook payloads and API responses.{"source": "opendesigns"}

Pretty URLs

By default, sandbox previews use *.sandbox.opendesigns.ai after you register your preview domain. To give each sandbox a human-readable subdomain, update the slug after creation:

Slugs must be unique within your workspace. If a slug is already taken, MIOSA returns a 409 conflict.


Embed a preview in an iframe

Never expose your API key to the browser. Your backend mints a short-lived preview token; the browser sets it as the <iframe src>.

In the browser:

<iframe
  id="workspace-frame"
  src="https://3000-brand-refresh-2026.sandbox.opendesigns.ai?token=mp_..."
  allow="clipboard-read; clipboard-write"
  sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
  style="width: 100%; height: 700px; border: none;"
  title="OpenDesigns Workspace"
></iframe>

See Preview Tokens for token refresh, permission scoping, and early revocation.


Get notified: webhook subscription

The POST /webhooks/miosa handler verifies the HMAC-SHA256 signature and dispatches events:

For the complete signature verification spec and retry policy, see Webhooks.


Customize after create

Update sandbox settings at any time without recreating the VM:


Bill by user

Query compute usage keyed to your external_user_id. Use this for per-seat billing, usage dashboards, or chargeback reports.


Per-user quotas

Prevent a single customer from consuming your entire compute budget. Set quotas at the workspace or project level, or enforce them in your own API layer:


Branded failure pages

502 and 404 errors in previews will show your branding once product_name and logo_url are set (see one-time setup). No additional configuration is needed. The preview proxy reads your tenant branding automatically.


Public sharing

Create a public share link for a sandbox preview - useful for design reviews or peer feedback:

Revoke a share before it expires:


End-user file tree, terminal, and run buttons

Give your users a native feel with file browsing, terminal, and run-button components backed by the MIOSA SDK. All three require a browser token with the appropriate scopes (see Preview Tokens - permission scoping).

File tree

Terminal

Run button


Teardown on cancellation

Destroy all sandboxes when a customer cancels their account:


End-to-end checklist

  • Set branding: product_name, logo_url, support_email
  • Register preview domain and add DNS CNAMEs
  • Verify DNS propagation
  • Register webhook and store the secret in your environment
  • Create sandboxes with external_user_id, external_project_id, and metadata
  • Mint preview tokens server-side only - never expose msk_* to the browser
  • Verify HMAC-SHA256 on every webhook delivery
  • Reject stale webhook timestamps (>5 min)
  • Deduplicate webhook events by event.id
  • Query usage by external_user_id for billing
  • Enforce per-user sandbox quotas before creating
  • Destroy sandboxes on cancellation

See also

Preview Tokens

Token format, TTL strategy, iframe attachment, refresh, and permission scoping.

Preview Tokens →

Webhooks Reference

Full event taxonomy, HMAC verification in 3 languages, idempotency, retries.

Webhooks →

White-Label Setup

Domains, branding, workspace and project scoping, domain precedence.

White-Label Setup →

External Attribution

Ownership fields, external IDs, usage reconciliation.

Attribution →

Was this helpful?