> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobilerun.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloud Quickstart

> Run your first autonomous task on a hosted device using the TypeScript SDK, Python, or cURL.

This guide takes you from zero to a completed cloud task. You will find a ready device, submit an
autonomous goal, wait for it to finish, and read the result. You can do this in **TypeScript**, in
**Python**, or with plain **cURL**.

Everything here uses the Mobilerun **Cloud**, which gives you hosted devices and a managed agent.
There is no local install, no adb, and no Portal APK. If you would rather run the open source
package on your own machine, follow the [Framework Quickstart](/framework/quickstart) instead.

## Prerequisites

* A Mobilerun account. You can sign up at [cloud.mobilerun.ai](https://cloud.mobilerun.ai).
* A **cloud API key** that starts with `dr_sk_` from the [API Keys](/api-keys) page. This is the
  only credential you need, because the agent's LLM usage is billed from your [credit](/credits)
  balance and you do **not** need your own model key.
* A **ready device**. You can connect your own phone with the
  [Portal app](/guides/connect-android), or provision a [Cloud Phone](/device-types#cloud-phone)
  or a [Physical Phone](/device-types#physical-phone) in the dashboard.

<Note>
  Autonomous tasks consume [credits](/credits) at roughly 0.5 credits per agent step. New accounts
  and device subscriptions include a monthly credit allowance.
</Note>

## 1. Set your API key

The examples below read your key from the `MOBILERUN_API_KEY` environment variable.

```bash theme={null}
export MOBILERUN_API_KEY=dr_sk_your_key_here
```

<Note>
  If you call `new Mobilerun()` without an `apiKey`, the TypeScript SDK auto-detects the
  `MOBILERUN_CLOUD_API_KEY` variable instead. The examples pass the key explicitly, so either name
  works.
</Note>

<Note>
  The TypeScript example uses top level `await`, so run it as an ES module. Set `"type": "module"`
  in your `package.json` or use a `.mts` file, and then run it with `npx tsx quickstart.ts`.
</Note>

## 2. Install

<CodeGroup>
  ```bash npm theme={null}
  npm install @mobilerun/sdk
  ```

  ```bash pip theme={null}
  # The Python example below uses only the standard requests library
  pip install requests
  ```
</CodeGroup>

## 3. Run your first task

Each example does the same four things. It lists a ready device, submits a task, polls until the
task finishes, and prints the result.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Mobilerun from '@mobilerun/sdk';

  // Pass your dr_sk_ key explicitly (or set MOBILERUN_CLOUD_API_KEY and call new Mobilerun())
  const client = new Mobilerun({ apiKey: process.env.MOBILERUN_API_KEY });

  // 1. Find a device that's ready to accept tasks
  const devices = await client.devices.list({ state: ['ready'] });
  const device = devices.items[0];
  if (!device) throw new Error('No ready device. Connect one in the dashboard first.');

  // 2. Submit an autonomous task
  const task = await client.tasks.run({
    deviceId: device.id,
    task: 'Open Settings and tell me the Android version',
    llmModel: 'mobilerun/mobile-agent-fast',
    maxSteps: 50,
  });
  console.log('Task started:', task.id);

  // 3. Wait for it to finish
  let status = await client.tasks.getStatus(task.id);
  while (!['completed', 'failed', 'cancelled'].includes(status.status)) {
    await new Promise((r) => setTimeout(r, 3000));
    status = await client.tasks.getStatus(task.id);
  }
  console.log('Final status:', status.status);

  // 4. Read the result from the trajectory
  const { trajectory } = await client.tasks.getTrajectory(task.id);
  const result = trajectory.find((e) => e.event === 'ResultEvent');
  console.log('Result:', result?.data);
  ```

  ```python Python theme={null}
  import os, time, requests

  API = "https://api.mobilerun.ai/v1"
  HEADERS = {
      "Authorization": f"Bearer {os.environ['MOBILERUN_API_KEY']}",
      "Content-Type": "application/json",
  }

  # 1. Find a device that's ready to accept tasks
  devices = requests.get(f"{API}/devices", headers=HEADERS, params={"state": "ready"}).json()
  device_id = devices["items"][0]["id"]

  # 2. Submit an autonomous task
  task = requests.post(
      f"{API}/tasks",
      headers=HEADERS,
      json={
          "deviceId": device_id,
          "task": "Open Settings and tell me the Android version",
          "llmModel": "mobilerun/mobile-agent-fast",
          "maxSteps": 50,
      },
  ).json()
  task_id = task["id"]
  print("Task started:", task_id)

  # 3. Poll until the task finishes
  while True:
      status = requests.get(f"{API}/tasks/{task_id}/status", headers=HEADERS).json()
      if status["status"] in ("completed", "failed", "cancelled"):
          break
      time.sleep(3)
  print("Final status:", status["status"])

  # 4. Read the result from the trajectory
  trajectory = requests.get(f"{API}/tasks/{task_id}/trajectory", headers=HEADERS).json()["trajectory"]
  result = next((e for e in trajectory if e["event"] == "ResultEvent"), None)
  print("Result:", result["data"] if result else None)
  ```

  ```bash cURL theme={null}
  # 1. Find a ready device and grab its id
  curl -s https://api.mobilerun.ai/v1/devices \
    -H "Authorization: Bearer $MOBILERUN_API_KEY" | jq '.items[0].id'

  # 2. Submit a task (use the device id from step 1)
  curl -s -X POST https://api.mobilerun.ai/v1/tasks \
    -H "Authorization: Bearer $MOBILERUN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "deviceId": "<DEVICE_ID>",
      "task": "Open Settings and tell me the Android version",
      "llmModel": "mobilerun/mobile-agent-fast",
      "maxSteps": 50
    }'

  # 3. Check status (use the task id returned in step 2)
  curl -s https://api.mobilerun.ai/v1/tasks/<TASK_ID>/status \
    -H "Authorization: Bearer $MOBILERUN_API_KEY"

  # 4. Once status is "completed", read the result from the trajectory
  curl -s https://api.mobilerun.ai/v1/tasks/<TASK_ID>/trajectory \
    -H "Authorization: Bearer $MOBILERUN_API_KEY" \
    | jq '.trajectory[] | select(.event == "ResultEvent") | .data'
  ```
</CodeGroup>

<Note>
  The trajectory is returned as `{ "trajectory": [ ... ] }`, which is an array of events. The final
  result is the event whose `event` field equals `"ResultEvent"`, and its `data` holds the fields
  `success`, `message`, `structured_output`, and `steps`. For data extraction tasks you can pass an
  `outputSchema` in JSON Schema form when you create the task, and then `structured_output` is
  populated with data matching it. See [Agent configuration](/agent#structured-output) for more.
</Note>

## Read the result without the trajectory

The trajectory is the full step by step record, which is useful when you want to inspect every
screenshot and action. For most tasks you do not need it, because the status endpoint already
returns the answer. A `GET /tasks/{id}/status` call returns the task outcome directly.

```json theme={null}
{
  "status": "completed",
  "succeeded": true,
  "message": "The Android version on your device is 15.",
  "output": null,
  "steps": 5
}
```

The `message` field holds the agent's natural language answer. The `output` field holds your
structured data when you submitted an `outputSchema`, and it is `null` otherwise. Because the
polling loop in step 3 already calls this endpoint, you can read `message` and `output` straight
from the final poll and skip the trajectory call entirely.

<Tip>
  Use the status endpoint for the answer and for polling. Reach for the trajectory only when you
  need the detailed run, such as the screenshots, the manager plan, or each executor action.
</Tip>

## Choosing a model

Pass `llmModel` to pick the model that drives the agent. Use one of the identifiers from the
[cloud model catalog](/agent#model-selection). For example, `mobilerun/mobile-agent-fast` is tuned
for speed and cost, while `mobilerun/mobile-agent-thinking` gives stronger reasoning for complex
flows. Omit the field to use your account default.

## Next steps

<CardGroup cols={2}>
  <Card title="Agent configuration" icon="sliders-horizontal" href="/agent">
    All task parameters, including models, vision, reasoning, stealth, memory, and structured
    output.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/tasks/run-task">
    Full REST schemas for every endpoint, with request and response examples.
  </Card>

  <Card title="MCP Server" icon="plug" href="/mcp-server">
    Drive Mobilerun from Cursor, Claude Desktop, and other MCP clients.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/webhooks">
    Get notified when tasks change state instead of polling.
  </Card>
</CardGroup>
