# Upsert consumer tool permissions for a connected account

**Documentation:** /reference/api-reference/consumer/patchConsumerConnectedAccountsByNanoidPermissions

Upserts durable Enhanced Control per-tool permission rows for a connected account. This is a scaffolded write path for initial connect/settings flows.

---

## PATCH `/api/v3.1/consumer/connected_accounts/{nanoid}/permissions`

**Endpoint:** `https://backend.composio.dev/api/v3.1/consumer/connected_accounts/{nanoid}/permissions`

**Summary:** Upsert consumer tool permissions for a connected account

Upserts durable Enhanced Control per-tool permission rows for a connected account. This is a scaffolded write path for initial connect/settings flows.

### Authentication

**ApiKeyAuth** - API Key in `header` header `x-api-key` OR **UserApiKeyAuth** - API Key in `header` header `x-user-api-key`

### Path Parameters

- `nanoid` (string (connectedAccountId)) *(required)*: Connected account nano ID.

### Request Body

**Schema:**

- `permissions` (array<object>) *(required)*: Tool permission rows to upsert for this connected account.
  - Array items:
    - `tool_slug` (string) *(required)*
    - `toolkit_slug` (string) *(required)*: Toolkit slug that owns this tool permission. Use this to group and query connected-account permissions by app/toolkit, for example `gmail` or `slack`.
    - `risk_group` (enum: "read" | "write" | "destructive") *(required)*
    - `state` (enum: "always_allow" | "always_deny" | "ask_once" | ...) *(required)*
    - `source` (enum: "initial_connect" | "settings" | "elicitation" | ...)
    - `permission_config_version` (string)

**Example:**

```json
{
  "permissions": [
    {
      "tool_slug": "string",
      "toolkit_slug": "string",
      "risk_group": "read",
      "state": "always_allow",
      "source": "settings",
      "permission_config_version": "string"
    }
  ]
}
```

### Responses

#### 200 - Connected account tool permissions updated successfully.

**Response Schema:**

- `permissions` (array<object>) *(required)*
  - Array items:
    - `id` (string) *(required)*
    - `connected_account_id` (string) *(required)*
    - `tool_slug` (string) *(required)*
    - `toolkit_slug` (string) *(required)*: Normalized toolkit slug that owns this tool permission. Use this to group permissions by app/toolkit, for example `gmail` or `slack`.
    - `risk_group` (enum: "read" | "write" | "destructive") *(required)*
    - `state` (enum: "always_allow" | "always_deny" | "ask_once" | ...) *(required)*
    - `source` (enum: "initial_connect" | "settings" | "elicitation" | ...) *(required)*
    - `permission_config_version` (string,null) *(required)*
    - `created_at` (string (date-time)) *(required)*
    - `updated_at` (string (date-time)) *(required)*

**Example Response:**

```json
{
  "permissions": [
    {
      "id": "string",
      "connected_account_id": "string",
      "tool_slug": "string",
      "toolkit_slug": "string",
      "risk_group": "read",
      "state": "always_allow",
      "source": "initial_connect",
      "permission_config_version": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ]
}
```

#### 400 - Bad request.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 401 - Unauthorized.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 403 - Forbidden.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 404 - Connected account not found.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 500 - Internal server error.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

### Example cURL Request

```bash
curl -X PATCH "https://backend.composio.dev/api/v3.1/consumer/connected_accounts/string/permissions" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": [
      {
        "tool_slug": "string",
        "toolkit_slug": "string",
        "risk_group": "read",
        "state": "always_allow",
        "source": "settings",
        "permission_config_version": "string"
      }
    ]
  }'
```