# Cloud Phone Live Streaming

Use either the Open API or Local API to upload one MP4 file, start live streaming, inspect its status, and stop it.

## API paths

| Operation | Open API | Local API |
|  --- | --- | --- |
| Query balance and quotas | `GET /balance` | `GET /api/balance` |
| Start streaming | `POST /cloudphone/live/start` | `POST /api/cloudphone/live/start` |
| Query streaming status | `POST /cloudphone/live/status` | `POST /api/cloudphone/live/status` |
| Stop streaming | `POST /cloudphone/live/end` | `POST /api/cloudphone/live/end` |


## Prerequisites

- Use a Cloud Phone model that supports live streaming. Other device models currently return `33401`.
- Power on the Cloud Phone before starting or stopping a stream.
- Obtain an OAuth2 Bearer token and permission to operate the Cloud Phone.
- Live-streaming files must be MP4 files uploaded with `uploadType=2`.


## Open API workflow

1. Call `POST /cloudphone/uploadUrl`, then upload the MP4 bytes to the returned `presignedUrl` with HTTP `PUT`.
2. Call `POST /cloudphone/uploadFile` with the uploaded object URL, destination directory, and `uploadType: 2`.
3. Poll `POST /cloudphone/uploadFileResult`. If `data` is `null`, the file is not visible yet; continue polling. Stop when `data.status` is `1` (success) or `2` (failed).
4. Keep the returned string `data.fileId` and send its exact numeric value as an `int64` to `POST /cloudphone/live/start`. Clients such as JavaScript must use an arbitrary-precision serializer instead of converting the value through `Number`.


```json
{
  "phoneId": 190000000000000001,
  "fileId": 820000000000000001
}
```

Use `POST /cloudphone/live/status` to check whether the stream is running, and `POST /cloudphone/live/end` to stop it. Both accept `{ "phoneId": 190000000000000001 }`.

## Local API workflow

1. Call `POST /api/cloudphone/upload/file/signedUrl`, then upload the MP4 bytes to the returned `presignedUrl` with HTTP `PUT`.
2. Call `POST /api/cloudphone/upload/file` with the uploaded object URL, destination directory, and `uploadType: 2`.
3. Poll `POST /api/cloudphone/upload/file/result`. If `data` is `null`, continue polling; stop when `data.status` is `1` or `2`.
4. Send the exact numeric value of the returned `data.fileId` to `POST /api/cloudphone/live/start`. Use `/api/cloudphone/live/status` and `/api/cloudphone/live/end` to inspect or stop the stream.


See the [Cloud Phone Open API](/api-reference/cloud-phone/open-api) and [Cloud Phone Local API](/api-reference/cloud-phone/local-api) for complete schemas.

## Retry and error handling

If a start request times out, query the status before retrying. Do not assume that a timeout means the stream did not start.

| Code | Meaning |
|  --- | --- |
| `33300` | Cloud Phone does not exist |
| `33301` | Cloud Phone is not powered on |
| `33401` | This Cloud Phone does not support live streaming |
| `33418` | Live-streaming file does not exist or is no longer valid |
| `33419` | `/cloudphone/uploadFile` rejected a live-streaming file that is not MP4 |
| `99002` | The current member cannot operate this Cloud Phone |