HTTP API
Base URL, authentication with API keys, the main endpoints for apps, builds, submissions and OTA updates, and the error format of the Ubriot API.
The ubriot CLI and the ubriot-mcp server both use this API. Prefer them where they cover the task; use the API directly when you need something they do not do.
Base URL and auth
- Base URL:
https://api.ubriot.dev/api/v1 - Health check, no auth:
GET https://api.ubriot.dev/api/v1/healthreturns{"ok":true,...}. - Auth:
Authorization: Bearer <token>, where the token is an API key (ubk_...) from ubriot.dev/dashboard/api-keys or a session token from signing in. - Request and response bodies are JSON. Wherever a path has
:appIdor:idfor an app, the numeric id or the app slug both work.
curl -s https://api.ubriot.dev/api/v1/ubriot/apps \
-H "Authorization: Bearer $UBRIOT_TOKEN"There is no published OpenAPI document yet. The endpoints below are the stable ones the CLI and MCP server depend on.
Main endpoints
Paths are relative to the base URL. "Key" means an API key works; "Session" means it needs a signed-in session.
| Method and path | Auth | What it does |
|---|---|---|
GET /ubriot/apps | Key | List apps. |
POST /ubriot/apps | Key | Create an app: name, slug, optional repoUrl, defaultBranch, iosBundleIdentifier, androidApplicationId, expoProjectRoot. |
GET /ubriot/apps/:appId | Key | Get one app. |
PATCH /ubriot/apps/:appId | Key | Update app settings. |
GET /ubriot/apps/:appId/readiness | Key | Credential and configuration checklist. |
GET /ubriot/apps/:appId/activity | Key | Who changed what on the app. |
POST /ubriot/apps/:appId/builds | Key | Queue a build: platform (ios or android), optional profile, branch, repoUrl. |
GET /ubriot/apps/:appId/builds | Key | List an app's builds. |
GET /ubriot/builds | Key | List recent builds across apps. |
GET /ubriot/builds/queue | Key | Why queued builds have not started. |
GET /ubriot/builds/last-good | Key | Last successful build per app, platform and profile. |
GET /ubriot/builds/:id | Key | Build status, error and submission state. |
GET /ubriot/builds/:id/logs | Key | Build log. |
GET /ubriot/builds/:id/artifacts | Key | Build artifacts. |
GET /ubriot/artifacts/:id/link | Key | A download link for an artifact. |
POST /ubriot/builds/:id/cancel | Key | Cancel a queued or running build. |
POST /ubriot/builds/:id/submit-testflight | Key | Upload an iOS build to TestFlight. |
POST /ubriot/builds/:id/submit-google-play | Key | Upload an Android build to Google Play: optional track, releaseStatus, rolloutPercentage, releaseNotes. |
GET /ubriot/apps/:appId/updates | Key | List OTA updates. |
POST /ubriot/apps/:appId/channels/:channel/rollback | Key | Roll an OTA channel back. |
GET /ubriot/apps/:appId/health | Key | Release health status. |
GET /ubriot/analytics/builds | Key | Build analytics. |
/ubriot/apps/:appId/credentials, /ubriot/account/credentials | Session | Signing credentials. |
/ubriot/apps/:appId/channels | Session | List, create and repoint OTA channels. |
/ubriot/apps/:appId/push/server-keys | Session | Push server keys. |
/ubriot/api-keys | Session | Create, list and revoke API keys. |
Publishing an OTA update means uploading an exported JavaScript bundle and its assets. Use ubriot update rather than calling the update endpoints directly.
Sending push from your backend uses a push server key in the x-ubriot-push-key header, not an API key. See Notify.
Errors
Errors return an HTTP status and a JSON body:
{ "statusCode": 401, "message": "Missing token", "error": "Unauthorized" }message is a plain sentence, and for billing and setup problems it says what to do next, for example Verify a payment card at ubriot.dev/dashboard/billing to start your 14-day trial. Some validation errors return message as an array of strings.
Newer errors also carry a stable code and a doc_url to the guide that fixes them:
{ "statusCode": 403, "code": "email_not_verified", "message": "Verify this account's email address before starting builds or store submissions. ...", "doc_url": "https://docs.ubriot.dev/quickstart#verify-email" }code | Status | Meaning |
|---|---|---|
email_not_verified | 403 | Starting a build or a TestFlight or Google Play submission before the account's email is verified. A person verifies it from the dashboard banner; see Verify your email. |
account_paused | 403 | Signing in with the correct password to an account that was paused. See Create and verify your account. |
signup_network_blocked, signup_rate_limited, captcha_required, captcha_failed, captcha_unavailable | 403, 429, 400, 403, 503 | Account creation only. See Create and verify your account. |
| Status | Usual cause | What to do |
|---|---|---|
400 | A missing or invalid field, or a submission already running for the build. | Read message and fix the request. |
401 | Missing, revoked or wrong token, or an API key used on a session-only route. | Check the token, or sign in for session-only routes. |
403 | No trial or plan, an unverified email (email_not_verified), or no access to that app. | A person fixes billing at ubriot.dev/dashboard/billing or verifies the email from the dashboard. |
404 | The app or build does not exist or belongs to another account. | Check the id with GET /ubriot/apps. |
429 | Rate limited. | Wait and retry with backoff. |
Older errors do not carry a code or a doc_url yet, and writes do not accept an idempotency key. Before retrying a write that may have succeeded, check its effect first, for example list builds before queueing another one.