# Media Pull Overview (/en/api-reference/api-ref/media-pull)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

**The RESTful API for Media Pull** enables you to inject an online media stream into the Agora channel as a live video source. After the injection succeeds, the online media stream automatically plays in the Agora channel, and remote users can see the content of the media stream.

## Working principle [#working-principle]

Injecting an online media stream into the Agora channel creates a Media Pull task (shown as "cloud player" in the rest of the article) in the Agora channel. You can control the cloud player through the RESTful API and accomplish the following functions for Media Pull:

* `Create`: Creates a cloud player in the project.
* `Delete`: Destroys the cloud player in the project.
* `List`: Queries and lists all the cloud players in the project.

Media Pull supports the following formats:

* Video codec formats: H.264, H.265, and VP9
* Audio codec formats: AAC and OPUS
* Protocols: HTTPS and RTMP
* Container formats: FLV, MP4, MPEG-TS, Matroska (MKV), and HLS

## Authentication [#authentication]

The RESTful APIs require basic HTTP authentication. You need to set the `Authorization` parameter in every HTTP request header. For how to get the value for Authorization, see [RESTful API authentication](./restful-authentication).

## Create API [#create-api]

This API creates a cloud player in the project.

### HTTP request [#http-request]

```bash
POST https://api.agora.io/{region}/v1/projects/{appId}/cloud-player/players
```

<CalloutContainer type="warning">
  <CalloutDescription>
    The Agora RESTful API only supports HTTPS with TLS 1.0, 1.1, or 1.2 for encrypted communication. Requests over plain HTTP are not supported and will fail to connect.
  </CalloutDescription>
</CalloutContainer>

#### Path parameters [#path-parameters]

* `appId`: (Required) String. Agora provides the [App ID](/en/realtime-media/media-pull/reference/glossary#app-id) when you create a **project** in Agora Console. The App ID identifies each project.
* `region`: (Required) String. The region that the cloud player was created in. Agora supports the creation of cloud players in different regions. Currently, it supports four regions:
* `cn`: China Mainland
* `ap`: Asia Pacific
* `na`: North America
* `eu`: Europe

<CalloutContainer type="info">
  <CalloutDescription>
    Please ensure that the region you set is the same region as where your media stream originates is located.
  </CalloutDescription>
</CalloutContainer>

#### Query parameters [#query-parameters]

A sample request URL when using query parameters:

```bash
https://api.agora.io/{region}/v1/projects/{appId}/cloud-player/players?streamIp={streamIp}
```

`streamIp`: (Optional) String. The IP address of the media stream's origin server. Must be a valid IPv4 address. Use this parameter to ensure the transmission quality of the media stream when the media stream is only available in some regions. Otherwise, ignore this parameter.

#### Request header [#request-header]

The request header contains the following fields:

* `Content-Type`: `application/json`
* `Authorization`: See [Authentication instructions](./restful-authentication).
* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. After passing in the field, the Agora SDRTN<sup>®</sup> returns it in the response header.
  Best practice is to use this field. If you do not pass in any value, the Agora SDRTN<sup>®</sup> automatically generates a UUID to pass in.

#### Request body [#request-body]

If the status code is 2XX, the request succeeds.

<CalloutContainer type="info">
  <CalloutDescription>
    * You must set the cloud player's username, which can be a Number or String. Otherwise, the cloud player cannot be created, and Agora's server returns the `400 (Bad Request)` status code. Ensure that you have read [How can I use a username in string type?](/en/api-reference/faq/integration/string_uid) when using a username in String type.
    * To avoid failed requests, do not pass `null` or `""` in the required fields.
  </CalloutDescription>
</CalloutContainer>

The response body is a JSON Object called `player`, containing the following fields:

* `audioOptions`: (Optional) JSON Object. The audio transcoding configuration of the cloud player. Setting this field to empty or not set means that the audio is not transcoded.
* `Profile`：Number. Audio profile. Sets the audio profile sample rate, bitrate, encoding mode, and the number of channels.
  * `0`: Default audio profile.
    * In the communication profile, the default audio profile represents a sample rate of 32 kHz, audio encoding, mono, and a bitrate of up to 18 Kbps.
    * In the live broadcasting profile, the default audio profile represents a sample rate of 48 kHz, music encoding, mono, and a bitrate of up to 64 Kbps.
  * `1`: SPEECH\_STANDARD. A sample rate of 32 kHz, audio encoding, mono, and a bitrate of up to 18 Kbps.
  * `2`: MUSIC\_STANDARD. A sample rate of 48 kHz, music encoding, mono, and a bitrate of up to 64 Kbps.
  * `3`: MUSIC\_STANDARD\_STEREO. A sample rate of 48 kHz, music encoding, stereo, and a bitrate of up to 80 Kbps.
  * `4`: MUSIC\_HIGH\_QUALITY. A sample rate of 48 kHz, music encoding, mono, and a bitrate of up to 96 Kbps.
  * `5`: MUSIC\_HIGH\_QUALITY\_STEREO. A sample rate of 48 kHz, music encoding, stereo, and a bitrate of up to 128 Kbps.
* `videoOptions`: (Optional) JSON Object. The video transcoding configuration of the cloud player. Setting this field to empty or not set means that the video is not transcoded.
* `width`: Number. The width (px) of the output video. The value range is \[66,1920].
* `height`: Number. The height (px) of the output video. The value range is \[66,1080].
* `widthHeightAdaption`: Bool. Whether to enable horizontal and vertical screen adaptive mode:
  * `true`: Enable portrait and landscape adaptive mode. After you enable the adaptive mode, if the source media stream is in landscape mode, the output video width and height are 1280 × 720; if the source media stream is in portrait mode, the output video width and height are 720 × 1280.
  * `false`: (Default) Do not enable portrait and landscape adaptive mode.
* `frameRate`: The frameRate (fps) of the output video. The value range is \[1,30]. The default value is 15. For details, see [Video profile table](/en/realtime-media/cloud-recording/build/customize-the-recording/recording-video-profile#video-profile-table).
* `bitrate`: Number. The bitrate (Kbps) of the output video. The value range is \[1,10000]. For details, see [Video profile table](/en/realtime-media/cloud-recording/build/customize-the-recording/recording-video-profile#video-profile-table).
* `codec`: String type. The encoding format of the output video. The following settings are supported:
  * VP9: Standard VP9.
  * H.264: (Default) Standard H.264.
    If set to other value, the default is H.264 video encoding format.
* `fillMode`: String. The fill mode of the output video:
  * `fit`: (Default) Scales the video proportionally until it is fully displayed in the viewport.
  * `fill`: Scales the video proportionally until it fills the viewport.
* `streamUrl`: (Required) String. The RTMP/HTTPS URL of the online media stream. The maximum length of this field is 1024 bytes.

<CalloutContainer type="info">
  <CalloutDescription>
    To inject an image to the Agora channel, set `streamUrl` to the URL of the image you want to inject, and the cloud player will convert the image to a video and inject it to the Agora channel. Images in JPEG and PNG formats are currently supported. You can set video transcoding parameters through `videoOptions`.
  </CalloutDescription>
</CalloutContainer>

* `channelName`: (Required) String. The channel name. The maximum length of this field is 64 bytes. Supported character scopes are:
  * All lowercase English letters: a to z.
  * All uppercase English letters: A to Z.
  * All numeric characters: 0 to 9.
  * The space character.
  * Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "\<", "=", ".", ">", "?", "@", "\[", "]", "^", "\_", " \{", "}", "|", "\~", ",".

* `uid`: (Optional) Number. The User ID of the cloud player in the channel. The value ranges from 0 to (2<sup>32</sup>-1). When you pass in `0`, Agora automatically assigns a User ID to the player.

<CalloutContainer type="info">
  <CalloutDescription>
    All UIDs within a channel must be unique. Ensure no other user or service bot is using this UID in the same channel.
  </CalloutDescription>
</CalloutContainer>

* `account`: (Optional) String. The User Account of the cloud player in the channel. The maximum length of this field is 255 bytes. Ensure that you set this parameter and do not set it as null. Supported character scopes are:
  * All lowercase English letters: a to z.
  * All uppercase English letters: A to Z.
  * All numeric characters: 0 to 9.
  * The space character.
  * Punctuation characters and other symbols, including: "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "\<", "=", ".", ">", "?", "@", "\[", "]", "^", "\_", " \{", "}", "|", "\~", ",".

<CalloutContainer type="info">
  <CalloutDescription>
    Ensure that the value is different from User Accounts of other users and players in the channel.
  </CalloutDescription>
</CalloutContainer>

* `token`: (Optional) String. The authentication token used by the cloud player in the channel. If you do not enable the App Certificate in Agora Console, ignore this field. If you enable the App Certificate in Agora Console, you must pass a value in this field:
  * For low-security requirements: Use the temporary token generated in Agora Console. For details, see [Generate a Video SDK temporary token](/en/realtime-media/media-pull/build/manage-agora-account#generate-a-temporary-tokens).
  * For high-security requirements: Use the token generated at your server. For details, see [Secure authentication with tokens](/en/realtime-media/video/build/authenticate-users/deploy-token-server).

<CalloutContainer type="info">
  <CalloutDescription>
    When generating a token at your server, the value of `uid` or `account` must be the same as the User ID or User Account of the cloud player, and `privilegeExpiredTs` is recommended to be `0` to ensure that the token is valid for 24 hours at most.
  </CalloutDescription>
</CalloutContainer>

* `idleTimeout`: (Optional) Number. The maximum length of time (in seconds) that the cloud player is idle. The "idle" state means that the media stream is not playing. When the idle state exceeds `idleTimeout`, the cloud player is automatically destroyed. The value ranges from 5 to 600. The default value is 300. If the value is less than 5, Agora's server automatically adjusts it to 5; if the value is greater than 600, Agora's server automatically adjusts it to 600.
* `playTs`: (Optional) Number. The Unix timestamp (in seconds) when the cloud player starts playing the online media stream. The value range of playTs is \[`createTs`-86400, `createTs`+300]. The default value is 0, which means the cloud player starts playing the online media stream when the cloud player is successfully created. If the value of `playTs` is not `0`, the following behavior occurs:
* `playTs` > `createTs`: The cloud player starts playing the online media stream when the time is `playTs`. This is suitable for timing playback with other elements.
* `playTs` \< `createTs`: If the online media stream is a live stream, the cloud player starts playing the live stream when the cloud player is successfully created. If the online media stream is an on-demand stream, the cloud player starts playing the online media stream at the specified time in the stream prior to the creation of the cloud player. This is suitable for error recovery. For example, if the cloud player experiences an error during operation, you can create a new cloud player and set the `playTs` field of new cloud player to the unix timestamp when the old cloud player started to play the online media stream.
* `name`: (Optional) String. The name of the cloud player. The maximum length of this parameter is 64 bytes. Supported character scopes are:
  * All lowercase English letters: a to z.
  * All uppercase English letters: A to Z.
  * All numeric characters: 0 to 9.
  * "-", "\_".
    `name` is null if you do not pass any value. Multiple cloud players using null name parameters can exist in one project at the same time; multiple cloud players with the same name cannot exist in one project at the same time. When trying to create a cloud player with the same name as an existing cloud player in the project, you will receive the `409(Conflict)` status code.

<CalloutContainer type="info">
  <CalloutDescription>
    To avoid creating multiple cloud players that inject the same online media stream into the same channel, use the `name` parameter to manage all the cloud players in your specified project. Agora recommends that you pass a value in `name` using a combination of the channel name (`channelName`) and the username (`uid` or `account`) of the cloud player, such as `class32_101` and `class33_teacher101` in the sample code.
  </CalloutDescription>
</CalloutContainer>

* `encryptMode`: (Optional) String. Encryption mode. Agora recommends using either the `aes-128-gcm2` or `aes-256-gcm2` encryption mode, both of which support adding a salt and are more secure.
* `aes-128-xts`: 128-bit AES encryption, XTS mode.
* `aes-256-xts`: 256-bit AES encryption, XTS mode.
* `aes-128-ecb`: 128-bit AES encryption, ECB mode.
* `sm4-128-ecb`: 128-bit SM4 encryption, ECB mode.
* `aes-128-gcm`: 128-bit AES encryption, GCM mode.
* `aes-256-gcm`: 256-bit AES encryption, GCM mode.
* `aes-128-gcm2`: 128-bit AES encryption, GCM mode. Compared to `aes-128-gcm` encryption mode, `aes-128-gcm2` encryption mode is more secure and requires you to set the salt (`encryptKdfSalt`).
* `aes-256-gcm2`: 256-bit AES encryption, GCM mode. Compared to `aes-256-gcm` encryption mode, `aes-256-gcm2` encryption mode is more secure and requires you to set the salt (`encryptKdfSalt`).
* `encryptKey`: (Optional) String. The encryption key with unlimited length. Agora recommends using a 32-byte key.

<CalloutContainer type="info">
  <CalloutDescription>
    If you do not set an encryption key or set it to null, built-in encryption is disabled.
  </CalloutDescription>
</CalloutContainer>

* `encryptKdfSalt`: (Optional) String. A 32-byte salt. Agora recommends using OpenSSL to generate this salt on your server. For details, see [Secure channel encryption](/en/realtime-media/interactive-live-streaming/build/secure-and-protect-channels/media-stream-encryption).

<CalloutContainer type="info">
  <CalloutDescription>
    This parameter is only valid when the encryption mode is set to `aes-128-gcm2` or `aes-256-gcm2`. In this case, ensure that it is not `0`.
  </CalloutDescription>
</CalloutContainer>

* `repeatTime`: (Optional) Int. Number of media streams played. This parameter applies only to on-demand streams. It can be set to:
* `1`: (Default) Plays a media resource once.
* `-1`: Plays media resources in a loop.
* `N`: User-defined number of media resources to be played. It is an integer and cannot be set to `0`.
* `seekPosition`: (Optional) Number. Specifies the playback position (seconds) of the on-demand file. The default value is 0, which means play from the beginning of the on-demand file. It must be less than the media resource duration.
* dataStreamOptions: (Optional) JSON Object. The data stream configuration, which is used to set the SEI information carried by the video frame. This parameter applies only to on-demand streams.
* `enable`: Set whether to inject the SEI information of Agora DataStream type.
  * `true`: Inject the SEI information of Agora DataStream type.
  * `false`: (Default) Do not inject the SEI information of Agora DataStream type.
    Agora DataStream is a data stream format of JSON type, the example is as follows:

    ```json
    message PositionData {
      # The length of the on-demand file
    int32 duration = 1;
      # The playback position of the on-demand file
    int32 position = 2;
      # The user ID of the host playing the on-demand file
    int32 uid = 3;
    }

    ```

### HTTP response [#http-response]

For all possible response status codes, see [Status codes](#code).

#### Response header [#response-header]

The response header contains the following fields:

* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. It is the same as the `X-Request-ID` field in the request header. If the request fails, print out this value in the log for troubleshooting.

<CalloutContainer type="info">
  <CalloutDescription>
    If you receive the `401(Unauthorized)` status code for this request, the response header does not contain the field.
  </CalloutDescription>
</CalloutContainer>

* `X-Resource-ID`: UUID (Universally Unique Identifier) to identify the cloud player created by this request:
  * When the status code is 2XX, this value is the ID of the cloud player created by this request.
  * When the status code is `409(Conflict)`, the name of the cloud player created by this request is duplicate with the name of other existing players in the project. This value is the ID of that existing player. Please check and modify the name of the cloud player created by this request.
  * When the status code is another value, this field is null and this request fails.

#### Response body [#response-body]

If the status code is 2XX, the request succeeds. The response body contains the following fields:

* `player`: JSON Object. Contains the following fields:
  * `uid`: Number. The User ID of the cloud player in the channel.
  * `account`: String. The User Account of the cloud player in the channel.
  * `id`: String. The ID of the cloud player. It is a UUID (Universally Unique Identifier) generated by Agora's server to identify the ID of the cloud player created.
  * `createTs`: Number. The Unix timestamp (in seconds) when creating the cloud player.
  * `status`: String. The state of the cloud player at runtime:
    * `"idle"`: The playback is not started.
    * `"connecting"`: Agora's server is connecting to the address of the media stream or detecting the audio and video data.
    * `"running"`: Playing.
    * `"failed"`: Agora's server cannot connect to the address of the media stream, or the media stream cannot be played.
  * `fields`: String. The field mask to represent a set of symbolic field paths. The field mask is encoded as a single string where paths are separated by a comma. It specifies a subset of fields that should be returned by this request. In the sample code using `uid`, `fields` specifies that Agora's server returns the `uid`, `id`, `createTs`, and `status` fields. For details, see [Google protobuf FieldMask](https://googleapis.dev/nodejs/pubsub/latest/google.protobuf.html#.FieldMask).

If the status code is not 2XX, the request fails. The response body contains the `message` field, which describes the detailed reason for the failure.

### Request example [#request-example]

**Media Pull without transcoding**

```json
{
    "player": {
    "streamUrl": "rtmp://example.agora.io/live/class32/101",
    "channelName": "class32",
    "token": "2a784467d6",
    "uid": 101,
    "idleTimeout": 300,
    "playTs": 1575508644,
    "name": "test"
    }
}
```

**Media Pull with transcoding**

```json
{
    "player": {
        "audioOptions": {
            "profile": 1
        },
        "videoOptions": {
            "width": 1920,
            "height": 1080,
            "frameRate": 15,
            "bitrate": 400,
            "codec": "VP9",
            "gop": 30,
            "fillMode": "fill"
        },
    "streamUrl": "rtmp://example.agora.io/live/class32/101",
    "channelName": "class32",
    "token": "2a784467d6",
    "uid": 101,
    "idleTimeout": 300,
    "playTs": 1575508644,
    "name": "test"
    }
}
```

### Response example [#response-example]

```json
{
    "player": {
        "uid": 101,
        "id": "2a784467d647bb87b60b719f6fa56317",
        "createTs": 1575508644,
        "status": "running"
    },
    "fields": "player.uid,player.id,player.createTs,player.status"
}
```

## Delete API [#delete-api]

This API destroys the cloud player in the project.

### HTTP request [#http-request-1]

```bash
DELETE https://api.agora.io/{region}/v1/projects/{appId}/cloud-player/players/{id}
```

#### Path parameters [#path-parameters-1]

* `appId`: (Required) String. Agora provides the [App ID](/en/realtime-media/media-pull/reference/glossary#app-id) when you create a **project** in Agora Console. The App ID identifies each project.
* `id`: (Required) String. The ID of the cloud player.
* `region`: (Required) String. The `region` where the Player is created in.

#### Request header [#request-header-1]

* `Authorization`: See [Authentication](#authentication).

* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. After passing in the field, Agora's server returns it in the response header.

<CalloutContainer type="info">
  <CalloutDescription>
    Agora recommends using this field. If you do not pass in any value, Agora's server automatically generates a UUID to pass in.
  </CalloutDescription>
</CalloutContainer>

### HTTP response [#http-response-1]

For all possible response status codes, see [Status codes](#code).

#### Response header [#response-header-1]

The response header contains the following fields:

* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. It is the same as the `X-Request-ID` field in the request header. If the request fails, print out this value in the log for troubleshooting.

<CalloutContainer type="info">
  <CalloutDescription>
    If you receive the `401(Unauthorized)` status code for this request, the response header does not contain the field.
  </CalloutDescription>
</CalloutContainer>

* `X-Resource-ID`: UUID (Universally Unique Identifier) to identify the ID of the cloud player created by this request. The UUID is the same as the value in the `id` path parameter.

#### Response body [#response-body-1]

* If the status code is 2XX, the request succeeds. The response body is empty.

* If the status code is not 2XX, the request fails. The response body contains the `message` field, which describes the detailed reason for the failure.

## List API [#list-api]

This API queries and lists all the cloud players in the project.

### HTTP request [#http-request-2]

```bash
GET https://api.agora.io/v1/projects/{appId}/cloud-player/players
```

#### Path parameters [#path-parameters-2]

`appId`: (Required) String. Agora provides the [App ID](/en/realtime-media/media-pull/reference/glossary#app=id) when you create a **project** in Agora Console. The App ID identifies each project.

#### Query parameters [#query-parameters-1]

A sample request URL when using query parameters:

```bash
https://api.agora.io/v1/projects/{appId}/cloud-player/players?filter={filter}&pageSize={pageSize}&pageToken={pageToken}
```

* `filter`: (Optional) String. The filter. Agora's server only lists the cloud players that meet the filter criteria in the project. The current filter is the value of `channelName` when creating the cloud player.

  Assuming the channel name is `class32`, replace `filter={filter}` in the sample request URL with `filter=channelName eq class32`; Assuming the channel name is `bigclass`, replace `filter={filter}` in the sample request URL with `filter=channelName eq bigclass`.

<CalloutContainer type="info">
  <CalloutDescription>
    Spaces exist before and after `eq` and require URL encoding.
  </CalloutDescription>
</CalloutContainer>

* `pageSize`: (Optional) Number. The maximum number of cloud players to return on one page. The value ranges from 1 to 500. The default value is 200, which means that for a single page, Agora's server lists up to 200 cloud players if you do not pass in any value.
* `pageToken`: (Optional) String. The page number to indicate the order of the pages. If you do not pass in any value, Agora's server returns to the first page.

<CalloutContainer type="info">
  <CalloutDescription>
    Recommended usage: When using the `List` API for the first time, do not pass any value in the `pageToken` query parameter. You can get the query results of the first page and the value of the `nextPageToken` field. The next time you use the `List` API, pass this value in the `pageToken` query parameter to query the cloud players on the next page.
  </CalloutDescription>
</CalloutContainer>

After using the above parameters, Agora's server queries and lists the cloud players according to the following steps:

1. Query the cloud players that meet the filter criteria in the specified project.
2. Set the space size of each page.
3. List the cloud players in the specified page.

   <CalloutContainer type="info">
     <CalloutDescription>
       Agora's server lists the cloud players in ascending order by `createTs`.
     </CalloutDescription>
   </CalloutContainer>

#### Request header [#request-header-2]

The request header contains the following fields:

* `Authorization`: See [Authentication](./restful-authentication).
* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. After passing in the field, Agora's server returns it in the response header.

<CalloutContainer type="info">
  <CalloutDescription>
    Agora recommends using this field. If you do not pass in any value, Agora's server automatically generates a UUID to pass in.
  </CalloutDescription>
</CalloutContainer>

### HTTP response [#http-response-2]

For all possible response status codes, see [Status codes](#code).

#### Response header [#response-header-2]

* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. It is the same as the `X-Request-ID` field in the request header. If the request fails, print out this value in the log for troubleshooting.

<CalloutContainer type="info">
  <CalloutDescription>
    If you receive the `401(Unauthorized)` status code for this request, the response header does not contain the field.
  </CalloutDescription>
</CalloutContainer>

#### Response body [#response-body-2]

If the status code is 2XX, the request succeeds. The response body contains the following fields:

* `totalSize`: Number. The number of cloud players that meet the filter criteria.

* `players`: JSON Array. Contains the following fields:
  * `name`: String. The name of the cloud player.
  * `streamUrl`: String. The RTMP/HTTPS URL of the online media stream.
  * `channelName`: String. The name of the Agora channel.
  * `uid`: Number. The User ID of the cloud player in the Agora channel.
  * `account`: String. The User Account of the cloud player in the Agora channel.
  * `id`: String. UUID (Universally Unique Identifier) to identify the cloud player created. It is the ID of the cloud player.
  * `createTs`: Number. The Unix timestamp (in seconds) when creating the cloud player.
  * `status`: String. The state of the cloud player at runtime:
    * `"idle"`: The playback is not started.
    * `"connecting"`: Agora's server is connecting to the address of the media stream or detecting the audio and video data.
    * `"running"`: Playing.
    * `"failed"`: Agora's server cannot connect to the address of the media stream, or the media stream cannot be played.

* `fields`: String. The field mask to represent a set of symbolic field paths. The field mask is encoded as a single string where paths are separated by a comma. It specifies that Agora's server returns a subset of fields in each player in the `players` array. In the sample code using `uid`, `fields` specifies that Agora's server returns the `name`, `streamUrl`, `channelName`, `uid`, `id`, `createTs`, and `status` fields in each player in the `players` array.

* `nextPageToken`: String. The next page number of `pageToken`. You can pass the value of the `nextPageToken` field in the `pageToken` query parameter when using the `List` API next time. When `nextPageToken` is an empty string, there are no more players that match the request.

If the status code is not 2XX, the request fails. The response body contains the `message` field, which describes the detailed reason for the failure.

### Response example [#response-example-1]

```json
{
    "totalSize": 10,
    "players": [{
        "name": "class32_101",
        "streamUrl": "rtmp://example.agora.io/live/class32/101",
        "channelName": "class32",
        "uid": 101,
        "id": "2a784467d647bb87b60b719f6fa56317",
        "createTs": 1575508644,
        "status": "running"
   }, {
        "name": "class68_422",
        "streamUrl": "rtmp://example.agora.io/live/class68/422",
        "channelName": "class68",
        "uid": 422,
        "id": "0b719f6fa563172a784467d647bb87b6",
        "createTs": 1575588644,
        "status": "connecting"
   }],
    "fields": "player.name,player.streamUrl,player.channelName,player.uid,player.id,player.createTs,player.status",
    "nextPageToken": "7b60b719f"
}
```

## Update API [#update-api]

Update the cloud player you specified in the project.

### HTTP request [#http-request-3]

```bash
PATCH https://api.agora.io/{region}/v1/projects/{appId}/cloud-player/players/{id}
```

#### Path parameters [#path-parameters-3]

* `appId`: (Required) String. Agora provides the [App ID](/en/realtime-media/media-pull/reference/glossary#app-id) when you create a **project** in Agora Console. The App ID identifies each project.
* `id`: (Required) String. The ID of the cloud player.
* `region`: (Required) String. The `region` where the Player is created in.

#### Query parameters [#query-parameters-2]

`sequence`: (Required) Number. The sequence number of the `Update` request. The parameter needs to be greater than or equal to 0. Ensure that the sequence number of the subsequent `Update` request is greater than the sequence number of the previous `Update` request. The serial number ensures that the Agora server updates Converter with the latest configuration you specified.

<CalloutContainer type="info">
  <CalloutDescription>
    Best practice is to fill `sequence` with `0` when calling `Update` for the first time. When calling `Update` for the second time, fill `sequence` with `1`. When calling `Update` for the third time, fill `sequence` with `2`. And so on. The Agora server updates cloud player according to the latest `Update` request (that is, the highest serial number).
  </CalloutDescription>
</CalloutContainer>

```bash
PATCH https://api.agora.io/{region}/v1/projects/{appId}/cloud-player/{playerid}?sequence={sequence}
```

#### Request header [#request-header-3]

* `Authorization`: See [Authentication instructions](./restful-authentication).
* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. After passing in the field, Agora's server returns it in the response header.

<div class="alert info"> Agora recommends using this field. If you do not pass in any value, Agora's server automatically generates a UUID to pass in.</div>

#### Request body [#request-body-1]

You can update the following fields at the same time:

* `streamUrl`
* `audioOptions`
* `audioOptions.volume`
* `seekPosition`
* `isPause`: Bool. Whether to pause the playback of the media stream source file:
  * `true`: Pauses playback of the media stream source file.
  * `false`:(Default) Plays the media stream source file.
* `audioOptions.volume`: Int. The volume of the cloud player. The value range is \[0,200]. The default value is 100, which represents the original volume.

For the details of other fields, see [Create request body](#create).

### HTTP response [#http-response-3]

For all possible response status codes, see [Status codes](#code).

#### Response header [#response-header-3]

* `X-Request-ID`: UUID (Universally Unique Identifier) to identify this request. It is the same as the `X-Request-ID` field in the request header. If the request fails, print out this value in the log for troubleshooting.

<CalloutContainer type="info">
  <CalloutDescription>
    If the status code is not 2XX, the response header does not contain the field.
  </CalloutDescription>
</CalloutContainer>

* `X-Resource-ID`: UUID (Universally Unique Identifier) to identify the ID of the cloud player created by this request. The UUID is the same as the value in the `id` path parameter.

#### Response body [#response-body-3]

* If the status code is 2XX, the request succeeds. The response body is empty.
* If the status code is not 2XX, the request fails. The response body contains the `message` field, which describes the detailed reason for the failure.

### Request example [#request-example-1]

```json
"player": {
   "audioOptions": {
       "volume": 10
   },
   "isPause": false,
   "streamUrl": "http://XXXX",
   "seekPosition": 40
}
```

## Rate limits [#rate-limits]

Do not exceed the API rate limits, otherwise you receive the `429(Too Many Requests)` status code.

| API      | Rate limit                                                                                                                                                                                                                                                                           |
| :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Create` | * In a project, when creating cloud players with `name`, the maximum rate of creating each cloud player with a different name is 2 times per second.

* In a project, the maximum rate of creating a cloud player without `name` is 50 times per second.                             |
| `Delete` | In a project, the maximum rate of destroying a cloud player is 100 times per second.                                                                                                                                                                                                 |
| `List`   | - In a project, the maximum rate of querying a cloud player with `filter`(`channelName`) is 2 times per second and 15 times per minute.

- In a project, the maximum rate of querying a cloud player without `filter`(`channelName`) is 10 times per second and 20 times per minute. |

<a id="code"></a>

## Status codes [#status-codes]

* If the status code is 2XX, the request succeeds.
* If the status code is not 2XX, the request fails. Use the `message` field in the response body for troubleshooting.

| Status code             | Possible message field                                                                                                                                                  |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 200 OK                  | /                                                                                                                                                                       |
| 400 Bad Request         | - Parameter 'streamUrl' is invalid formatted.

- Parameter channelName is invalid. Fix it in your request and retry.                                                    |
| 401 Unauthorized        | Invalid authentication credentials.                                                                                                                                     |
| 403 Forbidden           | * This project has not enabled Cloud Player product yet. Contact us to enable it.

* This project's permission to use Cloud Player was revoked. Contact us for details. |
| 404 Not Found           | Resource is not found and destroyed.                                                                                                                                    |
| 409 Conflict            | Resource with the same name already exists.                                                                                                                             |
| 429 Too Many Requests   | - Request rate limit exceeded.

- Resources quota limit exceeded.

- no available resources                                                                             |
| 500 Unknown             | Some internal error happened. Contact us to help fix it.                                                                                                                |
| 503 Service Unavailable | * Service overload. Retry with back off strategy, and contact us to help fix it.

* Service unavailable temporarily. Retry with back off strategy.                      |
| 504 Gateway Timeout     | Gateway timeout. Query to check whether the player has been created, or to create another one instead.                                                                  |

## RESTful API callback service [#restful-api-callback-service]

After using these RESTful APIs, Agora's notification server sends the callback notification to your server through an HTTP request.
For details, see [Message Notification Service](../../api-reference/ncs-events).

## Considerations [#considerations]

This section summarizes some important considerations when using the Media Pull RESTful API.

| Item                                                                                                                                                                                                                                                                     | Impact |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ |
| Ensure that the channel profile is set as `LIVE_BROADCASTING`.                                                                                                                                                                                                           | ★★★☆☆  |
| If the channel needs only one cloud player, ensure that you have set the `name` parameter. For details, see the description of `name`.                                                                                                                                   | ★★★☆☆  |
| If the channel needs more than one cloud player, ensure that each player has a unique user ID/account. For details, see the description of `uid` and `account`.                                                                                                          | ★★★★★  |
| Please ensure that the region you set is the same region as where your media stream originates is located. For details, see the description of `region`.                                                                                                                 | ★★★★★  |
| The cloud player may be deleted automatically due to server errors. Agora recommends that you enable the Message Notification Service to listen for events of Media Pull. For details, see the [Media Pull Message Notification Server](../../api-reference/enable-ncs). | ★★★★★  |
| When using the `List` API, the `players` field in the response body might only include `id`, `name`, and `CreateTs`. Ensure that your app logic can handle this situation.                                                                                               | ★★★★★  |
| If using the `Create` or `Delete` API results in a status code of `504 Gateway Timeout`, call the `List` API to query the actual state of the cloud player to make sure an unmanaged cloud player does not exist.                                                        | ★★★☆☆  |
| If your request fails, ensure that you print out the `X-Request-ID` and `X-Resource-ID` fields in the response header in the log for later use in troubleshooting.                                                                                                       | ★★★☆☆  |
| After creating a cloud player and receiving a response message, you need to wait about 10 seconds before using the `List` method to query, otherwise you may not get any information.                                                                                    | ★★★☆☆  |
| The default maximum number of concurrent tasks is 20, which means that a maximum of 20 Media Pull tasks are allowed to run simultaneously for each project. You can contact [support@agora.io](mailto\:support@agora.io) to get a higher quota.                          | ★★★★☆  |
