Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see POST /tests/generate).
The call returns as soon as the run is created. Take runId from the response and pass it to GET /runs/{runId} to follow the run until its status is completed or cancelled.
Choose the tests with testIds, tags, or both. A test is runnable on the run’s platform once its automation has been written and verified, which GET /tests shows as platforms.<platform>.runnable.
A test you name in testIds must be runnable. If it is not, the request is refused with 400.
A test that only matches tags and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in skippedTests with the reason, and warnings says how many were left out. If none of the tests matching tags is runnable, the request is refused with 400 and the message lists them.
Skipped tests are not part of the run: they are not counted in totalTests and never change the run’s status.
Name the app with one of:
buildId: the buildId that POST /uploadBuild returned.
build.meta.name: the newest build uploaded under that name. Add platform if you upload your iOS and Android apps under the same name.
bundleId and platform: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation.
Choose the device with usePhysicalDevice. MobileBoost picks the device itself, so deviceConfigs, deviceProviderSettings, launchParams, testInputs, tagsQuery, iterations, metaData, stealthMode, dependencyTestIds and the ephemeralTest* fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for.
Pass values to your tests with variables: NAME: value pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation’s environment variable of the same name for this run only. variables replaces testInputs. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation’s environment variables (ENV Variables in the web app).
Authenticate with your API key: Authorization: Bearer mb_live_.... organisationId must be the organisation the key belongs to. A request that sends variables or tunnelName needs the key even if your organisation does not otherwise require one.
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
organisationId
string
required
Your MobileBoost organisation ID. It must be the organisation your API key belongs to.
buildId
string
The build to test: the buildId that POST /uploadBuild returned. Send one of buildId, build or bundleId.
build
Build · object
Test the newest build uploaded under a name instead of naming a buildId: {"meta": {"name": "my-app"}}. When you send both, build is used.
Show child attributes
bundleId
string
Test the app with this bundle identifier that is already installed on your reserved device, instead of an uploaded build. Requires platform, always runs on a physical device, and has to be enabled for your organisation (403 otherwise). Cannot be combined with buildId.
platform
enum<string>
The platform to run on. Taken from the build when you send buildId. Required with bundleId. With build, it picks the newest build of that name for this platform.
Available options:
ios,
android
testIds
string[]
IDs of the tests to run, as GET /tests returns them. Send testIds, tags, or both.
tags
string[]
Run every test that has at least one of these tags. Combined with testIds, the run contains both sets.
usePhysicalDevice
boolean
true runs on a real handset reserved for your organisation, false on an emulator or simulator. Omit it to use your organisation's default: a real handset when you have one reserved for this platform, otherwise an emulator or simulator. An iOS .ipa build and a bundleId run always use a real handset.
tunnelName
string
Name of a connected MobileBoost Local tunnel: the --tunnel-name you started mb-local with. The app on the device then reaches your internal hosts, such as a staging API, through it. Omit it when your app's backend is publicly reachable. An unknown or disconnected tunnel fails the run.
trigger
string
A free-form label stored on the run to say what started it, for example ci or nightly. Defaults to api.
variables
Run variables · object
Values for this run's tests, as NAME: value pairs, for example the backend a canary test signs in against. Each test reads them as environment variables, and a value here wins over your organisation's environment variable of the same name for this run only. Names use upper case letters, digits and underscores and start with a letter; names the test runner relies on, such as PATH or anything starting with PYTHON, are refused. Values must be strings. Up to 20 per run. Requires your API key even if your organisation does not otherwise require one. Not for passwords or keys: values are kept with the run for 14 days, so keep credentials in your organisation's environment variables. Replaces testInputs.
The run was created. Its tests are queued on devices in the background.
message
string
required
A human-readable message describing the result of the request.
runId
string
required
The ID of the run. Pass it to GET /runs/{runId} to follow the run and read its results.
status
string
required
Always running: the run was accepted. Read its progress from GET /runs/{runId}.
scheduledTests
integer
Number of tests the run started with.
skippedTests
SkippedTest · object[]
Tests that matched tags but are not runnable on this platform yet, so the run does not include them. Empty when every selected test was scheduled.
Show child attributes
warnings
string[]
Human-readable notes about the request, such as how many tests were skipped. Print them in your CI log. Empty when there is nothing to report.
variables
string[]
The names of the variables the run received, sorted. Never their values. Present only when the request sent variables.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"MobileBoost","colors":{"primary":"#16A34A","light":"#07C983","dark":"#15803D"},"logo":{"light":"https://mintcdn.com/mobileboost-321ad6a9/OGuA69W71_lGnu9x/logo/light.png?fit=max\u0026auto=format\u0026n=OGuA69W71_lGnu9x\u0026q=85\u0026s=b6a6cc5ef5708fb7e589eb22c4e758e5","dark":"https://mintcdn.com/mobileboost-321ad6a9/BUpecZhwuqipr6rG/logo/dark.png?fit=max\u0026auto=format\u0026n=BUpecZhwuqipr6rG\u0026q=85\u0026s=fa051814a401e3fac77cd87f86f198b5"},"favicon":"https://mintcdn.com/mobileboost-321ad6a9/6v1OHjEJe7b4HZwT/favicon.png?fit=max\u0026auto=format\u0026n=6v1OHjEJe7b4HZwT\u0026q=85\u0026s=f0fa31f2c8ddd8d4e252cd3702d4f0c4","api":{"playground":{"display":"interactive"}},"footer":{"socials":{}},"seo":{},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"metadata":{"timestamp":false},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"mobileboost-321ad6a9","hasAudioNarration":false,"actualSubdomain":"mobileboost-321ad6a9","customDomains":["docs.mobileboost.io"],"gitSource":{"type":"github","owner":"mobileboosthq","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"entitlements":{},"buildId":"6af450ddbc2b4cf012828780","clientVersion":"0.0.4131","searchFilterCounts":[{"language":"default","tag":"Local Tooling","count":21},{"language":"default","tag":"API","count":19},{"language":"default","tag":"SDK","count":18},{"language":"default","tag":"Test Agent","count":15},{"language":"default","tag":"QA Studio","count":14},{"language":"default","tag":"Appium","count":11},{"language":"default","tag":"No-code test editor","count":7},{"language":"default","tag":"Test execution","count":7},{"language":"default","tag":"Tests","count":6},{"language":"default","tag":"Folders","count":5}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"changelog.css","content":".changelog-filters{display:flex;flex-wrap:wrap;gap:0.5rem;margin:1.5rem 0 2rem}.changelog-chip{padding:0.25rem 0.75rem;font-size:0.8125rem;line-height:1.4;border-radius:9999px;border:1px solid rgb(229 231 235);background:transparent;color:rgb(75 85 99);cursor:pointer;transition:background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease}.changelog-chip:hover{background:rgb(243 244 246);color:rgb(17 24 39)}.changelog-chip.is-active{background:#16a34a;background:rgb(var(--primary));border-color:#16a34a;border-color:rgb(var(--primary));color:#fff}.changelog-list{border-top:1px solid rgb(229 231 235)}.changelog-row{display:block;padding:1rem 0.75rem;margin:0 -0.75rem;border-bottom:1px solid rgb(229 231 235);text-decoration:none!important;color:inherit;border-radius:0.375rem;transition:background-color 0.12s ease}.changelog-row:hover{background:rgb(249 250 251)}.changelog-row-head{display:flex;align-items:baseline;justify-content:space-between;gap:1.5rem}.changelog-row-title{font-weight:600;font-size:1rem;line-height:1.5;color:rgb(17 24 39)}.changelog-row:hover .changelog-row-title{color:#16a34a;color:rgb(var(--primary))}.changelog-row-date{flex:none;font-size:0.8125rem;color:rgb(107 114 128);white-space:nowrap}.changelog-row-desc{margin:0.25rem 0 0;font-size:0.875rem;font-weight:400;line-height:1.6;color:rgb(107 114 128);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.changelog-meta{display:flex;flex-wrap:wrap;align-items:center;gap:0.75rem;margin-bottom:2rem;font-size:0.8125rem;color:rgb(107 114 128)}.changelog-meta span{padding:0.125rem 0.5rem;border-radius:9999px;background:rgb(243 244 246);color:rgb(75 85 99)}.changelog-back{margin-top:3rem;padding-top:1.5rem;border-top:1px solid rgb(229 231 235);font-size:0.875rem}.changelog-back p{margin:0}.changelog-back a::before{content:\"\\2190\\00a0\"}.dark .changelog-chip{border-color:rgb(55 65 81);color:rgb(156 163 175)}.dark .changelog-chip:hover{background:rgb(31 41 55);color:rgb(243 244 246)}.dark .changelog-chip.is-active{color:#fff}.dark .changelog-list,.dark .changelog-row,.dark .changelog-back{border-color:rgb(38 45 58)}.dark .changelog-row:hover{background:rgb(24 30 40)}.dark .changelog-row-title{color:rgb(243 244 246)}.dark .changelog-row-date,.dark .changelog-row-desc,.dark .changelog-meta{color:rgb(148 156 168)}.dark .changelog-meta span{background:rgb(31 41 55);color:rgb(203 213 225)}@media (max-width: 640px){.changelog-row-head{display:block}.changelog-row-date{display:block;margin-top:0.25rem}}.changelog-pager{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-top:2rem;flex-wrap:wrap}.changelog-pager-pages{display:flex;gap:0.25rem;flex-wrap:wrap}.changelog-pager-step,.changelog-pager-page{min-width:2rem;padding:0.3rem 0.75rem;font-size:0.8125rem;line-height:1.4;border-radius:0.375rem;border:1px solid rgb(229 231 235);background:transparent;color:rgb(75 85 99);cursor:pointer;transition:background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease}.changelog-pager-step:hover:not(:disabled),.changelog-pager-page:hover:not(.is-active){background:rgb(243 244 246);color:rgb(17 24 39)}.changelog-pager-step:disabled{opacity:0.4;cursor:default}.changelog-pager-page.is-active{background:#16a34a;background:rgb(var(--primary));border-color:#16a34a;border-color:rgb(var(--primary));color:#fff}.dark .changelog-pager-step,.dark .changelog-pager-page{border-color:rgb(55 65 81);color:rgb(156 163 175)}.dark .changelog-pager-step:hover:not(:disabled),.dark .changelog-pager-page:hover:not(.is-active){background:rgb(31 41 55);color:rgb(243 244 246)}.dark .changelog-pager-page.is-active{color:#fff}"}],"page":{"pagePath":"api-reference/execute-tests","slug":"/api-reference/execute-tests","pageMetadata":{"title":"Execute tests","description":"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see `POST /tests/generate`).\n\nThe call returns as soon as the run is created. Take `runId` from the response and pass it to `GET /runs/{runId}` to follow the run until its `status` is `completed` or `cancelled`.\n\n**Choose the tests** with `testIds`, `tags`, or both. A test is runnable on the run's platform once its automation has been written and verified, which `GET /tests` shows as `platforms.\u003cplatform>.runnable`.\n\n- A test you name in `testIds` must be runnable. If it is not, the request is refused with 400.\n- A test that only matches `tags` and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in `skippedTests` with the reason, and `warnings` says how many were left out. If none of the tests matching `tags` is runnable, the request is refused with 400 and the message lists them.\n\nSkipped tests are not part of the run: they are not counted in `totalTests` and never change the run's `status`.\n\n**Name the app** with one of:\n\n- `buildId`: the `buildId` that `POST /uploadBuild` returned.\n- `build.meta.name`: the newest build uploaded under that name. Add `platform` if you upload your iOS and Android apps under the same name.\n- `bundleId` and `platform`: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation.\n\n**Choose the device** with `usePhysicalDevice`. MobileBoost picks the device itself, so `deviceConfigs`, `deviceProviderSettings`, `launchParams`, `testInputs`, `tagsQuery`, `iterations`, `metaData`, `stealthMode`, `dependencyTestIds` and the `ephemeralTest*` fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for.\n\n**Pass values to your tests** with `variables`: `NAME: value` pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation's environment variable of the same name for this run only. `variables` replaces `testInputs`. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation's environment variables (ENV Variables in the web app).\n\n**Authenticate** with your API key: `Authorization: Bearer mb_live_...`. `organisationId` must be the organisation the key belongs to. A request that sends `variables` or `tunnelName` needs the key even if your organisation does not otherwise require one.","deprecated":null,"version":null,"openapi":"/openapi.json post /tests/execute","href":"/api-reference/execute-tests","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n li: \"li\",\n p: \"p\",\n strong: \"strong\",\n ul: \"ul\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see \", _jsx(_components.code, {\n children: \"POST /tests/generate\"\n }), \").\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The call returns as soon as the run is created. Take \", _jsx(_components.code, {\n children: \"runId\"\n }), \" from the response and pass it to \", _jsx(_components.code, {\n children: \"GET /runs/{runId}\"\n }), \" to follow the run until its \", _jsx(_components.code, {\n children: \"status\"\n }), \" is \", _jsx(_components.code, {\n children: \"completed\"\n }), \" or \", _jsx(_components.code, {\n children: \"cancelled\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Choose the tests\"\n }), \" with \", _jsx(_components.code, {\n children: \"testIds\"\n }), \", \", _jsx(_components.code, {\n children: \"tags\"\n }), \", or both. A test is runnable on the run’s platform once its automation has been written and verified, which \", _jsx(_components.code, {\n children: \"GET /tests\"\n }), \" shows as \", _jsx(_components.code, {\n children: \"platforms.\u003cplatform>.runnable\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"A test you name in \", _jsx(_components.code, {\n children: \"testIds\"\n }), \" must be runnable. If it is not, the request is refused with 400.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"A test that only matches \", _jsx(_components.code, {\n children: \"tags\"\n }), \" and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in \", _jsx(_components.code, {\n children: \"skippedTests\"\n }), \" with the reason, and \", _jsx(_components.code, {\n children: \"warnings\"\n }), \" says how many were left out. If none of the tests matching \", _jsx(_components.code, {\n children: \"tags\"\n }), \" is runnable, the request is refused with 400 and the message lists them.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Skipped tests are not part of the run: they are not counted in \", _jsx(_components.code, {\n children: \"totalTests\"\n }), \" and never change the run’s \", _jsx(_components.code, {\n children: \"status\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Name the app\"\n }), \" with one of:\"]\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"buildId\"\n }), \": the \", _jsx(_components.code, {\n children: \"buildId\"\n }), \" that \", _jsx(_components.code, {\n children: \"POST /uploadBuild\"\n }), \" returned.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"build.meta.name\"\n }), \": the newest build uploaded under that name. Add \", _jsx(_components.code, {\n children: \"platform\"\n }), \" if you upload your iOS and Android apps under the same name.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"bundleId\"\n }), \" and \", _jsx(_components.code, {\n children: \"platform\"\n }), \": an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Choose the device\"\n }), \" with \", _jsx(_components.code, {\n children: \"usePhysicalDevice\"\n }), \". MobileBoost picks the device itself, so \", _jsx(_components.code, {\n children: \"deviceConfigs\"\n }), \", \", _jsx(_components.code, {\n children: \"deviceProviderSettings\"\n }), \", \", _jsx(_components.code, {\n children: \"launchParams\"\n }), \", \", _jsx(_components.code, {\n children: \"testInputs\"\n }), \", \", _jsx(_components.code, {\n children: \"tagsQuery\"\n }), \", \", _jsx(_components.code, {\n children: \"iterations\"\n }), \", \", _jsx(_components.code, {\n children: \"metaData\"\n }), \", \", _jsx(_components.code, {\n children: \"stealthMode\"\n }), \", \", _jsx(_components.code, {\n children: \"dependencyTestIds\"\n }), \" and the \", _jsx(_components.code, {\n children: \"ephemeralTest*\"\n }), \" fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Pass values to your tests\"\n }), \" with \", _jsx(_components.code, {\n children: \"variables\"\n }), \": \", _jsx(_components.code, {\n children: \"NAME: value\"\n }), \" pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation’s environment variable of the same name for this run only. \", _jsx(_components.code, {\n children: \"variables\"\n }), \" replaces \", _jsx(_components.code, {\n children: \"testInputs\"\n }), \". It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation’s environment variables (ENV Variables in the web app).\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Authenticate\"\n }), \" with your API key: \", _jsx(_components.code, {\n children: \"Authorization: Bearer mb_live_...\"\n }), \". \", _jsx(_components.code, {\n children: \"organisationId\"\n }), \" must be the organisation the key belongs to. A request that sends \", _jsx(_components.code, {\n children: \"variables\"\n }), \" or \", _jsx(_components.code, {\n children: \"tunnelName\"\n }), \" needs the key even if your organisation does not otherwise require one.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Execute tests","description":"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see `POST /tests/generate`).\n\nThe call returns as soon as the run is created. Take `runId` from the response and pass it to `GET /runs/{runId}` to follow the run until its `status` is `completed` or `cancelled`.\n\n**Choose the tests** with `testIds`, `tags`, or both. A test is runnable on the run's platform once its automation has been written and verified, which `GET /tests` shows as `platforms.\u003cplatform>.runnable`.\n\n- A test you name in `testIds` must be runnable. If it is not, the request is refused with 400.\n- A test that only matches `tags` and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in `skippedTests` with the reason, and `warnings` says how many were left out. If none of the tests matching `tags` is runnable, the request is refused with 400 and the message lists them.\n\nSkipped tests are not part of the run: they are not counted in `totalTests` and never change the run's `status`.\n\n**Name the app** with one of:\n\n- `buildId`: the `buildId` that `POST /uploadBuild` returned.\n- `build.meta.name`: the newest build uploaded under that name. Add `platform` if you upload your iOS and Android apps under the same name.\n- `bundleId` and `platform`: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation.\n\n**Choose the device** with `usePhysicalDevice`. MobileBoost picks the device itself, so `deviceConfigs`, `deviceProviderSettings`, `launchParams`, `testInputs`, `tagsQuery`, `iterations`, `metaData`, `stealthMode`, `dependencyTestIds` and the `ephemeralTest*` fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for.\n\n**Pass values to your tests** with `variables`: `NAME: value` pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation's environment variable of the same name for this run only. `variables` replaces `testInputs`. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation's environment variables (ENV Variables in the web app).\n\n**Authenticate** with your API key: `Authorization: Bearer mb_live_...`. `organisationId` must be the organisation the key belongs to. A request that sends `variables` or `tunnelName` needs the key even if your organisation does not otherwise require one.","deprecated":null,"version":null,"openapi":"/openapi.json post /tests/execute","href":"/api-reference/execute-tests","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"summary":"Execute tests","description":"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see `POST /tests/generate`).\n\nThe call returns as soon as the run is created. Take `runId` from the response and pass it to `GET /runs/{runId}` to follow the run until its `status` is `completed` or `cancelled`.\n\n**Choose the tests** with `testIds`, `tags`, or both. A test is runnable on the run's platform once its automation has been written and verified, which `GET /tests` shows as `platforms.\u003cplatform>.runnable`.\n\n- A test you name in `testIds` must be runnable. If it is not, the request is refused with 400.\n- A test that only matches `tags` and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in `skippedTests` with the reason, and `warnings` says how many were left out. If none of the tests matching `tags` is runnable, the request is refused with 400 and the message lists them.\n\nSkipped tests are not part of the run: they are not counted in `totalTests` and never change the run's `status`.\n\n**Name the app** with one of:\n\n- `buildId`: the `buildId` that `POST /uploadBuild` returned.\n- `build.meta.name`: the newest build uploaded under that name. Add `platform` if you upload your iOS and Android apps under the same name.\n- `bundleId` and `platform`: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation.\n\n**Choose the device** with `usePhysicalDevice`. MobileBoost picks the device itself, so `deviceConfigs`, `deviceProviderSettings`, `launchParams`, `testInputs`, `tagsQuery`, `iterations`, `metaData`, `stealthMode`, `dependencyTestIds` and the `ephemeralTest*` fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for.\n\n**Pass values to your tests** with `variables`: `NAME: value` pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation's environment variable of the same name for this run only. `variables` replaces `testInputs`. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation's environment variables (ENV Variables in the web app).\n\n**Authenticate** with your API key: `Authorization: Bearer mb_live_...`. `organisationId` must be the organisation the key belongs to. A request that sends `variables` or `tunnelName` needs the key even if your organisation does not otherwise require one.","operationId":"execute_tests","requestBody":"75cea234-12fe-4a43-8f86-a6b7affa0b09","responses":{"200":"2e1e8978-0fc4-4d2a-9518-0770cb3d1348","400":"4edcc31d-2c6f-4c75-9512-842afe66f063","401":"da83c58b-d963-4cd3-9320-a9840b845753","403":"46cd5e04-48ff-4724-80ab-8c6ebaac89f1","404":"5bafd6b9-294e-4676-95aa-cbe7386e93b8"},"method":"post","type":"path","servers":["31979921-3f5d-458f-a621-e5d47d63d435"],"security":["a850a53c-b5e8-41a3-aa4e-562819e828db"],"path":"/tests/execute","baseUrlOptions":["https://api.mobileboost.io"],"title":"Execute tests","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"content":{"application/json":{"schema":{"title":"ExecuteTest","required":["organisationId"],"type":"object","properties":{"organisationId":{"title":"Organisation ID","type":"string","description":"Your MobileBoost organisation ID. It must be the organisation your API key belongs to.","isRequired":true,"uniqueKey":"organisationId","typeLabel":"string"},"buildId":{"title":"Build ID","type":"string","description":"The build to test: the `buildId` that `POST /uploadBuild` returned. Send one of `buildId`, `build` or `bundleId`.","uniqueKey":"buildId","typeLabel":"string"},"build":{"title":"Build","required":["meta"],"type":"object","properties":{"meta":{"title":"BuildMeta","required":["name"],"type":"object","properties":{"name":{"title":"Name","type":"string","description":"The build name to look up. Add `platform` to the request if your iOS and Android builds share a name.","isRequired":true,"uniqueKey":"build.meta.name","typeLabel":"string"}},"isRequired":true,"uniqueKey":"build.meta","typeLabel":"BuildMeta · object"}},"description":"Test the newest build uploaded under a name instead of naming a `buildId`: `{\"meta\": {\"name\": \"my-app\"}}`. When you send both, `build` is used.","uniqueKey":"build","typeLabel":"Build · object"},"bundleId":{"title":"Bundle ID","type":"string","description":"Test the app with this bundle identifier that is already installed on your reserved device, instead of an uploaded build. Requires `platform`, always runs on a physical device, and has to be enabled for your organisation (403 otherwise). Cannot be combined with `buildId`.","uniqueKey":"bundleId","typeLabel":"string"},"platform":{"title":"Platform","type":"string","enum":["ios","android"],"description":"The platform to run on. Taken from the build when you send `buildId`. Required with `bundleId`. With `build`, it picks the newest build of that name for this platform.","uniqueKey":"platform","typeLabel":"enum\u003cstring>"},"testIds":{"title":"Test IDs","type":"array","items":{"type":"string","uniqueKey":"testIds.items.[INDEX]","typeLabel":"string"},"description":"IDs of the tests to run, as `GET /tests` returns them. Send `testIds`, `tags`, or both.","uniqueKey":"testIds","typeLabel":"string[]"},"tags":{"title":"Tags","type":"array","items":{"type":"string","uniqueKey":"tags.items.[INDEX]","typeLabel":"string"},"description":"Run every test that has at least one of these tags. Combined with `testIds`, the run contains both sets.","uniqueKey":"tags","typeLabel":"string[]"},"usePhysicalDevice":{"title":"Use physical device","type":"boolean","description":"`true` runs on a real handset reserved for your organisation, `false` on an emulator or simulator. Omit it to use your organisation's default: a real handset when you have one reserved for this platform, otherwise an emulator or simulator. An iOS `.ipa` build and a `bundleId` run always use a real handset.","uniqueKey":"usePhysicalDevice","typeLabel":"boolean"},"tunnelName":{"title":"Tunnel name","type":"string","description":"Name of a connected MobileBoost Local tunnel: the `--tunnel-name` you started `mb-local` with. The app on the device then reaches your internal hosts, such as a staging API, through it. Omit it when your app's backend is publicly reachable. An unknown or disconnected tunnel fails the run.","uniqueKey":"tunnelName","typeLabel":"string"},"trigger":{"title":"Trigger","type":"string","description":"A free-form label stored on the run to say what started it, for example `ci` or `nightly`. Defaults to `api`.","uniqueKey":"trigger","typeLabel":"string"},"variables":{"title":"Run variables","type":"object","additionalProperties":{"type":"string","uniqueKey":"variables.additionalProperties","typeLabel":"string"},"maxProperties":20,"description":"Values for this run's tests, as `NAME: value` pairs, for example the backend a canary test signs in against. Each test reads them as environment variables, and a value here wins over your organisation's environment variable of the same name for this run only. Names use upper case letters, digits and underscores and start with a letter; names the test runner relies on, such as `PATH` or anything starting with `PYTHON`, are refused. Values must be strings. Up to 20 per run. Requires your API key even if your organisation does not otherwise require one. Not for passwords or keys: values are kept with the run for 14 days, so keep credentials in your organisation's environment variables. Replaces `testInputs`.","example":{"API_BASE_URL":"https://canary-api.example.com"},"uniqueKey":"variables","typeLabel":"Run variables · object"}},"uniqueKey":"","typeLabel":"ExecuteTest · object"},"examples":{"byTestIds":{"title":"byTestIds","value":{"organisationId":"org123","buildId":"JbUOAOHLx99O2MYJc0LC","testIds":["xMIt964RUpAB95b6YI2F","teXiuNg4TLL9ioHIct5H"]}},"byTagsAndBuildName":{"title":"byTagsAndBuildName","value":{"organisationId":"org123","build":{"meta":{"name":"my-app"}},"platform":"android","tags":["smoke"],"usePhysicalDevice":false,"trigger":"ci"}},"installedApp":{"title":"installedApp","value":{"organisationId":"org123","bundleId":"com.example.app","platform":"ios","tags":["smoke"]}},"runVariables":{"title":"runVariables","value":{"organisationId":"org123","build":{"meta":{"name":"my-app"}},"platform":"android","tags":["canary"],"variables":{"API_BASE_URL":"https://canary-api.example.com"},"trigger":"ci"}}},"exampleType":"examples"}},"required":true,"exampleType":"examples"},"responses":{"2e1e8978-0fc4-4d2a-9518-0770cb3d1348":{"description":"The run was created. Its tests are queued on devices in the background.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"A human-readable message describing the result of the request.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"runId":{"type":"string","description":"The ID of the run. Pass it to `GET /runs/{runId}` to follow the run and read its results.","isRequired":true,"uniqueKey":"runId","typeLabel":"string"},"status":{"type":"string","description":"Always `running`: the run was accepted. Read its progress from `GET /runs/{runId}`.","isRequired":true,"uniqueKey":"status","typeLabel":"string"},"scheduledTests":{"type":"integer","description":"Number of tests the run started with.","uniqueKey":"scheduledTests","typeLabel":"integer"},"skippedTests":{"type":"array","items":{"title":"SkippedTest","type":"object","properties":{"testId":{"type":"string","description":"The ID of the test, as in `GET /tests`.","uniqueKey":"skippedTests.items.[INDEX].testId","typeLabel":"string"},"title":{"type":"string","description":"The test's title.","uniqueKey":"skippedTests.items.[INDEX].title","typeLabel":"string"},"platform":{"type":"string","description":"The run's platform, `ios` or `android`, which the test is not runnable on yet.","uniqueKey":"skippedTests.items.[INDEX].platform","typeLabel":"string"},"reason":{"type":"string","enum":["not_automated","generation_in_progress","generation_failed","generation_blocked","not_ready"],"description":"Why the test was skipped. `not_automated`: no automation has been generated for it yet. `generation_in_progress`: its automation for this platform is being written or is queued. `generation_failed`: writing it for this platform failed. `generation_blocked`: writing it stopped and is waiting on an answer from you. `not_ready`: it is not runnable on this platform for another reason.","uniqueKey":"skippedTests.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"detail":{"type":"string","description":"The reason as a sentence, for a log or a message.","uniqueKey":"skippedTests.items.[INDEX].detail","typeLabel":"string"}},"uniqueKey":"skippedTests.items.[INDEX]","typeLabel":"SkippedTest · object"},"description":"Tests that matched `tags` but are not runnable on this platform yet, so the run does not include them. Empty when every selected test was scheduled.","uniqueKey":"skippedTests","typeLabel":"SkippedTest · object[]"},"warnings":{"type":"array","items":{"type":"string","uniqueKey":"warnings.items.[INDEX]","typeLabel":"string"},"description":"Human-readable notes about the request, such as how many tests were skipped. Print them in your CI log. Empty when there is nothing to report.","uniqueKey":"warnings","typeLabel":"string[]"},"variables":{"type":"array","items":{"type":"string","uniqueKey":"variables.items.[INDEX]","typeLabel":"string"},"description":"The names of the `variables` the run received, sorted. Never their values. Present only when the request sent `variables`.","uniqueKey":"variables","typeLabel":"string[]"}},"required":["message","runId","status"],"uniqueKey":"","typeLabel":"object"},"examples":{"allScheduled":{"title":"allScheduled","value":{"message":"Autotest run created","runId":"b1111111df174791a93e560390ea7e65","status":"running","scheduledTests":12,"skippedTests":[],"warnings":[]}},"someSkipped":{"title":"someSkipped","value":{"message":"Autotest run created","runId":"b1111111df174791a93e560390ea7e65","status":"running","scheduledTests":11,"skippedTests":[{"testId":"xMIt964RUpAB95b6YI2F","title":"Checkout with a saved card","platform":"android","reason":"not_automated","detail":"No automation has been generated for this test yet."}],"warnings":["1 of 12 tests matching tags smoke was not scheduled on android: 1 not automated yet. They are listed in skippedTests."]}}},"exampleType":"examples"}},"exampleType":"examples"},"4edcc31d-2c6f-4c75-9512-842afe66f063":{"description":"The request cannot run as sent. The message says why, for example: an unsupported field such as `deviceConfigs` or `testInputs`; a name in `variables` that is not allowed, a value that is not a string, or more than 20 of them; both `buildId` and `bundleId`, or neither; `bundleId` without `platform`; no test matching `testIds` or `tags`; a test in `testIds` that is not runnable on this platform yet; or tests matching `tags` of which none is runnable yet, listed in the message.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"da83c58b-d963-4cd3-9320-a9840b845753":{"description":"The API key is missing or invalid, and your organisation requires one or the request sends `variables` or `tunnelName`, which always need one.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"46cd5e04-48ff-4724-80ab-8c6ebaac89f1":{"description":"The API key belongs to a different organisation, a test in `testIds` belongs to another organisation, or `bundleId` was sent but running without a build is not enabled for your organisation.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"5bafd6b9-294e-4676-95aa-cbe7386e93b8":{"description":"A test in `testIds` does not exist, or no build has been uploaded under `build.meta.name` (for `platform`, when given).","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}}},"security":{"a850a53c-b5e8-41a3-aa4e-562819e828db":{"BearerAuth":{"type":"http","scheme":"bearer","scopes":[],"schemeName":"BearerAuth"}}},"servers":{"31979921-3f5d-458f-a621-e5d47d63d435":{"url":"https://api.mobileboost.io"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","scopes":[],"schemeName":"BearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Bearer authentication header of the form `Bearer \u003ctoken>`, where `\u003ctoken>` is your auth token.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"BearerAuth","name":"Authorization"}],"title":"BearerAuth"}]},"originalFileLocation":"openapi.json"},"subdomain":"mobileboost-321ad6a9","siteName":"MobileBoost","title":"Execute tests - MobileBoost","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-07T21:00:15.221Z","originalFileLocation":"api-reference/execute-tests.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see POST /tests/generate). The call returns as soon as the run is created. Take runId from the response and pass it to GET /runs/{runId} to follow the run until its status is completed or cancelled. Choose the tests with testIds, tags, or both. A test is runnable on the run\u0026#x27;s platform once its automation has been written and verified, which GET /tests shows as platforms..runnable. - A test you name in testIds must be runnable. If it is not, the request is refused with 400. - A test that only matches tags and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in skippedTests with the reason, and warnings says how many were left out. If none of the tests matching tags is runnable, the request is refused with 400 and the message lists them. Skipped tests are not part of the run: they are not counted in totalTests and never change the run\u0026#x27;s status. Name the app with one of: - buildId: the buildId that POST /uploadBuild returned. - build.meta.name: the newest build uploaded under that name. Add platform if you upload your iOS and Android apps under the same name. - bundleId and platform: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation. Choose the device with usePhysicalDevice. MobileBoost picks the device itself, so deviceConfigs, deviceProviderSettings, launchParams, testInputs, tagsQuery, iterations, metaData, stealthMode, dependencyTestIds and the ephemeralTest* fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for. Pass values to your tests with variables: NAME: value pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation\u0026#x27;s environment variable of the same name for this run only. variables replaces testInputs. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation\u0026#x27;s environment variables (ENV Variables in the web app). Authenticate with your API key: Authorization: Bearer mb_live_.... organisationId must be the organisation the key belongs to. A request that sends variables or tunnelName needs the key even if your organisation does not otherwise require one.\">\u003cmeta data-mint-head name=\"application-name\" content=\"MobileBoost\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Execute tests - MobileBoost\">\u003cmeta data-mint-head property=\"og:description\" content=\"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see POST /tests/generate). The call returns as soon as the run is created. Take runId from the response and pass it to GET /runs/{runId} to follow the run until its status is completed or cancelled. Choose the tests with testIds, tags, or both. A test is runnable on the run\u0026#x27;s platform once its automation has been written and verified, which GET /tests shows as platforms..runnable. - A test you name in testIds must be runnable. If it is not, the request is refused with 400. - A test that only matches tags and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in skippedTests with the reason, and warnings says how many were left out. If none of the tests matching tags is runnable, the request is refused with 400 and the message lists them. Skipped tests are not part of the run: they are not counted in totalTests and never change the run\u0026#x27;s status. Name the app with one of: - buildId: the buildId that POST /uploadBuild returned. - build.meta.name: the newest build uploaded under that name. Add platform if you upload your iOS and Android apps under the same name. - bundleId and platform: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation. Choose the device with usePhysicalDevice. MobileBoost picks the device itself, so deviceConfigs, deviceProviderSettings, launchParams, testInputs, tagsQuery, iterations, metaData, stealthMode, dependencyTestIds and the ephemeralTest* fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for. Pass values to your tests with variables: NAME: value pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation\u0026#x27;s environment variable of the same name for this run only. variables replaces testInputs. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation\u0026#x27;s environment variables (ENV Variables in the web app). Authenticate with your API key: Authorization: Bearer mb_live_.... organisationId must be the organisation the key belongs to. A request that sends variables or tunnelName needs the key even if your organisation does not otherwise require one.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"MobileBoost\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.mobileboost.io/api-reference/execute-tests\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://mobileboost-321ad6a9.mintlify.site/_mintlify/api/og/v2?division=Tests\u0026amp;title=Execute+tests\u0026amp;description=Start+a+run+of+your+tests+on+MobileBoost+devices.+Each+test+runs+the+automation+code+MobileBoost+wrote+and+verified+for+it+%28see+%60POST+%2Ftests%2Fgenerate%60%29.%0A%0AThe+ca\u0026amp;theme=9bbbaeabc0a28eadb8dda608\u0026amp;signature=1e8cfe2c15692835b0457564fa7b6cdb3bba655af26764193d0d7fd78cc034a2\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Execute tests - MobileBoost\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see POST /tests/generate). The call returns as soon as the run is created. Take runId from the response and pass it to GET /runs/{runId} to follow the run until its status is completed or cancelled. Choose the tests with testIds, tags, or both. A test is runnable on the run\u0026#x27;s platform once its automation has been written and verified, which GET /tests shows as platforms..runnable. - A test you name in testIds must be runnable. If it is not, the request is refused with 400. - A test that only matches tags and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in skippedTests with the reason, and warnings says how many were left out. If none of the tests matching tags is runnable, the request is refused with 400 and the message lists them. Skipped tests are not part of the run: they are not counted in totalTests and never change the run\u0026#x27;s status. Name the app with one of: - buildId: the buildId that POST /uploadBuild returned. - build.meta.name: the newest build uploaded under that name. Add platform if you upload your iOS and Android apps under the same name. - bundleId and platform: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation. Choose the device with usePhysicalDevice. MobileBoost picks the device itself, so deviceConfigs, deviceProviderSettings, launchParams, testInputs, tagsQuery, iterations, metaData, stealthMode, dependencyTestIds and the ephemeralTest* fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for. Pass values to your tests with variables: NAME: value pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation\u0026#x27;s environment variable of the same name for this run only. variables replaces testInputs. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation\u0026#x27;s environment variables (ENV Variables in the web app). Authenticate with your API key: Authorization: Bearer mb_live_.... organisationId must be the organisation the key belongs to. A request that sends variables or tunnelName needs the key even if your organisation does not otherwise require one.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://mobileboost-321ad6a9.mintlify.site/_mintlify/api/og/v2?division=Tests\u0026amp;title=Execute+tests\u0026amp;description=Start+a+run+of+your+tests+on+MobileBoost+devices.+Each+test+runs+the+automation+code+MobileBoost+wrote+and+verified+for+it+%28see+%60POST+%2Ftests%2Fgenerate%60%29.%0A%0AThe+ca\u0026amp;theme=9bbbaeabc0a28eadb8dda608\u0026amp;signature=1e8cfe2c15692835b0457564fa7b6cdb3bba655af26764193d0d7fd78cc034a2\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/mobileboost-321ad6a9/OkIIS1ivp_fMe1gq/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"MobileBoost\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#16A34A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.mobileboost.io/api-reference/execute-tests\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/execute-tests.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.mobileboost.io/#organization\",\"name\":\"MobileBoost\",\"url\":\"https://docs.mobileboost.io\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/mobileboost-321ad6a9/OGuA69W71_lGnu9x/logo/light.png?fit=max\u0026auto=format\u0026n=OGuA69W71_lGnu9x\u0026q=85\u0026s=b6a6cc5ef5708fb7e589eb22c4e758e5\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.mobileboost.io#website\",\"name\":\"MobileBoost\",\"url\":\"https://docs.mobileboost.io\",\"publisher\":{\"@id\":\"https://docs.mobileboost.io/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.mobileboost.io/api-reference/execute-tests#webpage\",\"url\":\"https://docs.mobileboost.io/api-reference/execute-tests\",\"name\":\"Execute tests\",\"description\":\"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see POST /tests/generate). The call returns as soon as the run is created. Take runId from the response and pass it to GET /runs/{runId} to follow the run until its status is completed or cancelled. Choose the tests with testIds, tags, or both. A test is runnable on the run's platform once its automation has been written and verified, which GET /tests shows as platforms..runnable. - A test you name in testIds must be runnable. If it is not, the request is refused with 400. - A test that only matches tags and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in skippedTests with the reason, and warnings says how many were left out. If none of the tests matching tags is runnable, the request is refused with 400 and the message lists them. Skipped tests are not part of the run: they are not counted in totalTests and never change the run's status. Name the app with one of: - buildId: the buildId that POST /uploadBuild returned. - build.meta.name: the newest build uploaded under that name. Add platform if you upload your iOS and Android apps under the same name. - bundleId and platform: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation. Choose the device with usePhysicalDevice. MobileBoost picks the device itself, so deviceConfigs, deviceProviderSettings, launchParams, testInputs, tagsQuery, iterations, metaData, stealthMode, dependencyTestIds and the ephemeralTest* fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for. Pass values to your tests with variables: NAME: value pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation's environment variable of the same name for this run only. variables replaces testInputs. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation's environment variables (ENV Variables in the web app). Authenticate with your API key: Authorization: Bearer mb_live_.... organisationId must be the organisation the key belongs to. A request that sends variables or tunnelName needs the key even if your organisation does not otherwise require one.\",\"dateModified\":\"2026-10-07T21:00:15.221Z\",\"isPartOf\":{\"@id\":\"https://docs.mobileboost.io#website\"},\"breadcrumb\":{\"@id\":\"https://docs.mobileboost.io/api-reference/execute-tests#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.mobileboost.io/api-reference/execute-tests#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Tests\",\"item\":\"https://docs.mobileboost.io/api-reference/create-test\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Execute tests\",\"item\":\"https://docs.mobileboost.io/api-reference/execute-tests\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.mobileboost.io/api-reference/execute-tests#apireference\",\"headline\":\"Execute tests\",\"name\":\"Execute tests\",\"description\":\"Start a run of your tests on MobileBoost devices. Each test runs the automation code MobileBoost wrote and verified for it (see POST /tests/generate). The call returns as soon as the run is created. Take runId from the response and pass it to GET /runs/{runId} to follow the run until its status is completed or cancelled. Choose the tests with testIds, tags, or both. A test is runnable on the run's platform once its automation has been written and verified, which GET /tests shows as platforms..runnable. - A test you name in testIds must be runnable. If it is not, the request is refused with 400. - A test that only matches tags and is not runnable yet is skipped, and the rest of the run starts. The response lists each skipped test in skippedTests with the reason, and warnings says how many were left out. If none of the tests matching tags is runnable, the request is refused with 400 and the message lists them. Skipped tests are not part of the run: they are not counted in totalTests and never change the run's status. Name the app with one of: - buildId: the buildId that POST /uploadBuild returned. - build.meta.name: the newest build uploaded under that name. Add platform if you upload your iOS and Android apps under the same name. - bundleId and platform: an app that is already installed on your reserved device, with no build uploaded. This has to be enabled for your organisation. Choose the device with usePhysicalDevice. MobileBoost picks the device itself, so deviceConfigs, deviceProviderSettings, launchParams, testInputs, tagsQuery, iterations, metaData, stealthMode, dependencyTestIds and the ephemeralTest* fields are not supported. A request that sends any of them is refused with 400 rather than run on a device you did not ask for. Pass values to your tests with variables: NAME: value pairs, such as the backend a canary test signs in against. Each test in the run reads them as environment variables, and a value here wins over your organisation's environment variable of the same name for this run only. variables replaces testInputs. It is not for passwords or keys: the values are kept with the run for 14 days, so keep credentials in your organisation's environment variables (ENV Variables in the web app). Authenticate with your API key: Authorization: Bearer mb_live_.... organisationId must be the organisation the key belongs to. A request that sends variables or tunnelName needs the key even if your organisation does not otherwise require one.\",\"url\":\"https://docs.mobileboost.io/api-reference/execute-tests\",\"mainEntityOfPage\":{\"@id\":\"https://docs.mobileboost.io/api-reference/execute-tests#webpage\"},\"dateModified\":\"2026-10-07T21:00:15.221Z\",\"publisher\":{\"@id\":\"https://docs.mobileboost.io/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.mobileboost.io#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"MobileBoost\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"MobileBoost\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/execute-tests.md","siteName":"MobileBoost","nav":{"global":null,"tabs":[{"tab":"Test Agent","icon":"robot","pages":[{"title":"Test Agent","href":"/test-agent/overview"}]},{"tab":"Local Tooling","icon":"code","pages":[{"title":"Local Tooling","href":"/engineer-tooling/overview"}]},{"tab":"QA Studio","icon":"flask-vial","pages":[{"title":"QA Studio","href":"/qa-studio/build-requirements"}]},{"tab":"API","icon":"square-terminal","groups":[{"group":"Getting started","pages":[{"title":"Getting started","href":"/api/getting-started"},{"title":"Folders","href":"/api/folders"}]},{"group":"Tests","pages":[{"title":"Create test","deprecated":null,"version":null,"openapi":"/openapi.json post /tests","href":"/api-reference/create-test"},{"title":"Get tests","deprecated":null,"version":null,"openapi":"/openapi.json get /tests","href":"/api-reference/get-tests"},{"title":"Update test","deprecated":null,"version":null,"openapi":"/openapi.json patch /tests","href":"/api-reference/update-test"},{"title":"Delete test","description":"Delete one or more test cases by ID.","deprecated":null,"version":null,"openapi":"/openapi.json delete /tests","href":"/api-reference/delete-test"},{"title":"Execute tests","deprecated":null,"version":null,"openapi":"/openapi.json post /tests/execute","href":"/api-reference/execute-tests"},{"title":"Generate test automation","description":"Write the automation code for a test that has a description but no working test file yet. Explores the app on a device, writes the test, verifies it by running it several times in a row, and commits it to the organisation's test repository, after which the test is runnable via `POST /tests/execute`. By default this targets the newest build uploaded for every platform the organisation has one for, writing the platforms one after the other: the first creates the file, the next extends it with its own selectors. Pass `uploadId`, `bundleId`, or `platform` to narrow that. Generation is fire-and-forget: it queues on the organisation's existing device slots and the response returns as soon as the work is dispatched, not once it finishes; follow it under `platforms` on `GET /tests`.\n\n**Retrying one platform.** When `GET /tests` shows a test `ready` on one platform and `failed` or `blocked` on the other, call this with `platform` set to the one that needs writing again. The existing file is kept and extended for that platform. Both platforms share one file, so a test has one agent at a time: a request while either platform is still `generating` is refused with 409, naming the busy platform.","deprecated":null,"version":null,"openapi":"/openapi.json post /tests/generate","href":"/api-reference/generate-test-automation"}]},{"group":"Folders","pages":[{"title":"List folders","deprecated":null,"version":null,"openapi":"/openapi.json get /tests/folders","href":"/api-reference/list-folders"},{"title":"Create folder","deprecated":null,"version":null,"openapi":"/openapi.json post /tests/folders","href":"/api-reference/create-folder"},{"title":"Rename or move folder","deprecated":null,"version":null,"openapi":"/openapi.json patch /tests/folders","href":"/api-reference/rename-or-move-folder"},{"title":"Delete folder","deprecated":null,"version":null,"openapi":"/openapi.json delete /tests/folders","href":"/api-reference/delete-folder"},{"title":"Move tests into a folder","deprecated":null,"version":null,"openapi":"/openapi.json post /tests/folders/move","href":"/api-reference/move-tests-into-a-folder"}]},{"group":"Runs","pages":[{"title":"Get run status","deprecated":null,"version":null,"openapi":"/openapi.json get /runs/{runId}","href":"/api-reference/get-run-status"}]},{"group":"Builds","pages":[{"title":"Upload build","deprecated":null,"version":null,"openapi":"/openapi.json post /uploadBuild","href":"/api-reference/upload-build"}]},{"group":"Native Runners","pages":[{"title":"XCUITest","href":"/api/xcui-packaging"},{"title":"Espresso","href":"/api/espresso-packaging"}]},{"group":"Audit","pages":[{"title":"List audit logs","deprecated":null,"version":null,"openapi":"/openapi.json get /audit/logs","href":"/api-reference/list-audit-logs"}]},{"group":"Usage","pages":[{"title":"Get SDK session usage","deprecated":null,"version":null,"openapi":"/openapi.json get /usage/sdk-sessions","href":"/api-reference/get-sdk-session-usage"}]}]},{"tab":"Changelog","icon":"clock-rotate-left","pages":[{"title":"Changelog","href":"/changelog"}]}]},"basePath":"","title":"Execute tests - MobileBoost","buildId":"dpl_5joLUXmnJgwqjrHAS4dxZrQTdxgh","deploymentId":"dpl_5joLUXmnJgwqjrHAS4dxZrQTdxgh","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-DPDWPCdE.js","utils-DyjUHyLo.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-BWYE1cdS.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-COAzxpEw.js","snippetPresets-DNiD_S52.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-CjwVt80x.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-ByHQMk7z.js","shallow-CaZuw1AO.js","getApiPlaygroundDisplay-DPVPOknm.js","CodeSnippet-B31CH-Mp.js","CodeSnippets-BxTYZWz6.js","Page-DDHbuAIY.js","getPastedJson-DhoAwiNO.js","icon-Dhq8z75J.js","MethodPill-DLXmKOwr.js","DuplicateIcon-jzdVwyRU.js","createIcon-eD0b3klN.js","DynamicMarkdown-BfddVCX7.js","SectionHeading-2pSCIo17.js","axios-vUo_bRtp.js","Markdown-DsWjhwJ4.js","clsx-B2t_mZQG.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CUljsAY7.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-Cf70306N.js"]}