# REST API

The Rest APIs are designed for jobs, configurations, and cluster management.

### Distributed Load

Pre-loads UFS (Underlying File System) data into worker caches to prevent performance degradation caused by cold reads.

#### Submit or resume a load job

| **Method** | **Path**     | **Parameters** | **Request Body Type**          |
| ---------- | ------------ | -------------- | ------------------------------ |
| POST       | /api/v1/load | None           | Content-Type: application/json |

**Parameters**

| **Name**  | **Type** | **Required** | **Description**                                              | **Example**                                                |
| --------- | -------- | ------------ | ------------------------------------------------------------ | ---------------------------------------------------------- |
| `index`   | string   | No           | Path to the index file on UFS (must be mounted)              | '{"index": "s3://bucket/key"}'                             |
| `paths`   | string   | No           | List of UFS paths to load                                    | '{"paths": \["s3://bucket/key1", "s3://bucket/key2"]}'     |
| `alias`   | string   | No           | Used in combination with paths for subsequent status queries | '{"paths": \["s3://bucket/key1"], "alias": "database1"}'   |
| \`options | object   | No           | Configuration options for the load job                       | '{"index": "s3://bucket/key", "options":{"batchSize":10}}' |

Note: You must choose either `index` or `paths`. If `paths` is used, an `alias` can be specified; otherwise, a random alias will be generated and returned.

An `options` JSON can be used to configure the options of the load job. All options are optional. Possible configs are:

| Name               | Type | Required | Description                                                                |
| ------------------ | ---- | -------- | -------------------------------------------------------------------------- |
| `batchSize`        | int  | No       | Batch size for workers to load data from UFS                               |
| `replicas`         | int  | No       | Number of file replicas to load. Defaults to the path-specific config or 1 |
| `skipIfExists`     | bool | No       | Skip the loading process if the file already exists                        |
| `loadPolicy`       | enum | No       | Currently supports IF\_CHANGED. Updates the file if it has changed         |
| `loadMetadataOnly` | bool | No       | Only load file metadata                                                    |

**Example**

JSON request payload:

```
{
  "paths": [
    "s3://my-bucket/dir/to/path"
  ],
  "options": {
    "batchSize": 1,
    "replicas": 1,
    "loadMetadataOnly": true,
    "loadPolicy": "IF_CHANGED"
  }
}
```

Success Response (JSON):

```
{
  "target":"job-95e8a01f-d519-4c1a-8311-26714f4db623",
  "id":"1cf35e69-b6e6-4807-8aae-588e0e994277"
}
```

**Error Codes**

| HTTP Code | Error Code            | Description                                                |
| --------- | --------------------- | ---------------------------------------------------------- |
| 200       | OK                    | Operation successful                                       |
| 400       | Bad Request           | Request body missing or required fields missing            |
| 409       | Conflict              | An identical job is already scheduled; submission rejected |
| 500       | Internal Server Error | Unexpected error                                           |

#### Get Load Job Progress

| **Method** | **Path**     | **Params** | **Request Body Type** |
| ---------- | ------------ | ---------- | --------------------- |
| GET        | /api/v1/load | Yes        | None                  |

**Parameters:**

| **Name**     | **Type** | **Required** | **Description**                                    | **Example**                                                                      |
| ------------ | -------- | ------------ | -------------------------------------------------- | -------------------------------------------------------------------------------- |
| `target`     | string   | Yes          | Field information returned when submitting the job | target=job-95e8a01f-d519-4c1a-8311-26714f4db623                                  |
| `fileList`   | bool     | No           | Retrieve the list of loaded files                  | target=job-95e8a01f-d519-4c1a-8311-26714f4db623\&fileList=true                   |
| `fileStatus` | string   | No           | File list type \[TOTAL\|FAILURE]                   | target=job-95e8a01f-d519-4c1a-8311-26714f4db623\&fileList=true\&fileStatus=TOTAL |

Note: 3.7 query parameters remain compatible, eg:`alias`,`index`

**Examples:**

Response for job execution status:

```json
{
    "id": "043cc6c2-b456-4d57-a807-a8c86256d8f2",
    "startTime": "2026-01-16T16:35:35.32+08:00",
    "endTime": "2026-01-16T16:35:42.149+08:00",
    "jobState": "SUCCEEDED",
    "timeElapsedMilliseconds": 6829,
    "paths": [
        "s3://test/index"
    ],
    "alias": "job-e7cc61f3-fdd5-45fe-a11b-e8f92f0c6d05",
    "batchSize": 200,
    "loadedBytes": 127,
    "totalBytes": 127,
    "loadedNonEmptyFiles": 1,
    "scannedFiles": 1,
    "replicas": "ALL"
}
```

Response for file list:

```
[
    {
        "path": "s3://test/index",
        "size": 0,
        "mTime": 0
    },
    {
        "path": "s3://test/index-copy",
        "size": 0,
        "mTime": 0
    }
]
```

**Error Codes**

| HTTP Code | Error Code            | Description          |
| --------- | --------------------- | -------------------- |
| 200       | OK                    | Operation successful |
| 404       | Not Found             | Job does not exist   |
| 500       | Internal Server Error | Unexpected error     |

#### Stop a load job

| **Method** | **Path**     | **Parameters** | **Request Body Type**          |
| ---------- | ------------ | -------------- | ------------------------------ |
| DELETE     | /api/v1/load | None           | Content-Type: application/json |

**Parameters**

| Name   | Type   | Required | Description                          | Example                                               |
| ------ | ------ | -------- | ------------------------------------ | ----------------------------------------------------- |
| target | string | Yes      | Target ID returned at job submission | {"target":"job-95e8a01f-d519-4c1a-8311-26714f4db623"} |

Note: Stop parameters remain compatible with version 3.7, eg:`alias`,`index`

**Error Codes**

| HTTP Status | Error Code  | Description                                |
| ----------- | ----------- | ------------------------------------------ |
| 200         | OK          | Operation successful                       |
| 400         | Bad Request | No request body or missing required fields |
| 404         | Not Found   | Load job does not exist                    |
| 410         | Gone        | Load job has already completed             |

#### List all load jobs

| **Method** | **Path**     | **Parameters** | **Request Body Type** |
| ---------- | ------------ | -------------- | --------------------- |
| GET        | /api/v1/load | yes            | None                  |

**Parameters:**

| **Name** | **Type** | **Required** | **Description**                  |
| -------- | -------- | ------------ | -------------------------------- |
| state    | enum     | No           | Job status \[RUNNING             |
| lastKey  | string   | No           | List jobs starting from this key |
| count    | int      | No           | Expected number of jobs to list  |

Note: If no parameters are provided, all jobs will be listed.

**Error Codes**

| HTTP Status | Error Code | Description          |
| ----------- | ---------- | -------------------- |
| 200         | OK         | Operation successful |

**Responses** Example response for listing jobs (JSON):

```
{
    "results": [
        {
            "id": "53b3123d-a042-4eb1-90e5-73798b963b04",
            "startTime": "2026-01-17T08:22:52.787+08:00",
            "endTime": "2026-01-17T08:22:57.289+08:00",
            "jobState": "SUCCEEDED",
            "timeElapsedMilliseconds": 4502,
            "paths": [
                "s3://tidas-alluxio-test/index"
            ],
            "alias": "job-1cfb048e-7ca7-48d3-8dd3-aa2ed8472176",
            "batchSize": 200,
            "loadedBytes": 127,
            "totalBytes": 127,
            "loadedNonEmptyFiles": 1,
            "scannedFiles": 1,
            "replicas": "ALL"
        },
        {
            "id": "89e288cf-480a-40df-a45b-91c3e08cb138",
            "startTime": "2026-01-17T08:22:54.117+08:00",
            "endTime": "1970-01-01T08:00:00+08:00",
            "jobState": "RUNNING",
            "runningStage": "LOADING",
            "paths": [
                "s3://tidas-alluxio-test/index"
            ],
            "alias": "job-9869111f-99f3-4ee4-9dbe-6c0204b96aec",
            "batchSize": 200,
            "replicas": "ALL"
        }
    ]
}
```

### Free Cache

Clean up worker cache data to release storage space.

#### Submit or resume a free job

| **Method** | **Path**     | **Parameters** | **Request Body Type**          |
| ---------- | ------------ | -------------- | ------------------------------ |
| POST       | /api/v1/free | None           | Content-Type: application/json |

**Parameters**

| **Name**  | **Type** | **Required** | **Description**                          | **Example**                                                                  |
| --------- | -------- | ------------ | ---------------------------------------- | ---------------------------------------------------------------------------- |
| `index`   | string   | No           | Index file path on UFS (must be mounted) | '{"index": "s3://bucket/key"}'                                               |
| `paths`   | string   | No           | List of UFS paths to be freed            | '{"paths": \["s3://bucket/key1", "s3://bucket/key2"]}'                       |
| `alias`   | string   | No           | Used with paths for status queries       | '{"paths": \["s3://bucket/key1", "s3://bucket/key2"], "alias": "database1"}' |
| `options` | object   | No           | Configuration options for the free job   | '{"index": s3://bucket/key, "options":{"batchSize":10}}'                     |

Note: Either `index` or `paths` must be provided. If `paths` is used, an `alias` can be specified; otherwise, an internal random alias will be generated.

At most one of the parameters is required. Paths and alias must be provided together.

An `options` JSON can be used to configure the options of the free job. All options are optional. Possible configs are:

| **Name**       | **Type** | **Required** | **Description**                                        |
| -------------- | -------- | ------------ | ------------------------------------------------------ |
| `batchSize`    | int      | No           | Speed at which the worker frees cache files per second |
| `replicas`     | int      | No           | Number of file replicas to free                        |
| `indexService` | bool     | No           | Free directory cache                                   |

**Example**

An example JSON request payload looks like the following:

```json
{
    "paths": [
        "s3://tidas-alluxio-test/index",
        "s3://tidas-alluxio-test/index-copy"
    ],
    "options": {
        "batchSize": "30"
    }
}
```

Successful Response (JSON):

```
{
    "target": "job-0aafec67-53b4-488c-b988-73493b2b9ebe",
    "id": "bc0c3296-ea1f-484b-b371-300bf4d54ca6"
}
```

#### Get Free Job Progress

| **Method** | **Path**     | **Parameters** | **Request Body Type** |
| ---------- | ------------ | -------------- | --------------------- |
| GET        | /api/v1/free | Yes            | None                  |

**Parameters:**

| Name   | Type   | Required | Description                                | Example                |
| ------ | ------ | -------- | ------------------------------------------ | ---------------------- |
| target | string | Yes      | The field returned when submitting the job | target=job-95e8a01f... |

Note: 3.7 query parameters remain compatible, eg:`alias`,`index`

**Example**

Successful response for job status (JSON): **Responses:**

```
{
    "id": "17bb4213-891b-4c3f-bc32-8d314051514b",
    "startTime": "2026-01-17T21:59:11.831+08:00",
    "endTime": "2026-01-17T21:59:16.104+08:00",
    "jobState": "SUCCEEDED",
    "timeElapsedMilliseconds": 4273,
    "paths": ["s3://test/"],
    "alias": "job-95adb50b-4722-4a79-bd58-872cfeca48cb",
    "freedBytes": 409600,
    "totalBytes": 409600,
    "freedFiles": 100,
    "totalFiles": 100
}
```

**Error Codes**

| HTTP Status | Error Code | Description             |
| ----------- | ---------- | ----------------------- |
| 200         | OK         | Operation successful    |
| 404         | Not Found  | Load job does not exist |

#### Stop a free job

| **Method** | **Path**     | **Parameters** | **Request Body Type**          |
| ---------- | ------------ | -------------- | ------------------------------ |
| DELETE     | /api/v1/free | None           | Content-Type: application/json |

**Parameters**

| Name   | Type   | Required | Description                                | Example                                               |
| ------ | ------ | -------- | ------------------------------------------ | ----------------------------------------------------- |
| target | string | Yes      | The field returned when submitting the job | {"target":"job-95e8a01f-d519-4c1a-8311-26714f4db623"} |

Note: Stop parameters remain compatible with version 3.7, eg:`alias`,`index`

**Error Codes**

| HTTP Status | Error Code  | Description                                |
| ----------- | ----------- | ------------------------------------------ |
| 200         | OK          | Operation successful                       |
| 400         | Bad Request | No request body or missing required fields |
| 404         | Not Found   | Job does not exist                         |
| 410         | Gone        | Job has already completed                  |

#### List all free jobs

| **Method** | **Path**     | **Parameters** | **Request Body Type** |
| ---------- | ------------ | -------------- | --------------------- |
| GET        | /api/v1/free | yes            | None                  |

**Parameters:**

| **Name** | **Type** | **Required** | **Description**                  |
| -------- | -------- | ------------ | -------------------------------- |
| state    | enum     | No           | Job status \[RUNNING             |
| lastKey  | string   | No           | List jobs starting from this key |
| count    | int      | No           | Expected number of jobs to list  |

Note: If no parameters are provided, all jobs will be listed.

**Error Codes**

| HTTP Status | Error Code | Description          |
| ----------- | ---------- | -------------------- |
| 200         | OK         | Operation successful |

**Response** Example response for listing jobs (JSON):

```
{
    "results": [
        {
            "id": "1498117f-bf66-4198-967d-1186588c56d1",
            "startTime": "2026-01-17T22:13:35.198+08:00",
            "endTime": "2026-01-17T22:13:40.385+08:00",
            "jobState": "SUCCEEDED",
            "timeElapsedMilliseconds": 5187,
            "paths": ["s3://test/rest1/test/"],
            "alias": "job-312c44ac-156c-4e5a-b142-e540067ad086"
        },
        {
            "id": "3baf5ab6-c303-4a59-8678-f297870847f4",
            "startTime": "2026-01-17T22:13:26.177+08:00",
            "endTime": "2026-01-17T22:13:30.38+08:00",
            "jobState": "SUCCEEDED",
            "timeElapsedMilliseconds": 4203,
            "paths": ["s3://test/rest/test/"],
            "alias": "job-749f2cbf-32cb-44d5-aa4f-4a4e6b94689b"
        }
    ]
}
```

### Rebalance

#### List all rebalance jobs

**Method:** `GET`

**Path:** `/api/v1/rebalance`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "results": [
      {...}
    ]
  }
  ```

  for more information on the job description, please refer to the **“Get the progress of a rebalance job”**
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Get the progress of a rebalance job

**Method:** `GET`

**Path:** `/api/v1/rebalance`

**Parameters:**

At most one of the parameters is required.

| **Name** | **Description**                                                                                                                    |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `id`     | job id returned by POST                                                                                                            |
| `target` | the target workers of the rebalance job, can bea worker id (e.g. worker-54b88939-de49-46ef-acab-fe489f46d1a0)ALL (for all workers) |

**Responses:**

* `200 - OK`: successful operation(empty value will be omitted)

  ```json
  {
     "succeededWorkers":2,
     "bytesPreserved":4,
     "filesLoaded":0,
     "filesPreserved":1,
     "filesFailed":0,
     "totalWorkers":2,
     "bytesPruned":226,
     "filesPruned":5,
     "bytesLoaded":0,
     "timeElapsedMilliseconds":4536,
     "runningWorkers":0,
     "startTime":"2024-12-19T23:15:07.043+08:00",
     "id":"8de63d3a-63c8-4f08-bbc1-c87e3c0fb6d9",
     "state":"SUCCEEDED",
     "failedWorkers":0
  }
  ```
* `404 - Not Found`: no job found

  ```json
  {
    "status": "No job found..."
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Submit or resume a rebalance job

**Method:** `POST`

**Path:** `/api/v1/rebalance`

**Parameters:** none

**Request body:** `Content-Type: application/json`

Required field

| **Name** | **Description**                                                                                                                                    |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `target` | The target workers of the rebalance job, can be either a worker id (e.g. `worker-54b88939-de49-46ef-acab-fe489f46d1a0`) or `ALL` (for all workers) |

An `options` JSON can be used to configure the options of the load job. All options are optional. Possible configs are:

| **Name**         | **Description**                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| `loadBatchSize`  | the batch size in the loading phase, the same as the batchSize option in the load job             |
| `loadBandwidth`  | The load bandwidth of each worker per second in bytes. e.g.: 10485746000...                       |
| `pruneBandwidth` | The prune bandwidth of each worker per second in bytes. e.g.: 10485746000...                      |
| `skipPrune`      | If rebalance should only load data and skip pruning the data that does not blong to the worker(s) |

An example JSON request payload looks like the following:

```json
{
  "target": "ALL",
  "options": {
    "loadBatchSize": 1000,
    "loadBandwidth": 10485746000,
    "pruneBandwidth": 10485746000,
    "skipPrune": false,
  }
}
```

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "id": "54b88939-de49-46ef-acab-fe489f46d1a0"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `409 - Conflict`: resume the load job with the same path and return the previous job id

  ```json
  {
    "id": "54b88939-de49-46ef-acab-fe489f46d1a0"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Stop a rebalance job

**Method:** `DELETE`

**Path:** `/api/v1/rebalance`

**Parameters:** none

**Request body:** `Content-Type: application/json`

At most one of the parameters is required.

| **Name** | **Description**                                                                                                                                    |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`     | job id returned by POST                                                                                                                            |
| `target` | the target workers of the rebalance job, can be either a worker id (e.g. `worker-54b88939-de49-46ef-acab-fe489f46d1a0`) or `ALL` (for all workers) |

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `410 - Gone`: the job doesn’t exist or has already finished

  ```json
  {
    "status": "The job doesn't exist or has already finished"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

### Clear Stale Cache

> This operation differs from the [Free Cache](#free-cache) operation in that:
>
> 1. The free job requires a list of files or directories as input arguments to specify what to free from the workers. The Clear Stale Cache operation does not require such input because what counts as “stale cache” is determined automatically by scanning the worker cache storage and consulting the current consistent hash ring.
> 2. The free job requires setting the correct number of replicas, otherwise it may free fewer replicas than expected, if file replication is enabled. The clear stale cache operation simply broadcasts to all the workers in the cluster, so it always triggers the clearing of stale cache on all workers, regardless of how many replicas there are.

#### Start clearing stale cache

**Method:** `POST`

**Path:** `/api/v1/cache`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "op": "clear-stale"
}
```

**Responses:**

* `200 - OK`: an empty errors object indicates that the operation has been successfully submitted to all workers for execution

  ```json
  {
    "errors": {}
  }
  ```
* `200 - OK`: non-empty errors object indicates that the operation fails to be submitted to at least one of the workers for execution

  ```json
  {
    "errors": {
      "worker-host": "error message"
    }
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: the specified operation type is not implemented

  ```json
  {
    "status": "OP not implemented"
  }
  ```

#### Stop clearing stale cache

**Method:** `DELETE`

**Path:** `/api/v1/cache`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "op": "clear-stale"
}
```

**Responses:**

* `200 - OK`: an empty errors object indicates that all workers have been successfully notified to stop clearing stale cache

  ```json
  {
    "errors": {}
  }
  ```
* `200 - OK`: non-empty errors object indicates that the coordinator fails to notify at least one of the workers to stop clearing stale cache

  ```json
  {
    "errors": {
      "worker-host": "error message"
    }
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: the specified operation type is not implemented

  ```json
  {
    "status": "OP not implemented"
  }
  ```

### Mount Table

#### List mount points

**Method:** `GET`

**Path:** `/api/v1/mount`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation(options will be omitted if empty)

  ```json
  {
    "results": [
      {
        "path": "/data/",
        "ufs": "s3://my-bucket/",
        "options": {
          "s3a.secretKey": "string",
          "s3a.accessKeyId": "string"
        }
      }
    ]
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Get mount point information

**Method:** `GET`

**Path:** `/api/v1/mount`

**Parameters:**

| **Name** | **Description**                        |
| -------- | -------------------------------------- |
| `path`   | Alluxio or UFS path of the mount point |

**Responses:**

* `200 - OK`: successful operation(options will be omitted if empty)

  ```json
  {
    "path": "/data/",
    "ufs": "s3://my-bucket/",
    "options": {
      "s3a.secretKey": "string",
      "s3a.accessKeyId": "string"
    }
  }
  ```
* `404 - Not Found`: mount point not found

  ```json
  {
    "status": "No mount point found for path: /data/"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Create a mount point

**Method:** `POST`

**Path:** `/api/v1/mount`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data",
  "ufs": "s3://my-bucket",
  "options": {
    "s3a.secretKey": "string",
    "s3a.accessKeyId": "string"
  }
}
```

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `409 - Conflict`: the path is already mounted, or the UFS has been mounted to another path

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: the mount table doesn’t support managing via an API (e.g.: static file mount table)

  ```json
  {
    "status": "string"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Delete a mount point

**Method:** `DELETE`

**Path:** `/api/v1/mount`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data"
}
```

Note that the path can be either a UFS path or an Alluxio path.

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `410 - Gone`: the path isn’t mounted to any UFS

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: the mount table doesn’t support managing via an API (e.g.: static file mount table)

  ```json
  {
    "status": "string"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

### Quota

#### List all quota status

**Method:** `GET`

**Path:** `/api/v1/quota`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "results": [
      {
        "path": "/data/dir/to/path",
        "state": "Available",
        "quotaBytes": 10737418240,
        "usedBytes": 9663676416,
        "reservedBytes": 1073741824
      }
    ]
  }
  ```

  Note that the returned paths are Alluxio paths.
* `501 - Not Implemented`: quota is not enabled

  ```json
  {
    "status": "Quota not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Get quota status

**Method:** `GET`

**Path:** `/api/v1/quota`

**Parameters:**

| **Name** | **Description**                       |
| -------- | ------------------------------------- |
| `path`   | Alluxio or UFS path of the quota rule |

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "path": "/data/dir/to/path",
    "state": "Available",
    "quotaBytes": 10737418240,
    "usedBytes": 9663676416,
    "reservedBytes": 1073741824
  }
  ```

  Note that the returned paths are Alluxio paths.
* `404 - Not Found`: quota not found

  ```json
  {
    "status": "No quota item found for path: /data/dir/to/path"
  }
  ```
* `501 - Not Implemented`: quota is not enabled

  ```json
  {
    "status": "Quota not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Add or update quota

**Method:** `POST`

**Path:** `/api/v1/quota`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data/dir/to/path",
  "quotaBytes": 10737418240
}
```

Note that the path can be either a UFS path or an Alluxio path. The path must have been mounted in Alluxio's mount table.

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `400 - Bad Request`: the path doesn’t refer to a mounted UFS but it must be bound with an existing UFS

  ```json
  {
    "status": "No mounted UFS found"
  }
  ```
* `501 - Not Implemented`: quota is not enabled

  ```json
  {
    "status": "Quota not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Delete quota

**Method:** `DELETE`

**Path:** `/api/v1/quota`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data/dir/to/path"
}
```

Note that the path can be either a UFS path or an Alluxio path. The path must have been mounted in Alluxio's mount table.

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `400 - Bad Request`: quota not found or other problems

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: quota is not enabled

  ```json
  {
    "status": "Quota not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

### TTL

#### List all TTL policies

**Method:** `GET`

**Path:** `/api/v1/ttl`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "results": [
      {
        "path": "/data/dir/to/path",
        "ttlSeconds": 600
      }
    ]
  }
  ```

  Note that the returned path is an Alluxio path.
* `501 - Not Implemented`: TTL policy is not enabled

  ```json
  {
    "status": "TTL not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Get TTL policy

**Method:** `GET`

**Path:** `/api/v1/ttl`

**Parameters:**

| **Name** | **Description**                                  |
| -------- | ------------------------------------------------ |
| `path`   | Alluxio or UFS path of the TTL policy to look up |

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "path": "/data/dir/to/path",
    "ttlSeconds": 600
  }
  ```

  Note that the returned path is an Alluxio path.
* `404 - Not Found`: TTL not found

  ```json
  {
    "status": "No TTL policy found for path: /data/dir/to/path"
  }
  ```
* `501 - Not Implemented`: TTL policy is not enabled

  ```json
  {
    "status": "TTL not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Add or update TTL

**Method:** `POST`

**Path:** `/api/v1/ttl`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data/dir/to/path",
  "ttlSeconds": 600
}
```

Note that the path can be either a UFS path or an Alluxio path. The path must have been mounted in Alluxio's mount table.

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `400 - Bad Request`: the path doesn’t refer to a mounted UFS but it must be bound with an existing UFS

  ```json
  {
    "status": "No mounted UFS found"
  }
  ```
* `501 - Not Implemented`: TTL policy is not enabled

  ```json
  {
    "status": "TTL not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Delete TTL

**Method:** `DELETE`

**Path:** `/api/v1/ttl`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data/dir/to/path"
}
```

Note that the path can be either a UFS path or an Alluxio path. The path must have been mounted in Alluxio's mount table.

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `400 - Bad Request`: TTL not found

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: TTL is not enabled

  ```json
  {
    "status": "TTL not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

### Priority Eviction

#### List all priority eviction policies

**Method:** `GET`

**Path:** `/api/v1/priority`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "results": [
      {
        "path": "/data/dir/to/path",
        "priority": "high"
      }
    ]
  }
  ```

Note that the returned paths are Alluxio paths.

* `501 - Not Implemented`: Priority eviction is not enabled

  ```json
  {
    "status": "Priority eviction not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Get priority eviction policy

**Method:** `GET`

**Path:** `/api/v1/priority`

**Parameters:**

| **Name** | **Description**                                     |
| -------- | --------------------------------------------------- |
| `path`   | Alluxio or UFS path of the priority rule to look up |

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "path": "/data/dir/to/path",
    "priority": "high"
  }
  ```

  Note that the returned path is an Alluxio path.
* `404 - Not Found`: priority eviction not found

  ```json
  {
    "status": "No priority rule found for path: /data/dir/to/path"
  }
  ```
* `501 - Not Implemented`: priority eviction is not enabled

  ```json
  {
    "status": "Priority eviction not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Add or update priority

**Method:** `POST`

**Path:** `/api/v1/priority`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data/dir/to/path",
  "priority": "high"
}
```

Note that the path can be either a UFS path or an Alluxio path. The path must have been mounted in Alluxio's mount table.

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `400 - Bad Request`: priority string misformatted or other problems

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: priority eviction is not enabled

  ```json
  {
    "status": "Priority eviction not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Delete priority

**Method:** `DELETE`

**Path:** `/api/v1/priority`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "path": "/data/dir/to/path"
}
```

Note that the path can be either a UFS path or an Alluxio path. The path must have been mounted in Alluxio's mount table.

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `501 - Not Implemented`: priority eviction is not enabled

  ```json
  {
    "status": "Priority eviction not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

### Node management

#### List all nodes

**Method:** `GET`

**Path:** `/api/v1/nodes`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "result": [
      {
        "identity": "worker-587899dd-5da5-45d4-af40-ce481acc4087",
        "address": "192.168.1.19:29989",
        "status": "ONLINE"
      },
      {
        "identity": "worker-844db66c-d7fd-46cc-8de0-2f3989360828",
        "address": "192.168.1.19:29999",
        "status": "OFFLINE"
      }
    ]
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Query a node

**Method:** `GET`

**Path:** `/api/v1/nodes`

**Parameters:**

| **Name** | **Description**                                              |
| -------- | ------------------------------------------------------------ |
| `id`     | worker id (e.g. worker-587899dd-5da5-45d4-af40-ce481acc4087) |

**Responses:**

* `200 - OK`: successful operation\
  (empty value will be omitted)

  ```json
  {
    "identity": "worker-587899dd-5da5-45d4-af40-ce481acc4087",
    "address": "192.168.1.19:29989",
    "status": "ONLINE"
  }
  ```
* `404 - Not Found`: worker not found

  ```json
  {
    "status": "worker not found..."
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Decommission a node (remove a node from etcd)

**Method:** `DELETE`

**Path:** `/api/v1/nodes`

**Parameters:**

| **Name** | **Description**                                              |
| -------- | ------------------------------------------------------------ |
| `id`     | worker id (e.g. worker-587899dd-5da5-45d4-af40-ce481acc4087) |

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "status": "ok"
  }
  ```
* `404 - Not Found`: worker not found

  ```json
  {
    "status": "worker not found..."
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

### Global File Index

#### List all nodes

**Method:** `GET`

**Path:** `/api/v1/file_index`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation

  ```json
  {
    "results": [
      "file:///home/yimin/alluxio/ufs/10MB",
      "file:///home/yimin/alluxio/ufs/to_load/f1"
    ]
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Add files into the global file index

**Method:** `POST`

**Path:** `/api/v1/file_index`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "files": [
    "s3://foo/bar/f1",
    "s3://foo/bar/f2"
  ]
}
```

**Responses:**

* `200 - OK`: successful operation (# of entries added)

  ```json
  {
    "entries": 10
  }
  ```
* `404 - Not Found`: feature not enabled

  ```json
  {
    "status": "Global file index is not enabled"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

#### Remove files from the global file index

**Method:** `DELETE`

**Path:** `/api/v1/file_index`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "files": [
    "s3://foo/bar/f1",
    "s3://foo/bar/f2"
  ]
}
```

**Responses:**

* `200 - OK`: successful operation (# of entries removed)

  ```json
  {
    "entries": 10
  }
  ```
* `404 - Not Found`: feature not enabled

  ```json
  {
    "status": "worker not found..."
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```

### Cache Filter

#### List all cache filter rules

**Method:** `GET`

**Path:** `/api/v1/cache-filter`

**Parameters:** none

**Responses:**

* `200 - OK`: successful operation

```json
{
  "results": [
    {
      "apiVersion": 1,
      "type": "metadata",
      "rules": {
        "defaultType": "immutable",
        "defaultMaxAge": null,
        "skipCache": ["s3://bucket/mutable-dir/.*"],
        "immutable": ["s3://bucket/immutable-dir/.*"],
        "maxAge": {"s3://bucket/auto-refresh/.*":  "1d"}
      }
    },
    {
      "apiVersion": 1,
      "type": "data",
      "rules": {
        "defaultType": "immutable",
        "defaultMaxAge": null,
        "skipCache": [],
        "immutable": [],
        "maxAge": {}
      }
    }
  ]
}
```

* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: cache filter is not enabled

  ```json
  {
    "status": "Cache filter not enabled"
  }
  ```

#### Add a cache filter rule or update the default rule

**Method:** `POST`

**Path:** `/api/v1/cache-filter`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "type": "data",
  "rule": "skipCache",
  "pattern": "s3a://data-bucket/c/.*"
}
```

If the rule is `maxAge`, a `time` is required.

```json
{
  "type": "data",
  "rule": "maxAge",
  "pattern": "s3a://auto-refresh/c/.*",
  "time": "1d"
}
```

If you want to update the default rule, set `updateDefault`. No need to specify a `pattern` because all paths that don't match any other rules will be captured by the default rule.

```json
{
  "type": "metadata",
  "rule": "skipCache",
  "updateDefault": true
}
```

**Responses:**

* `200 - OK`: successful operation
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: cache filter is not enabled

  ```json
  {
    "status": "Cache filter not enabled"
  }
  ```

#### Remove a cache filter rule

**Method:** `DELETE`

**Path:** `/api/v1/cache-filter`

**Parameters:** none

**Request body:** `Content-Type: application/json`

```json
{
  "type": "data",
  "rule": "skipCache",
  "pattern": "s3a://data-bucket/c/.*"
}
```

No need to specify `time` if the rule is `maxAge`. Also, you can't remove a default rule. You can only change the default to another rule.

**Responses:**

* `200 - OK`: successful operation
* `400 - Bad Request`: the request doesn’t have a body or the required fields are missing

  ```json
  {
    "status": "Required parameters not provided"
  }
  ```
* `500 - Internal Server Error`: unexpected error

  ```json
  {
    "status": "string"
  }
  ```
* `501 - Not Implemented`: cache filter is not enabled

  ```json
  {
    "status": "Cache filter not enabled"
  }
  ```
