# Kiteworks API — clients Operations

**7 endpoints** | [Browse interactive reference](https://developer.kiteworks.com/api-reference/clients.html) | [Download spec slice](https://developer.kiteworks.com/assets/specs/clients.json)

> **Authentication required.** All requests must include a Bearer access token in the
> `Authorization` header. See [Authentication](https://developer.kiteworks.com/authentication.md) for how to
> obtain a token using OAuth 2.0 Authorization Code (PKCE) or JWT Bearer flow.

---

## GET /rest/clients

**Summary:** List clients

Returns a list of registered OAuth clients. Hidden clients are excluded from the results.

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `name` | query | no | Client name |
| `name:contains` | query | no | Client name. Search for results that contain the specified characters in this parameter. |
| `description:contains` | query | no | Client description. Search for results that contain the specified characters in this parameter. |
| `orderBy` | query | no | Sorting options |
| `offset` | query | no | Offset |
| `limit` | query | no | Limit |
| `with` | query | no | With parameters |
| `mode` | query | no | Determines the detail level of the response body. |

**Responses:**

| Code | Description |
|------|-------------|
| 200 | Returns a paginated list of OAuth client records. |
| 490 | Request blocked by WAF |

**Response Examples:**

**200 (Client list):**

```json
{
  "data": [
    {
      "id": "mobile_app_ios",
      "name": "iOS Mobile App",
      "description": "Company iOS mobile client",
      "redirect_uri": "https://example.com/callback",
      "scope": "*",
      "flag": 0,
      "flow": 1,
      "access_token_lifetime": 24,
      "refresh_token_lifetime": 720,
      "type": 2,
      "touch_id": true,
      "min_version": 28
    },
    {
      "id": "custom_integration",
      "name": "Custom Integration",
      "description": "Third-party integration client",
      "redirect_uri": "https://integration.example.com/callback",
      "scope": "files folders",
      "flag": 0,
      "flow": 1,
      "access_token_lifetime": 8,
      "refresh_token_lifetime": 168,
      "type": 0,
      "touch_id": false,
      "min_version": 28
    }
  ],
  "total": 2,
  "page": 1,
  "pageSize": 20
}
```

**Code Samples:**

**cURL:**

```shell
curl -X GET \
  "https://{instance}.kiteworks.com/rest/clients" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

**Python:**

```python
import requests

url = "https://{instance}.kiteworks.com/rest/clients"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.json())
```

---

## POST /rest/clients

**Summary:** Create a client

Creates a new OAuth client (e.g. a custom mobile app). The response includes the plain-text `client_secret`, which is only returned once at creation time and cannot be retrieved again.

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `returnEntity` | query | no | If set to `true`, returns information about the newly created entity. |
| `mode` | query | no | Determines the detail level of the response body. |

**Request Body:**

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | string | yes | Display name of the client application |
| `description` | string | yes | Human-readable description of the client application and its purpose |
| `redirectUri` | string | yes | Where the server send the code that client can redeem access token.                         e.g. https://HOST/rest/callback.html |
| `scope` | string | yes | API entities which this client can access |
| `signatureKey` | string | no | Secret key used to sign requests made by this client |
| `accessTokenLifetime` | integer | no | Life time for access token of client in hours. e.g. 5=5 hours |
| `refreshTokenLifetime` | integer | no | Life time for refresh token of client in hours |
| `addLinks` | boolean | no | Indicates whether HATEOAS links should be included in the response |

**Responses:**

| Code | Description |
|------|-------------|
| 200 | Returns the newly created client record, including the plain-text `client_secret`. |
| 409 | Conflict  <i>Possible error codes: </i>ERR_ENTITY_EXISTS |
| 422 | Unprocessable Content  <i>Possible error codes: </i>ERR_INPUT_REQUIRED, ERR_INPUT_NOT_INTEGER, ERR_INPUT_MIN_VALUE |
| 490 | Request blocked by WAF |

**Response Examples:**

**200 (Client created):**

```json
{
  "id": "custom_integration",
  "client_secret": "p1a2i3n4t5e6x7t8s9e0c",
  "name": "Custom Integration",
  "description": "Third-party integration client",
  "redirect_uri": "https://integration.example.com/callback",
  "scope": "files folders",
  "flag": 0,
  "flow": 1,
  "access_token_lifetime": 8,
  "refresh_token_lifetime": 168,
  "type": 0,
  "touch_id": false,
  "min_version": 28
}
```

**409 (ERR_ENTITY_EXISTS):**

```json
{
  "errors": {
    "code": "ERR_ENTITY_EXISTS",
    "message": "Entity exists"
  }
}
```

**422 (ERR_INPUT_REQUIRED):**

```json
{
  "errors": {
    "code": "ERR_INPUT_REQUIRED",
    "message": "Field is required"
  }
}
```

**422 (ERR_INPUT_NOT_INTEGER):**

```json
{
  "errors": {
    "code": "ERR_INPUT_NOT_INTEGER",
    "message": "Input is not a valid integer"
  }
}
```

**422 (ERR_INPUT_MIN_VALUE):**

```json
{
  "errors": {
    "code": "ERR_INPUT_MIN_VALUE",
    "message": "The specified input below the minimum allowed value."
  }
}
```

**Code Samples:**

**cURL:**

```shell
curl -X POST \
  "https://{instance}.kiteworks.com/rest/clients" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
         "name": "string",
         "description": "string",
         "redirectUri": "string",
         "scope": "string",
         "signatureKey": "string",
         "accessTokenLifetime": 1
       }'
```

**Python:**

```python
import requests

url = "https://{instance}.kiteworks.com/rest/clients"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
}
payload = {
  "name": "string",
  "description": "string",
  "redirectUri": "string",
  "scope": "string",
  "signatureKey": "string",
  "accessTokenLifetime": 1
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
```

---

## GET /rest/clients/me

**Summary:** Get current client

Returns the settings of the OAuth client used to make the current request (e.g. pin timeout, token lifetime).
**Responses:**

| Code | Description |
|------|-------------|
| 200 | Returns the OAuth client record for the client making the request. |
| 490 | Request blocked by WAF |

**Response Examples:**

**200 (Current client settings):**

```json
{
  "id": "mobile_app_ios",
  "name": "iOS Mobile App",
  "description": "Company iOS mobile client",
  "redirect_uri": "https://example.com/callback",
  "scope": "*",
  "flag": 0,
  "flow": 1,
  "access_token_lifetime": 24,
  "refresh_token_lifetime": 720,
  "ask_pin": 1,
  "pin_timeout": 5,
  "max_pin_attempts": 5,
  "type": 2,
  "touch_id": true,
  "min_version": 28
}
```

**Code Samples:**

**cURL:**

```shell
curl -X GET \
  "https://{instance}.kiteworks.com/rest/clients/me" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

**Python:**

```python
import requests

url = "https://{instance}.kiteworks.com/rest/clients/me"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.json())
```

---

## GET /rest/clients/{id}

**Summary:** Get a client

Returns the settings for the specified OAuth client (e.g. an iOS mobile app), including token lifetimes, PIN policy, scope, and OAuth flow configuration.

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The unique identifier of the client. |

**Responses:**

| Code | Description |
|------|-------------|
| 200 | Returns the OAuth client record. |
| 490 | Request blocked by WAF |

**Response Examples:**

**200 (Client settings):**

```json
{
  "id": "custom_integration",
  "name": "Custom Integration",
  "description": "Third-party integration client",
  "redirect_uri": "https://integration.example.com/callback",
  "scope": "files folders",
  "flag": 0,
  "flow": 1,
  "access_token_lifetime": 8,
  "refresh_token_lifetime": 168,
  "type": 0,
  "touch_id": false,
  "min_version": 28
}
```

**Code Samples:**

**cURL:**

```shell
curl -X GET \
  "https://{instance}.kiteworks.com/rest/clients/:id" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

**Python:**

```python
import requests

id = "VALUE"  # The unique identifier of the client.

url = f"https://{{instance}}.kiteworks.com/rest/clients/{id}"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.json())
```

---

## PUT /rest/clients/{id}

**Summary:** Update a client

Updates the settings for the specified OAuth client. The fields available for update depend on the client type: custom clients support `name`, `description`, `redirectUri`, `accessTokenLifetime`, `refreshTokenLifetime`, `scope`, and `signatureKey`; built-in clients support only `accessTokenLifetime` and `refreshTokenLifetime`.

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | ID of the client to be updated |

**Request Body:**

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | string | yes | Display name of the client application |
| `description` | string | yes | Human-readable description of the client application and its purpose |
| `redirectUri` | string | yes | Where the server send the code that client can redeem access token.                         e.g. https://HOST/rest/callback.html |
| `scope` | string | yes | API entities which this client can access |
| `signatureKey` | string | no | Secret key used to sign requests made by this client |
| `accessTokenLifetime` | integer | no | Life time for access token of client in hours. e.g. 5=5 hours |
| `refreshTokenLifetime` | integer | no | Life time for refresh token of client in hours |
| `addLinks` | boolean | no | Indicates whether HATEOAS links should be included in the response |

**Responses:**

| Code | Description |
|------|-------------|
| 200 | Returns the updated OAuth client record. |
| 403 | Forbidden  <i>Possible error codes: </i>ERR_ACCESS_USER |
| 490 | Request blocked by WAF |

**Response Examples:**

**200 (Client updated):**

```json
{
  "id": "custom_integration",
  "name": "Custom Integration v2",
  "description": "Updated third-party integration client",
  "redirect_uri": "https://integration.example.com/callback",
  "scope": "files folders",
  "flag": 0,
  "flow": 1,
  "access_token_lifetime": 12,
  "refresh_token_lifetime": 336,
  "type": 0,
  "touch_id": false,
  "min_version": 28
}
```

**403 (ERR_ACCESS_USER):**

```json
{
  "errors": {
    "code": "ERR_ACCESS_USER",
    "message": "Insufficient access permissions"
  }
}
```

**Code Samples:**

**cURL:**

```shell
curl -X PUT \
  "https://{instance}.kiteworks.com/rest/clients/:id" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
         "name": "string",
         "description": "string",
         "redirectUri": "string",
         "scope": "string",
         "signatureKey": "string",
         "accessTokenLifetime": 1
       }'
```

**Python:**

```python
import requests

id = "VALUE"  # ID of the client to be updated

url = f"https://{{instance}}.kiteworks.com/rest/clients/{id}"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
}
payload = {
  "name": "string",
  "description": "string",
  "redirectUri": "string",
  "scope": "string",
  "signatureKey": "string",
  "accessTokenLifetime": 1
}
response = requests.put(url, headers=headers, json=payload)
print(response.json())
```

---

## DELETE /rest/clients/{id}

**Summary:** Delete a client

Deletes the specified OAuth client. Built-in system clients cannot be deleted.

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | ID of the client to be deleted |

**Responses:**

| Code | Description |
|------|-------------|
| 204 | The client was successfully deleted. Returns no content. |
| 403 | Forbidden  <i>Possible error codes: </i>ERR_ACCESS_USER |
| 490 | Request blocked by WAF |

**Response Examples:**

**403 (ERR_ACCESS_USER):**

```json
{
  "errors": {
    "code": "ERR_ACCESS_USER",
    "message": "Insufficient access permissions"
  }
}
```

**Code Samples:**

**cURL:**

```shell
curl -X DELETE \
  "https://{instance}.kiteworks.com/rest/clients/:id" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

**Python:**

```python
import requests

id = "VALUE"  # ID of the client to be deleted

url = f"https://{{instance}}.kiteworks.com/rest/clients/{id}"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
}
response = requests.delete(url, headers=headers)
print(response.json())
```

---

## GET /rest/clients/{id}/scopes

**Summary:** List scopes of a client

Returns the list of API resource scopes the specified client is authorized to access, such as folders, files, members, and comments.

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | ID of the client whose scopes to be retrieved |
| `mode` | query | no | Determines the detail level of the response body. |

**Responses:**

| Code | Description |
|------|-------------|
| 200 | Client scopes retrieved successfully. |
| 490 | Request blocked by WAF |

**Response Examples:**

**200 (ClientScopes):**

```json
{
  "data": [
    "folders/*",
    "files/*",
    "members/*",
    "comments/*"
  ]
}
```

**Code Samples:**

**cURL:**

```shell
curl -X GET \
  "https://{instance}.kiteworks.com/rest/clients/:id/scopes" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

**Python:**

```python
import requests

id = "VALUE"  # ID of the client whose scopes to be retrieved

url = f"https://{{instance}}.kiteworks.com/rest/clients/{id}/scopes"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.json())
```

---
