White-label setup
MIOSA can run behind your product and your customers’ domains. The important order is: set the organization identity first, create workspaces/projects for downstream customers, configure preview and deployment domains separately, then attach exact custom domains where a customer needs their own hostname.
Setup flow
1. Organization identity
Every account needs a real organization name. MIOSA derives the organization slug from that name, and the slug is permanent after setup. Do this before letting users create resources.
Example:
| Organization name | Organization slug | Default managed deployment URL |
|---|---|---|
ClinicIQ | cliniciq | https://lead-magnet.cliniciq.miosa.app |
If a newly created account still has a temporary setup slug such as org-... or a slug that does not match the organization name, require setup before normal app navigation.
GET /api/v1/platform/tenants/current
Authorization: Bearer msk_live_... If setup is required, update the tenant with the final organization name:
PUT /api/v1/tenants/{tenant_id}
Authorization: Bearer msk_live_...
Content-Type: application/json
{
"name": "ClinicIQ"
} The API normalizes the slug from name. If a slug is supplied, it must match the normalized organization name. After setup, name and slug are immutable.
2. Workspaces and projects
For white-label platforms, use workspaces for downstream customers and projects for the things they build.
ClinicIQ example:
Organization: ClinicIQ
Workspace: Dr. Smith Clinic
Project: Summer lead magnet
Sandboxes: generated app previews
Databases: form submissions
Deployment: production lead magnet
Domain: program.drsmithclinic.com
Workspace: Downtown Dental
Project: Booking portal Create workspaces and projects directly, or let resource create calls auto-resolve them from workspace_slug / project_slug or external_workspace_id / external_project_id.
POST /api/v1/sandboxes
Content-Type: application/json
{
"template_id": "miosa-sandbox",
"workspace_slug": "dr-smith-clinic",
"workspace_name": "Dr. Smith Clinic",
"project_slug": "summer-lead-magnet",
"project_name": "Summer Lead Magnet",
"external_workspace_id": "clinic_123",
"external_user_id": "dr-smith-456",
"external_project_id": "project_789"
} Responses include workspace_id and project_id. Store those IDs for future calls.
3. URL layers
White-label production has distinct URL layers. Do not mix them:
| Resource | Default URL shape |
|---|---|
| Sandbox preview | https://{port}-{sandbox_slug}.sandbox.{preview_domain} |
| Computer desktop | https://{computer_slug}.computer.miosa.ai/desktop/index.html |
| Durable deployment | https://{deployment_slug}.{deployment_domain} |
| Deployment fallback | https://{deployment_slug}.{organization_slug}.miosa.app |
| Exact custom domain | https://customer-owned.example.com |
For ClinicIQ, a deployment named Lead Magnet defaults to something like:
https://lead-magnet.cliniciq.miosa.app The fallback is always available. If a tenant deployment domain is configured, deployment responses return that branded URL instead. SDKs, CLIs, and frontends should display the returned public_url / url, not construct hostnames.
4. Organization preview domain
Set a tenant preview domain when generated sandbox preview URLs should use your organization’s domain instead of the MIOSA fallback.
Example:
PUT /api/v1/tenant/preview-domain
Content-Type: application/json
{
"preview_domain": "cliniciq.dev"
} DNS:
| Record type | Name | Value |
|---|---|---|
CNAME | * | proxy.miosa.ai |
CNAME | *.sandbox | proxy.miosa.ai |
After DNS propagates:
GET /api/v1/tenant/preview-domain/verify Sandbox preview URLs then use:
https://5173-sbx01j9x.sandbox.cliniciq.dev 5. Deployment domain
Set a tenant deployment domain when published apps should use your branded production URL base.
Recommended ClinicIQ setup:
*.sandbox.cliniciq.com CNAME proxy.miosa.ai
*.apps.cliniciq.com CNAME proxy.miosa.ai Then generated URLs look like:
| Surface | Example |
|---|---|
| Sandbox preview | https://5173-sbx01j9x.sandbox.cliniciq.com |
| Durable deployment | https://lead-magnet.apps.cliniciq.com |
| Managed fallback | https://lead-magnet.cliniciq.miosa.app |
Current V1 note: public tenant preview-domain routes are exposed. Tenant deployment-domain resolution exists in backend settings/routing; public tenant-level management routes are still operator-managed. Your client code should consume returned deployment public_url values.
6. Resource custom domains
Attach exact domains when a project, deployment, or computer needs its own public URL.
Examples:
drsmithclinic.comfor a website deploymentprogram.drsmithclinic.comfor a lead magnetapp.drsmithclinic.comfor an apppreview.drsmithclinic.comfor a client-specific preview surface
For deployments:
POST /api/v1/deployments/{deployment_id}/domains
Content-Type: application/json
{
"domain": "program.drsmithclinic.com"
} For computers:
POST /api/v1/computers/{computer_id}/domains
Content-Type: application/json
{
"domain": "desktop.drsmithclinic.com"
} The domain response returns DNS instructions and verification status. Exact resource domains take precedence over managed MIOSA URLs.
7. Domain precedence
When MIOSA renders or routes a URL, use this mental model:
| Priority | Source | Example |
|---|---|---|
| 1 | Exact resource domain | program.drsmithclinic.com |
| 2 | Tenant deployment domain | lead-magnet.apps.cliniciq.com |
| 3 | MIOSA managed fallback | lead-magnet.cliniciq.miosa.app |
Sandbox preview domains are separate from deployment domains. Computer desktop URLs are separate from both. Exact resource custom domains still win when attached.
8. Branding
Tenant branding controls the product UI, desktop wallpaper, logos, support URL, and whether “Powered by MIOSA” is shown.
PUT /api/v1/tenant/branding
Content-Type: application/json
{
"custom_app_name": "ClinicIQ",
"custom_logo_url": "https://cliniciq.com/logo-dark.png",
"support_url": "https://help.cliniciq.com",
"desktop_wallpaper_url": "https://cliniciq.com/wallpaper.png",
"powered_by_visible": false
} Wallpaper requirements:
| Property | Value |
|---|---|
| Format | PNG or JPEG |
| Dimensions | 1920 x 1080 recommended |
| File size | Max 5 MB |
9. Browser tokens
Never expose an msk_* API key in a browser. Your backend creates sandboxes, deployments, and domains, then issues scoped browser tokens for the end user.
const token = await client.browserTokens.create({
workspaceId: "550e8400-e29b-41d4-a716-446655440000",
projectId: "660e8400-e29b-41d4-a716-446655440001",
externalWorkspaceId: "clinic_123",
externalUserId: "dr-smith-456",
permissions: ["sandbox:read", "sandbox:exec", "preview:read"],
ttlSeconds: 3600,
}) Complete setup checklist
- Require organization setup if the account still has a temporary slug or no organization name.
- Explain that organization name creates the permanent MIOSA slug one time.
- Create or auto-resolve workspaces for downstream customers.
- Create or auto-resolve projects for each app, website, lead magnet, document, or workflow.
- Store
workspace_idandproject_idfrom create responses. - Use returned MIOSA fallback URLs until DNS is configured.
- Configure preview domain if sandbox previews should use your domain.
- Configure deployment domain if generated apps should use your domain by default.
- Attach exact custom domains to deployments or computers when a customer wants their own URL.
- Apply tenant branding and support links.
- Issue browser tokens from your backend only.
See also
Workspace/project ownership plus external IDs for chargeback and filtering.
Domain APIs, DNS records, and verification responses.
Workspace create, update, settings, and usage.
Project create, update, and workspace scoping.