Deploy, inspect and manage your SnapDeploy containers programmatically
Your API key authenticates the /api/mobile/** endpoints documented on this page.
Send it in any of three forms:
Get your key from the API Keys page in your dashboard — it also has one-line setup for the MCP connector (Claude Code, Cursor and other AI assistants).
Destructive actions are refused for API keys, by design. Deleting containers, databases, domains or your account, changing the password, and cancelling subscriptions all return
403 INTERACTIVE_SESSION_REQUIRED — they can only be done by a person signed in to the web dashboard or the mobile app. A leaked key (or an over-eager AI agent) cannot destroy anything.
/api/mobile/bootstrap
Everything in one call: your profile and plan, all containers, the deploy limit and your free-hours usage.
{
"user": { "userId": "…", "email": "…", "plan": "FREE" },
"containers": [ { "containerId": "…", "name": "my-app", "status": "RUNNING", "url": "https://my-app.containers.snapdeploy.app" } ],
"deployCap": { "capped": true, "remaining": 5, "dailyLimit": 5 },
"usage": { "hoursUsed": 12.5, "hoursLimit": 100, "remainingHours": 87.5 }
}
/api/mobile/deploy-cap
Deploy limit only: capped, remaining, dailyLimit, timeUntilReset. Free accounts get 10 deploys a day (5 per rolling 12 hours) — failed attempts count. Always-On or a $1 Sprint Pack removes the limit.
/api/mobile/containers
Create a container. For GitHub-built apps use the placeholder image "pending" — the build supplies the real image after you link a repo.
{
"name": "my-app",
"image": "pending",
"memory": 512,
"environmentVariables": { "NODE_ENV": "production" }
}
/api/mobile/containers/{containerId}
Full container detail: status, URL, port (with detection confidence), detected technology, resources, env-var names.
/api/mobile/containers/{containerId}/start · /stop · /restart · /wake
Lifecycle actions. Start/restart/wake are subject to the free-hours gate — see the 402 error below. Restart also consumes a deploy-limit unit on free accounts.
/api/mobile/containers/{containerId}/env
Replace the container's environment variables (rolling restart, no rebuild). Public-prefixed names (VITE_*, NEXT_PUBLIC_*, …) are applied at build time — trigger a redeploy for them to reach the compiled bundle.
{ "environmentVariables": { "DATABASE_URL": "…", "VITE_API_BASE": "…" } }
/api/mobile/containers/{containerId}/logs?lines=200
Recent runtime logs (CloudWatch), up to 1,000 lines per request.
/api/mobile/containers/{containerId}/deployments?limit=20
Deployment history for a container, newest first (max 50).
Requires GitHub connected to your account (GET /api/mobile/github/status; if not connected, GET /api/mobile/github/connect-url returns the browser link).
/api/mobile/github/repos · /repos/search?q= · /repos/{owner}/{repo}/branches · /repos/{owner}/{repo}/detect-env-vars
Browse your repositories, and scan one for the environment variables it needs before the first deploy (Supabase and other well-known keys come with where-to-find help).
/api/mobile/github/link
Link a repo to a container. Linking triggers the first build itself and returns its deploymentId — don't call the deploy endpoint right after linking, or you'll start (and pay the deploy-limit for) a second build.
{
"containerId": "…",
"repoFullName": "you/your-repo",
"deployBranch": "main"
}
/api/mobile/github/link/{repoLinkId}/deploy
Redeploy an already-linked repo — the CI/CD hook for scripts and assistants. Consumes one deploy-limit unit at trigger.
{ "status": "triggered", "deploymentId": "…" }
/api/mobile/deployments/{deploymentId}
Poll this after triggering a build. Terminal statuses are COMPLETED, FAILED, CANCELLED, ROLLED_BACK. On failure the response carries everything needed to diagnose:
{
"deploymentId": "…",
"status": "FAILED",
"errorCode": "BUILD_FAILED",
"errorMessage": "…human-readable cause…",
"buildLogsTail": "…last lines of the build log…",
"smartFixEligible": true
}
/api/mobile/deployments/{deploymentId}/stream
Live build log as Server-Sent Events, for real-time progress UIs.
SmartFix: when smartFixEligible is true, SnapDeploy can propose an automatic fix. Deterministic fixes are free for everyone; the AI-powered fix requires an active Sprint Pack or Always-On subscription. Applying a fix commits to your repository, so it requires an interactive session — it cannot be applied with an API key.
/api/mobile/services/addons
List or create managed add-ons (PostgreSQL, MySQL, MariaDB, MongoDB, Redis, RabbitMQ). Creation requires a purchased add-on subscription — without one the response carries the purchase link. Credentials are injected into linked containers as env vars; they are shown to you in the dashboard, not returned to API-key callers' tooling.
/api/mobile/services/domains
List or attach custom domains ({ "domain": "app.example.com", "containerId": "…" }); fetch the DNS records to create via GET …/domains/{domainId}/dns-records, then verify with POST …/domains/{domainId}/verify.
/api/mobile/services/always-on/unassigned
POST
/api/mobile/services/always-on/assign
See unassigned Always-On subscriptions and attach one to a container ({ "subscriptionId": "…", "containerId": "…" }) — assigning also starts a stopped container. Cancelling or detaching a subscription is interactive-only.
fieldErrors map names each offending fieldmessage, actionUrl and actionText — show them to the user; when spareSubscriptionId is present, an unused Always-On can be assigned instead. Don't retry the call.DEPLOY_CAP_REACHED means the free deploy limit (10 a day — 5 per rolling 12 h, failed attempts count) — the $1 Sprint Pack link in actionUrl lifts it for 24 hours.Sign up free, grab your key from the API Keys page, and deploy from scripts, CI or your AI assistant