Search

Integrate

Android Automation REST API: Runs, Cloud Devices, Profiles

Call the MAS Android automation REST API with an API key for run history, cloud device runs, code sync, device lists, settings profiles, proxies and webhooks.

  • Windows
  • Mac
  • Emulator
  • Cloud device
  • API
Advanced Updated 12 min read
On this page
  1. Authenticate to the Android automation API
  2. OpenAPI document
  3. Runs and macro run history
  4. GET /api/executions
  5. GET /api/executions/${id}
  6. GET /api/executions/${execution_id}/logs
  7. Cloud runs: run a macro through the API
  8. POST /api/hosted/devices/${id}/run
  9. POST /api/hosted/runs/${id}/stop
  10. GET /api/hosted/runs/${id}
  11. Code sync
  12. GET /api/macros/${id}/code-state
  13. POST /api/macros/${id}/code-snapshot
  14. Devices and groups
  15. GET /api/emulator/devices
  16. GET /api/emulator/groups
  17. Settings profiles
  18. GET /api/macro-setting-profiles
  19. POST /api/macro-setting-profiles
  20. PUT /api/macro-setting-profiles/${id}
  21. DELETE /api/macro-setting-profiles/${id}
  22. Proxies
  23. POST /api/proxy
  24. GET /api/proxy
  25. POST /api/proxy/import
  26. GET, PUT and DELETE /api/proxy/${id}
  27. POST /api/proxy/${id}/validate
  28. POST /api/proxy/assignments
  29. GET /api/proxy/assignments
  30. GET /api/proxy/devices/${device_id}
  31. DELETE /api/proxy/assignments/${id}
  32. GET /api/proxy/assignments/${id}/connection-info
  33. GET /api/proxy/usage
  34. Webhooks
  35. GET /api/webhooks
  36. POST /api/webhooks
  37. GET, PUT and DELETE /api/webhooks/${id}
  38. POST /api/webhooks/${id}/regenerate-secret
  39. POST /api/webhooks/${id}/test
  40. GET /api/webhooks/deliveries
  41. GET /api/webhooks/deliveries/${id}
  42. POST /api/webhooks/deliveries/${id}/redeliver
  43. App-only

The Macro Automation Studio (MAS) REST API is the Android automation API you can call with an API key. It covers what an integration needs: the history of your runs, starting and stopping macro runs on cloud devices, syncing code before a cloud run, listing your devices and groups, and managing settings profiles, proxies and webhooks. Everything else stays in the app. This page lists every route that accepts a key, with the fields you send and the fields you get back.

Authenticate to the Android automation API

Send your key in an X-API-KEY header on every request. The base URL is https://api.automationmacro.com. Bodies and responses are JSON. Create keys on the API Keys page in the app; the API keys page explains expiry, the 25 active key limit, the rate limit of 120 requests per minute per key and 300 per user, and the 402 you get without an active subscription. For an AI client, the MCP server is the better door and takes the same key.

bash
curl -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/executions

A key acts as the person who created it and ignores the scopes chosen at creation; scopes matter only to the MCP server. Auth failures use one envelope, {"message": "...", "details": {"code": "..."}}, with status 401, 402 or 429. Validation failures return 422 with a message that says what was wrong. A resource that belongs to someone else answers 404, never 403, so ids cannot be probed.

Paged lists share one shape: page, page_size, total_rows, total_pages and rows. Pages start at 1 and page_size defaults to 50 with a maximum of 200.

OpenAPI document

The backend publishes its own OpenAPI document at https://api.automationmacro.com/openapi.json, with /openapi.yaml next to it and an interactive viewer at /docs on the same host. No auth is needed to read it. It describes every route, including the app-only ones; the routes on this page are the ones whose security lists apiKey.

Runs and macro run history

Every macro run, on a local device or a cloud device, is recorded on the server: the app reports local runs and the cloud runner reports its own. These routes read that history. Reporting itself is app-only.

GET /api/executions

Lists your runs, newest first.

Query fieldMeaning
statusrunning, completed, failed or stopped
device_id, macro_idFilter by device or macro id
since, untilRFC 3339 timestamps; runs started at or after since and at or before until
page, page_sizePaging; page_size defaults to 50, maximum 200
bash
curl -H "X-API-KEY: mas_your_key" \
  "https://api.automationmacro.com/api/executions?status=failed&since=2026-09-01T00:00:00Z"

Each row carries id, execution_id, status, macro_id, macro_name, device_id, device_name, device_port, group_id, execution_type (block or python), started_at, ended_at, duration_ms, exit_code, error_message, proxy_exit_ip and proxy_country. Optional fields are omitted when empty. duration_ms is computed on the server from the start and end times.

GET /api/executions/{id}

Returns one run by its numeric id from the list. The response is a single row with the fields above.

bash
curl -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/executions/1842

GET /api/executions/{execution_id}/logs

Returns the output of one of your runs by its string execution_id. Logs are shipped from cloud runs; local runs keep their output in the app.

Query fieldMeaning
max_linesNewest lines to return, 1 to 1000, default 200
since_seqCursor: only lines from batches after this sequence number; 0 or absent returns the newest window
bash
curl -H "X-API-KEY: mas_your_key" \
  "https://api.automationmacro.com/api/executions/hosted-12-abc/logs?max_lines=100"

The response holds execution_id, lines (oldest first) and last_seq. Pass last_seq back as since_seq to read only what is new.

Cloud runs: run a macro through the API

A cloud device runs its macros server-side, so you can start and stop them without the app. The device must be one of your cloud devices; a local device answers 404 with a message that it is not a cloud device. Creating, starting, stopping and deleting cloud devices is app-only; see Cloud devices.

POST /api/hosted/devices/{id}/run

Starts a macro on cloud device {id}. The device boots first if it is stopped. The call returns as soon as the run is launching; poll it for state.

Body fieldMeaning
macro_idThe macro to run
argsOptional. Overrides the device’s stored arguments for this run only, keyed by argument name
bash
curl -X POST -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"macro_id": 123, "args": {"rounds": 5}}' \
  https://api.automationmacro.com/api/hosted/devices/45/run

The response is the run: id, execution_id, device_id, macro_id, state, state_message, started_at, finished_at, bundle_sha and code_ref. state moves through launching, running, then finished or failed, with stopping while a stop is in flight. A device that already has an active run answers 409. When server-side runs are not available, the route answers 503.

POST /api/hosted/runs/{id}/stop

Stops run {id}. The device stays on. Returns the run with its new state.

bash
curl -X POST -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/hosted/runs/981/stop

GET /api/hosted/runs/{id}

Returns the orchestration state of run {id}, the same fields as the start response. The business outcome, exit code and duration live in the runs history under the same execution_id.

bash
curl -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/hosted/runs/981

Code sync

A cloud run executes a snapshot of the macro’s working tree, not the git repository. The app uploads a snapshot before each cloud run when the code changed, so most integrations never call these routes; they exist so your own tooling can check what the server has and refresh it. See Git and code sync.

GET /api/macros/{id}/code-state

Returns the current snapshot of macro {id}: worktree_hash, entry_path, size_bytes, file_count and created_at. A 404 means the macro has never been synced.

bash
curl -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/macros/123/code-state

POST /api/macros/{id}/code-snapshot

Uploads a working tree as a snapshot.

Body fieldMeaning
zip_file_base64Required. The project tree as a zip, base64-encoded
worktree_hashRequired. The content hash the server recomputes from the zip; a mismatch is rejected
entry_pathOptional, for example src/app.py. When empty the server derives it: src/app.py, then any main.py, then the first .py file

The request body is limited to 16 MiB, which carries a 10 MiB zip. The response carries worktree_hash, entry_path, entry_kind, image_ids (the image library ids the code references), warnings, size_bytes, file_count and created, which is false when the same hash already existed. The hash is a digest over the per-file manifest the app computes; the simplest way to refresh a snapshot is to open the macro in the app and run it on the cloud device once.

Devices and groups

Two read-only lists so an integration can discover the ids that other routes need. Creating, editing and deleting devices and groups, and starting a local device, are app-only.

GET /api/emulator/devices

Lists your devices.

Query fieldMeaning
macro_id, group_idFilter by the assigned macro or the group
nameCase-insensitive substring match on the device name
sort, page, page_sizePaging; page_size up to 200
bash
curl -H "X-API-KEY: mas_your_key" "https://api.automationmacro.com/api/emulator/devices?group_id=7"

Each row carries id, name, port, macro_id, group_id, run_count, is_hosted and, for a cloud device, hosted_state (stopped, placing, starting, ready, stopping or error).

GET /api/emulator/groups

Lists your device groups. Query fields are name, description, sort, page and page_size.

bash
curl -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/emulator/groups

Each row carries id, name, description, kind (byod for devices on your own machine, cloud for cloud devices), no_of_devices, created_at and updated_at.

Settings profiles

A settings profile is a named bundle of arguments for one code macro that devices follow. Every macro has a Default profile that cannot be renamed or deleted. Editing a profile changes the next run of every device that follows it. See Settings profiles.

A profile carries id, macro_id, name, args, is_default, devices_using and updated_at. args has the same shape as a device’s own script arguments: values keyed by argument name, plus the pre-rendered __cli_args__ command line where the app stored one. args may not exceed 64 KB.

GET /api/macro-setting-profiles

Lists the profiles of one macro. macro_id is required. The list always includes Default, which is created on first read.

bash
curl -H "X-API-KEY: mas_your_key" "https://api.automationmacro.com/api/macro-setting-profiles?macro_id=123"

The response is items, an array of profiles.

POST /api/macro-setting-profiles

Creates a profile. Body: macro_id, name (1 to 100 characters, unique per macro; Default is reserved) and optional args.

bash
curl -X POST -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"macro_id": 123, "name": "Night shift", "args": {"rounds": 20, "sleep_s": 3}}' \
  https://api.automationmacro.com/api/macro-setting-profiles

Returns the profile. A name already in use answers 409; a macro that is not yours or not a code macro answers 404.

PUT /api/macro-setting-profiles/{id}

Renames a profile, replaces its args, or both. Body: name and/or args; args replaces the whole set. Renaming Default is refused.

bash
curl -X PUT -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"args": {"rounds": 30}}' \
  https://api.automationmacro.com/api/macro-setting-profiles/58

DELETE /api/macro-setting-profiles/{id}

Deletes a profile. Devices that followed it are repointed to Default. The response carries deleted and repointed_to, the id of that Default profile. Deleting Default is refused.

bash
curl -X DELETE -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/macro-setting-profiles/58

Proxies

Proxies give each device its own exit IP. The API manages the proxy records, attaches them to devices and reads traffic totals; the app applies them at run time. See Proxies. Passwords are accepted on create and never returned by any route except connection-info with include_secrets.

A proxy record carries id, mode (byop for your own proxy or managed), label, scheme, host, port, username, session_type, gateway, a targeting object (countries, exclude_countries, state, city, zip, asn, exclude_asn), and the results of the last check: status (unchecked, live or dead), last_check_at, last_exit_ip, last_exit_country, last_latency_ms, last_error and created_at.

POST /api/proxy

Adds a proxy. Body: host and port (1 to 65535) are required; scheme is http, https or socks5 and defaults to http; label, username, password and gateway are optional. For a gateway proxy you can also send target_countries, exclude_countries, target_state, target_city, target_zip, target_asn and exclude_asn; a plain proxy ignores them.

bash
curl -X POST -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"label": "farm-1", "scheme": "socks5", "host": "proxy.example.net", "port": 1080, "username": "user", "password": "secret"}' \
  https://api.automationmacro.com/api/proxy

GET /api/proxy

Lists your proxies. Query: mode, status, page, page_size. Paged.

POST /api/proxy/import

Bulk-adds proxies. Body: proxies, one per line, as host:port, host:port:user:pass or scheme://user:pass@host:port. The response carries created_count, error_count, created and errors, each error with line, raw and reason.

bash
curl -X POST -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"proxies": "10.0.0.1:8080:alice:pw\nsocks5://bob:pw@10.0.0.2:1080"}' \
  https://api.automationmacro.com/api/proxy/import

GET, PUT and DELETE /api/proxy/{id}

GET returns one proxy. PUT updates label and, when present, replaces the whole targeting object. DELETE removes the proxy.

bash
curl -X PUT -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"label": "farm-1-eu", "targeting": {"countries": "de,nl"}}' \
  https://api.automationmacro.com/api/proxy/17

POST /api/proxy/{id}/validate

Tests the proxy from the server and stores the result. Returns proxy_id, status, reachable, latency_ms, exit_ip, country, city, asn and error.

bash
curl -X POST -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/proxy/17/validate

POST /api/proxy/assignments

Attaches a proxy to a device. Body: proxy_id, emulator_device_id (from the devices list) and optional session_type, sticky or rotating. Returns the assignment: id, proxy_id, proxy, emulator_device_id, device_name, device_port, session_id, session_type, active and created_at.

bash
curl -X POST -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"proxy_id": 17, "emulator_device_id": 45, "session_type": "sticky"}' \
  https://api.automationmacro.com/api/proxy/assignments

GET /api/proxy/assignments

Lists active assignments as items and total.

GET /api/proxy/devices/{device_id}

Returns the assignment attached to one device, in the same items shape. A device with no proxy returns an empty list, not 404.

DELETE /api/proxy/assignments/{id}

Removes an assignment and returns the remaining list.

GET /api/proxy/assignments/{id}/connection-info

Returns what a device needs to use the proxy: scheme, host, port, username, password, session_id, session_type, secrets_revealed and a relay recipe. The password is masked unless you pass include_secrets=true, and every reveal is written to the audit log with the key that asked.

bash
curl -H "X-API-KEY: mas_your_key" \
  "https://api.automationmacro.com/api/proxy/assignments/9/connection-info?include_secrets=true"

GET /api/proxy/usage

Returns traffic routed through your proxies. Query: period, one of today (default), week, month or all. The response carries period, since, items per proxy, devices per device, groups per group, and the totals bytes_up, bytes_down and bytes_total. Reporting usage (POST /api/proxy/usage) is app-only.

bash
curl -H "X-API-KEY: mas_your_key" "https://api.automationmacro.com/api/proxy/usage?period=week"

Webhooks

Webhook endpoints receive a signed POST when a macro starts, completes, fails or stops, and when a script emits a custom event. The Webhooks page covers payloads, signatures and retries; these routes manage the endpoints and read the delivery log.

An endpoint carries id, url, description, event_types, secret_prefix, scope_mode (all, groups or devices), scope_group_ids, scope_device_ids, scope_device_count, enabled, consecutive_failures, disabled_reason, last_success_at and created_at. An account can hold up to 10 endpoints.

GET /api/webhooks

Lists your endpoints as items and total.

POST /api/webhooks

Registers an endpoint. Body: url (HTTPS; private and internal addresses are refused), optional description (up to 255 characters), event_types (defaults to ["*"]), and the scope fields scope_mode, scope_group_ids and scope_device_ids. A narrowed scope must name at least one group or device.

bash
curl -X POST -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/hooks/mas", "description": "Alerts", "event_types": ["macro.failed", "custom.*"], "scope_mode": "groups", "scope_group_ids": [7]}' \
  https://api.automationmacro.com/api/webhooks

The response carries secret, the signing secret shown once, plus endpoint and warning.

GET, PUT and DELETE /api/webhooks/{id}

GET returns one endpoint. PUT updates any of url, description, event_types, enabled, and the scope fields; omit scope_mode to leave the scope unchanged. Setting enabled to true clears the failure streak of an auto-disabled endpoint. DELETE removes the endpoint and returns the remaining list; its delivery history stays readable.

bash
curl -X PUT -H "X-API-KEY: mas_your_key" -H "Content-Type: application/json" \
  -d '{"enabled": true}' https://api.automationmacro.com/api/webhooks/4

POST /api/webhooks/{id}/regenerate-secret

Issues a new signing secret and returns it once. Deliveries are signed with the new secret at once, so update your receiver first.

POST /api/webhooks/{id}/test

Queues a webhook.test event to the endpoint, regardless of its subscriptions. Returns queued, event_id and message.

bash
curl -X POST -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/webhooks/4/test

GET /api/webhooks/deliveries

Lists delivery attempts, newest first. Query: endpoint_id, status (pending, succeeded, failed or exhausted), page, page_size. Each row carries id, endpoint_id, event_id, event_type, status, attempts, next_attempt_at (only while pending), last_status_code, last_error, last_response_body, delivered_at and created_at.

bash
curl -H "X-API-KEY: mas_your_key" \
  "https://api.automationmacro.com/api/webhooks/deliveries?endpoint_id=4&status=exhausted"

GET /api/webhooks/deliveries/{id}

Returns one delivery with the same fields plus payload, the exact body that was sent.

POST /api/webhooks/deliveries/{id}/redeliver

Queues the delivery again and returns it. Use it after fixing your receiver.

bash
curl -X POST -H "X-API-KEY: mas_your_key" https://api.automationmacro.com/api/webhooks/deliveries/512/redeliver

Emitting a custom event (POST /api/webhooks/events) is app-only; scripts emit events with mas.webhook() and the app relays them.

App-only

The following never accept a key and are reached only from the signed-in app: macro creation, editing and deletion; the scheduler; the marketplace; the cloud device lifecycle (create, start, stop, delete, live view, screenshots, APK installs); billing and subscriptions; MAS Agent sessions; API key management; execution reporting; proxy usage reporting; and custom webhook events. Devices and groups can be listed with a key but not changed.

Next steps

Related pages

Was this page helpful?

Questions? Ask in Discord