GET/v1/me
Identify the workspace and scopes behind the key. Use it to check a key works.
The same operations as the MCP tools, over plain HTTPS and JSON. The API is in preview, so expect additions.
https://api.distilled.cxAuthorization: Bearer dk_live_a1b2c3d4e5f6g7h8_<secret>Every call needs an API key. A key carries scopes, and each endpoint lists the scope it needs. Check a key with:
curl https://api.distilled.cx/v1/me -H "Authorization: Bearer $DISTILLED_API_KEY"| Scope | Grants |
|---|---|
phones:read | List phones and read their state. |
phones:write | Allocate phones onto the rack. |
apps:write | Install an app on a phone. |
runs:read | List and inspect runs, and read their events. |
runs:write | Start and stop runs. |
skills:read | List registered skills and cohorts. |
skills:write | Create, change, and delete skills and cohorts. |
Send an Idempotency-Key header on calls that change state to make retries safe. Reusing a key with a different body returns idempotency_conflict. On rate_limited, wait for the Retry-After header.
/v1/meIdentify the workspace and scopes behind the key. Use it to check a key works.
/v1/phonesEvery phone in the workspace.
/v1/phones/:id/appsApps installed on a phone that a run can open. The catalogue is what you may install; this is what is there now.
/v1/phones/allocateClaim phones from the warm pool, up to the workspace quota.
| Field | Type | Description |
|---|---|---|
count | integer | How many phones to claim, 1 to 20. Default 1. |
device | string | Device profile, such as pixel8pro. |
region | string | Where the phone should run. |
/v1/phones/:idOne phone by id.
| Field | Type | Description |
|---|---|---|
idrequired | string | Phone id. |
/v1/phones/:id/releaseHand a phone back to the pool. It leaves the workspace at once and is wiped and re-identified before anyone can claim it again.
| Field | Type | Description |
|---|---|---|
idrequired | string | Phone id. |
/v1/apps/searchSearch the app catalogue.
| Field | Type | Description |
|---|---|---|
qrequired | string | Search text, as a query parameter. |
/v1/apps/:pkgOne catalogue app by Android package name.
| Field | Type | Description |
|---|---|---|
pkgrequired | string | Android package, such as com.example.app. |
/v1/apps/installInstall a pinned app on chosen phones. Returns a run you can poll or stream.
| Field | Type | Description |
|---|---|---|
pkgrequired | string | Android package to install. |
phones | string[] | Phone ids to install on. Omit to target every phone in the workspace. |
/v1/skillsRegistered workflows.
/v1/skillsRegister a workflow. The block list is validated, with depth and size limits.
| Field | Type | Description |
|---|---|---|
namerequired | string | What the workflow is called. |
apprequired | string | Android package the workflow drives. |
intent | string | One sentence on what the workflow is for. |
workflowrequired | object[] | The blocks to run: step, wait, repeat, or if. |
guardrails | object | Time limit, stop conditions, and phone cap. |
risk | string | low, medium, or high. |
targetCohort | string | Cohort the workflow is meant for. |
/v1/skills/:id/enabledEnable or disable a registered workflow without deleting it.
| Field | Type | Description |
|---|---|---|
idrequired | string | Skill id. |
enabledrequired | boolean | Whether runs may use it. |
/v1/skills/:idDelete a registered workflow.
| Field | Type | Description |
|---|---|---|
idrequired | string | Skill id. |
/v1/cohortsSaved groups used to target runs.
/v1/cohortsSave a group of phones by region or device to target later.
| Field | Type | Description |
|---|---|---|
namerequired | string | Unique within the workspace. |
filter | object | Any of region (US or EU), model (device profile id), and app (Android package). |
/v1/cohorts/:idDelete a cohort.
| Field | Type | Description |
|---|---|---|
idrequired | string | Cohort id. |
/v1/cohorts/:id/phonesThe phones a cohort currently matches.
| Field | Type | Description |
|---|---|---|
idrequired | string | Cohort id. |
/v1/runsRecent runs, newest first.
/v1/runsStart a run. It returns immediately; poll the run or stream its events.
| Field | Type | Description |
|---|---|---|
skillrequired | string | object | A registered skill id, or a workflow defined inline. |
target | string | Cohort name. Omit to target every live phone. |
phones | string[] | Phone ids, instead of a cohort. |
/v1/runs/:idOne run, with its per-step state.
| Field | Type | Description |
|---|---|---|
idrequired | string | Run id. |
/v1/runs/:id/eventsServer-sent events for a run. Resume with Last-Event-ID.
| Field | Type | Description |
|---|---|---|
idrequired | string | Run id. |
/v1/runs/:id/stopStop a run that is still going.
| Field | Type | Description |
|---|---|---|
idrequired | string | Run id. |
Failures return a JSON body with a stable code.
| Code | Meaning |
|---|---|
invalid_request | The body or a parameter failed validation. |
unauthorized | The key is missing, malformed, revoked, or expired. |
insufficient_scope | The key is valid but lacks the scope this call needs. |
not_invited | The account is not a member of an active workspace. |
not_found | No such resource in this workspace. |
idempotency_conflict | The same Idempotency-Key was reused with a different body. |
capacity_unavailable | No phone was free to claim. |
quota_exceeded | The workspace is at its phone quota. |
rate_limited | Too many calls. Retry after the Retry-After header. |
unavailable | A dependency is down. Retrying is safe. |