# Quickstart using middleware (/en/realtime-media/cloud-recording/middleware-quickstart)

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

To streamline the use of Agora RESTful APIs within your infrastructure, Agora’s developer community offers the open-source [Agora Go Backend Middleware](https://github.com/AgoraIO-Community/agora-go-backend-middleware). This backend provides RESTful APIs for tasks such as token generation, cloud recording management, and real-time transcription. It simplifies the integration of Agora’s cloud services into your real-time voice and video applications. This guide shows you how to implement cloud recording using the community middleware.

## Understand the tech [#understand-the-tech]

The following figure illustrates the architecture of the middleware cloud recording micro service.

![](https://assets-docs.agora.io/images/cloud-recording/cloud-recording-middleware.svg)

## Set up and run the Go backend middleware [#set-up-and-run-the-go-backend-middleware]

Take the following steps to set up and run the middleware project:

1. **Clone the repository**

   ```bash
   git clone https://github.com/AgoraIO-Community/agora-go-backend-middleware.git
   ```

2. **Install dependencies**
   Ensure you have [Go](https://go.dev/doc/install) installed on your system. Navigate to the project directory and install the project dependencies:

   ```bash
   cd agora-go-backend-middleware
   go mod download
   ```

3. **Configure environment variables**

   1. Copy the example `.env` file.

      ```bash
      cp .env.example .env
      ```

   2. Update the following variables in the `.env` file:

      * `APP_ID`: Your Agora App ID.
      * `APP_CERTIFICATE`: Your Agora App Certificate.
      * `CUSTOMER_ID`: Your customer ID
      * `CUSTOMER_SECRET`: Your Customer Secret
      * `STORAGE_VENDOR`: Cloud storage vendor (e.g., AWS, GCP).
      * `STORAGE_REGION`: Region of your cloud storage.
      * `STORAGE_BUCKET`: Bucket name.
      * `STORAGE_ACCESS_KEY`: Cloud storage access key.
      * `STORAGE_SECRET_KEY`: Cloud storage secret key.

4. **Run the middleware:**

   Start the middleware server using the following command:

   ```bash
   go run cmd/main.go
   ```

   The middleware runs on the default port, for example `localhost:8080`.

## Implement Cloud Recording using middleware [#implement-cloud-recording-using-middleware]

This section explains the RESTful API calls to the backend middleware for starting, managing, and stopping a Cloud Recording session.

### Start recording [#start-recording]

To start a Cloud Recording session refer to the following examples:

<CalloutContainer type="info">
  <CalloutDescription>
    The command-line examples in this guide are for demonstration purposes only. Do not use them directly in a production environment. Implement RESTful API requests through your application server.
  </CalloutDescription>
</CalloutContainer>

* Basic example

  ```bash
  curl -X POST http://localhost:8080/cloud_recording/start \
    -H "Content-Type: application/json" \
    -d '{
      "channelName": "test_channel",
      "sceneMode": "realtime",
      "recordingMode": "mix",
      "excludeResourceIds": []
    }'
  ```

* Advanced example

  ```bash
  curl -X POST http://localhost:8080/cloud_recording/start \
    -H "Content-Type: application/json" \
    -d '{
      "channelName": "testChannel",
      "sceneMode": "realtime",
      "recordingMode": "mix",
      "excludeResourceIds": [],
      "recordingConfig": {
        "channelType": 0,
        "decryptionMode": 1,
        "secret": "your_secret",
        "salt": "your_salt",
        "maxIdleTime": 120,
        "streamTypes": 2,
        "videoStreamType": 0,
        "subscribeAudioUids": ["#allstream#"],
        "unsubscribeAudioUids": [],
        "subscribeVideoUids": ["#allstream#"],
        "unsubscribeVideoUids": [],
        "subscribeUidGroup": 0,
        "streamMode": "individual",
        "audioProfile": 1,
        "transcodingConfig": {
          "width": 640,
          "height": 360,
          "fps": 15,
          "bitrate": 500,
          "maxResolutionUid": "1",
          "layoutConfig": [
            {
              "x_axis": 0,
              "y_axis": 0,
              "width": 640,
              "height": 360,
              "alpha": 1,
              "render_mode": 1
            }
          ]
        }
      }
  }'
  ```

### Stop recording [#stop-recording]

To stop an ongoing cloud recording session:

```bash
curl -X POST http://localhost:8080/cloud_recording/stop \
  -H "Content-Type: application/json" \
  -d '{
    "cname": "test_channel",
    "uid": "uid-from-start-response",
    "resourceId": "resource-id-from-start-response",
    "sid": "sid-from-start-response",
    "recordingMode": "mix",
    "async_stop": false
  }'
```

### Get Recording Status [#get-recording-status]

During the recording, call the `status` endpoint to query the recording status as required.

```bash
curl -X GET "http://localhost:8080/cloud_recording/status?resourceId=your-resource-id&sid=your-sid&mode=mix"
```

### Update Subscriber List [#update-subscriber-list]

To update the subscriber list during a recording session, refer to the following example:

```bash
curl -X POST http://localhost:8080/cloud_recording/update/subscriber-list \
  -H "Content-Type: application/json" \
  -d '{
    "cname": "test_channel",
    "uid": "uid-from-start-response",
    "resourceId": "your-resource-id",
    "sid": "your-sid",
    "recordingMode": "mix",
    "recordingConfig": {
      "streamSubscribe": {
        "audioUidList": {
          "subscribeAudioUids": ["2345", "3456"]
        },
        "videoUidList": {
          "subscribeVideoUids": ["2345", "3456"]
        }
      }
    }
  }'
```

### Update Layout [#update-layout]

To update the layout of a recording session, refer to the following example:

```bash
curl -X POST http://localhost:8080/cloud_recording/update/layout \
  -H "Content-Type: application/json" \
  -d '{
    "cname": "test_channel",
    "uid": "uid-from-start-response",
    "resourceId": "your-resource-id",
    "sid": "your-sid",
    "recordingMode": "mix",
    "recordingConfig": {
      "mixedVideoLayout": 1,
      "backgroundColor": "#000000",
      "layoutConfig": [
        {
          "uid": "2345",
          "x_axis": 0,
          "y_axis": 0,
          "width": 360,
          "height": 640,
          "alpha": 1,
          "render_mode": 1
        }
      ]
    }
  }'
```

## Cloud Recording Middleware API Reference [#cloud-recording-middleware-api-reference]

This section provides details about the Go middleware Cloud Recording API endpoints.

### Start Recording [#start-recording-1]

Starts a cloud recording session.

##### Endpoint [#endpoint]

**POST:** `/cloud_recording/start`

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

```json
{
  "channelName": "string",
  "uid": "string",
  "recordingConfig": {
    // RecordingConfig fields
  },
  "storageConfig": {
    // StorageConfig fields
  }
}
```

#### Response [#response]

```json
{
  "resourceId": "string",
  "sid": "string",
  "timestamp": "string"
}
```

### Stop Recording [#stop-recording-1]

Stops an ongoing cloud recording session.

#### Endpoint [#endpoint-1]

**POST:** `/cloud_recording/stop`

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

```json
{
  "cname": "string",
  "uid": "string",
  "resourceId": "string",
  "sid": "string",
  "recordingMode": "string",
  "async_stop": boolean
}
```

#### Response [#response-1]

```json
{
  "resourceId": "string",
  "sid": "string",
  "serverResponse": {
    "fileListMode": "string",
    "fileList": [
      {
        "fileName": "string",
        "trackType": "string",
        "uid": "string",
        "mixedAllUser": boolean,
        "isPlayable": boolean,
        "sliceStartTime": number
      }
    ]
  },
  "timestamp": "string"
}
```

### Get Recording Status [#get-recording-status-1]

Retrieves the status of a cloud recording session.

#### Endpoint [#endpoint-2]

**GET:** `/cloud_recording/status`

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

* `resourceId`: string
* `sid`: string
* `mode`: string

#### Response [#response-2]

```json
{
  "resourceId": "string",
  "sid": "string",
  "serverResponse": {
    "fileListMode": "string",
    "fileList": [
      {
        "fileName": "string",
        "trackType": "string",
        "uid": "string",
        "mixedAllUser": boolean,
        "isPlayable": boolean,
        "sliceStartTime": number
      }
    ]
  },
  "timestamp": "string"
}
```

### Update Subscriber List [#update-subscriber-list-1]

Updates the subscriber list for a cloud recording session.

#### Endpoint [#endpoint-3]

**POST:** `/cloud_recording/update/subscriber-list`

#### Request Body [#request-body-2]

```json
{
  "cname": "string",
  "uid": "string",
  "resourceId": "string",
  "sid": "string",
  "recordingMode": "string",
  "recordingConfig": {
    // UpdateSubscriptionClientRequest fields
  }
}
```

#### Response [#response-3]

```json
{
  "cname": "string",
  "uid": "string",
  "resourceId": "string",
  "sid": "string",
  "timestamp": "string"
}
```

### Update Layout [#update-layout-1]

Updates the layout of a cloud recording session.

#### Endpoint [#endpoint-4]

**POST:** `/cloud_recording/update/layout`

#### Request Body [#request-body-3]

```json
{
  "cname": "string",
  "uid": "string",
  "resourceId": "string",
  "sid": "string",
  "recordingMode": "string",
  "recordingConfig": {
    // UpdateLayoutClientRequest fields
  }
}
```

#### Response [#response-4]

```json
{
  "cname": "string",
  "uid": "string",
  "resourceId": "string",
  "sid": "string",
  "timestamp": "string"
}
```

Replace `localhost:8080` with your server's address, if it is different.
