On this page

Fundamental Concepts

MIOSA is a cloud platform for building and deploying applications. Before writing your first API call, read this page. It covers the eight concepts that underpin every MIOSA integration.


1. Organization, workspaces, and projects

Your MIOSA account starts as one organization. The organization has a permanent slug, one billing account, and API keys. Inside it, you can create multiple workspaces and projects:

  • The organization is the authorization and billing boundary.
  • A workspace usually represents a customer, client, team, or environment.
  • A project represents the app, website, lead magnet, document, or workflow being built inside a workspace.
  • Sandboxes, Computers, Deployments, Databases, Domains, Storage, Volumes, Functions, and Jobs belong to a project.

If you are building a platform product on top of MIOSA, use MIOSA workspaces for downstream customers and MIOSA projects for the things they create. External attribution fields still exist for your own IDs and chargeback.


2. Authentication

Every API request carries one header:

Authorization: Bearer <token>

The token is either an API key or a browser token (scoped JWT).

API keys

API keys have the prefix msk_ followed by a role segment:

PrefixRoleUse
msk_u_...userGeneral-purpose server-side calls
msk_a_...adminOperator/platform tooling
msk_p_...platformTenant-wide automation

API keys are server-side only. Never put an msk_* key in browser code, a mobile app, or a public repository.

Browser tokens

For browser-side access - embedding a preview, opening a terminal in an iframe - your backend mints a short-lived scoped token and passes it to the client:

Browser tokens expire, are non-renewable, and are scoped to a single resource. They cannot create new resources.

See Authentication and Browser Tokens for the full reference.


3. Ownership and external attribution

Every MIOSA resource accepts canonical ownership fields and optional attribution fields:

FieldMeaning
workspace_id / workspace_slugThe MIOSA workspace that owns the resource
project_id / project_slugThe MIOSA project that owns the resource
external_workspace_idYour customer’s account / tenant ID
external_user_idThe end-user inside that account
external_project_idThe project or app ID in your own database

Every resource also accepts a free-form metadata object (up to 16 key-value string pairs). Use it to carry application-layer context - feature flags, plan tier, region, whatever your billing system needs - without bloating your own database with a MIOSA resource join.

Integrators use these fields for four main purposes:

  • Usage rollup - query GET /api/v1/sandboxes?external_workspace_id=acme-co to aggregate compute time and costs for a downstream customer.
  • Per-end-user quotas - enforce your own rate limits by counting active sandboxes per external_user_id before creating a new one.
  • Audit log filtering - the audit log accepts external_user_id and external_project_id as filters so you can pull a customer-specific activity trail without exposing other customers’ data.
  • Chargeback and billing - external_workspace_id is the recommended key for billing rollup when you resell MIOSA compute to downstream customers. See the Audit Log and Quotas references.

MIOSA stores canonical workspace_id and project_id on each resource. The external fields are stored as opaque strings. Both appear on list/read responses, and list endpoints accept them as filters:

Filtering is always scoped to your MIOSA organization. You cannot see another organization’s resources regardless of what workspace, project, or external IDs you pass.

See Ownership and Attribution for the full filter spec and billing split by workspace/project.


4. The six resources

Every MIOSA operation creates, reads, updates, or destroys one of these six types.

Sandbox

A mutable microVM where agents or developers build an app. Execute commands, read and write files, run dev servers, take snapshots.

Sandboxes →

Preview

A temporary public URL that tunnels to a port inside a running sandbox. Safe to embed in an iframe with a browser token.

Previews →

Deployment

The stable product object the world knows as “the live app.” Holds an active_version_id. Publishing creates a new Version; rollback resets it.

Deploy overview →

Version

An immutable snapshot of a built Release attached to a Deployment. Promoting a Version updates live traffic. Prior Versions stay available for rollback.

Versions →

Runtime Instance

A production microVM booted from a dynamic Release. The scheduler places, scales, and health-checks instances automatically.

Runtime Instances →

Domain

A DNS hostname routed to a Deployment’s active Version. Supports MIOSA-managed subdomains and custom domains with auto-provisioned TLS.

Domains →

The publish pipeline connects them in order:


Sandbox → Builder → Release → Version → Deployment → Domain

A Builder is an internal ephemeral VM that runs the build. You never address it directly.


5. Token types

MIOSA issues five distinct token types. Each covers a different caller and trust level:

TokenPrefixCallerTTLRead / Write
API keymsk_*Your serverUntil revokedRead + Write
JWTey...Admin UI / browser session~1 h (refresh 7 d)Read + Write
Browser token(opaque)Your user’s browserConfigurable (default 1 h)Read-only, single resource
Preview tokenmp_*Browser / <MiosaPreview> iframeConfigurable (default 1 h)Read-only, sandbox preview
Share tokenms_*Anyone - no account requiredConfigurableRead-only, sandbox preview

The msk_* API key is the root credential. All other token types are minted downstream from it by your server. Never give an msk_* key to a browser or end user.

For minting flows, revocation, and validation rules see Authentication and Preview Tokens.


7. Idempotency

Every mutation endpoint (POST, PUT, PATCH, DELETE) accepts an optional Idempotency-Key header. Retrying a request with the same key is safe - MIOSA returns the original response without re-executing the operation.

POST /api/v1/sandboxes
Authorization: Bearer msk_u_...
Idempotency-Key: create-sandbox-for-alice-2026-05-17
Content-Type: application/json

{ "template_id": "miosa-sandbox", "external_user_id": "alice" }

Idempotency keys are:

  • Scoped to your workspace and the endpoint path.
  • Valid for 24 hours from first use.
  • Stored regardless of whether the original request succeeded or failed.

If the first request timed out before you received a response, retry with the same key. You will receive the original result if the operation completed, or a 202 Accepted if it is still in progress.


8. Rate limits

Rate limits apply per API key, per workspace, and per endpoint family. Every response includes quota headers:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1748390460

Default limits:

Endpoint familyLimitWindow
GET /api/v1/* (reads)600 requestsPer minute per key
POST /PUT /PATCH /DELETE /api/v1/* (writes)300 requestsPer minute per key
Auth (/auth/login, /auth/refresh)60 requestsPer minute per IP

When you exceed a limit, the API returns 429 Too Many Requests with a Retry-After header containing the number of seconds until your quota resets.

High-volume workloads (AI agent pipelines creating many sandboxes per minute) can request a quota increase from the platform dashboard or by contacting support.


9. Tenant-level configuration

White-label integrators can configure four areas of tenant behavior via the API. All routes accept msk_a_* admin keys or admin JWTs.

Preview domain

Map a custom subdomain (e.g., preview.yourdomain.com) to sandbox preview URLs. Once set, the MIOSA router serves sandbox previews on your domain instead of *.miosa.app. Configure DNS with a CNAME to sandbox.miosa.app, then register the domain:

PUT /api/v1/tenant/preview-domain
{ "domain": "preview.yourdomain.com" }

See Tenant Preview Domain.

Branding

Customize the 404 and 502 error pages shown inside sandbox previews and deployments. Accepts an HTML template with {{status}} and {{message}} interpolation slots:

PUT /api/v1/tenant/branding
{ "error_page_html": "<html>...</html>", "logo_url": "https://..." }

See Tenant Branding.

Webhooks

Subscribe to sandbox and deployment lifecycle events delivered as HTTPS POST requests to your endpoint. MIOSA signs each request with an HMAC-SHA256 signature in the X-Miosa-Signature header:

POST /api/v1/tenant/webhooks
{ "url": "https://yourapp.com/webhooks/miosa", "events": ["sandbox.*", "deployment.*"] }

See Webhooks and Integrations for the event catalog and signature verification.

Per-end-user quotas

Set maximum resource counts per external_user_id to prevent runaway usage by a single downstream user. Quotas are checked at resource creation time and return 429 with code QUOTA_EXCEEDED when reached:

PUT /api/v1/tenant/quotas
{ "max_sandboxes_per_user": 5, "max_computers_per_user": 2 }

See Quotas.


10. Errors

All errors use a consistent envelope:

{
  "error": {
    "code": "SANDBOX_NOT_FOUND",
    "message": "No sandbox with id sbx_abc123 exists in this workspace.",
    "request_id": "req_01hx9z..."
  }
}
FieldDescription
codeMachine-readable constant. Use this in your switch statements, not message.
messageHuman-readable explanation. May change between API versions.
request_idInclude this when contacting support or filing a bug report.

HTTP status codes map directly to error categories:

StatusCategory
400Invalid request body or parameters
401Missing or invalid credential
403Valid credential, insufficient permissions
404Resource not found (or not visible to your workspace)
409Conflict - resource already exists, duplicate idempotency key with different body
422Validation error - request parsed correctly but failed domain rules
429Rate limited
5xxMIOSA-side fault - safe to retry with exponential backoff

The full error code catalog is in the API Reference.


10. Events (SSE)

Several long-running operations stream progress over Server-Sent Events. The SSE stream for a resource is always at:


GET /api/v1/{resource-type}/{id}/events

Because the browser EventSource API does not support custom headers, SSE endpoints use a one-time ticket for authentication instead of the Authorization header:

Event types vary by resource. Common event shapes:

// Build log line
{ "type": "log", "stream": "stdout", "data": "Installing dependencies...", "ts": 1748390460 }

// Status change
{ "type": "status_changed", "previous": "building", "current": "ready", "ts": 1748390462 }

// Error
{ "type": "error", "code": "BUILD_FAILED", "message": "Exit code 1", "ts": 1748390465 }

Sandbox lifecycle events

EventWhen
sandbox.createdSandbox resource created (not yet booted)
sandbox.readyBoot complete, exec and file endpoints available
sandbox.errorFatal boot or runtime error
sandbox.destroyedSandbox stopped and resources released
sandbox.share.createdA share token was minted for the sandbox
sandbox.share.revokedA share token was revoked

Deployment lifecycle events

EventWhen
deployment.createdDeployment object created
deployment.build_startedBuilder VM booted, build in progress
deployment.build_succeededRelease artifact ready
deployment.build_failedBuild exited non-zero
deployment.publishedActive version updated, traffic cut over
deployment.rollbackActive version reset to a prior version

Tenant-wide SSE stream

To receive all lifecycle events for your organization without polling per-resource endpoints, subscribe to the tenant stream:

# Mint a ticket
TICKET=$(curl -s -X POST https://api.miosa.ai/api/v1/events/ticket 
  -H "Authorization: Bearer msk_u_..." | jq -r '.ticket')

# Stream all org events
curl -N "https://api.miosa.ai/api/v1/events?ticket=$TICKET"

Each event on the tenant stream includes a resource_type and resource_id field so you can route to the right handler:

{
  "type": "sandbox.ready",
  "resource_type": "sandbox",
  "resource_id": "sbx_abc123",
  "external_user_id": "alice@acme.com",
  "ts": 1748390462
}

See Events (SSE) API Reference and Tenant Events for the complete event catalog and filtering options.


11. Sandboxes vs Computers

Two products, one platform. Pick based on what your workflow needs:

SandboxComputer
Primary useCode execution, file I/O, dev servers, agent build loopsDesktop GUI, browser automation, screen-driven agents
DisplayHeadless (no screen)X11 + VNC stream
Accessibility treeNoYes
APIsexec, file I/O, snapshots, previewsscreenshot, click, type, keyboard, scroll
LifecycleShort-to-medium, auto-suspend on idleSession-oriented
Typical agent task“Write and deploy a FastAPI service”“Fill out this web form”, “navigate a GUI app”

Use a Sandbox when your agent needs to write code, run shell commands, manage files, or serve a dev server.

Use a Computer when your agent needs to operate a graphical interface - a browser, a desktop app, or anything with a visible screen.

Both products live in the same organization, can be separated by workspace/project, and appear on the same billing account.


What’s next

Was this helpful?