# Resolve consumer tool-router permissions

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

Resolves durable connected-account tool permissions into the landed tool-router experimental.permissions config so consumer flows can pass it directly when creating a tool-router session. In addition to existing auth methods, server-side callers may use admin auth with org_member_id/project_id/org_id query params to derive the project user context.

---

## POST `/api/v3.1/consumer/permissions/resolve`

**Endpoint:** `https://backend.composio.dev/api/v3.1/consumer/permissions/resolve`

**Summary:** Resolve consumer tool-router permissions

Resolves durable connected-account tool permissions into the landed tool-router experimental.permissions config so consumer flows can pass it directly when creating a tool-router session. In addition to existing auth methods, server-side callers may use admin auth with org_member_id/project_id/org_id query params to derive the project user context.

### Authentication

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

### Query Parameters

- `org_member_id` (string (uuid)): Org member/user UUID used with admin auth.
- `project_id` (string (projectId)): Project nano ID used with admin auth.
- `org_id` (string (orgId)): Org nano ID used with admin auth.

### Request Body

**Schema:**

- `connected_account_ids` (array<string (connectedAccountId)>): Connected account nano IDs to include in resolution.
- `connected_accounts` (object): Optional toolkit_slug -> connected account nano ID array map. Values are flattened and merged with connected_account_ids.
  - `[key: string]` (array<string (connectedAccountId)>)
- `default` (enum: "allow_all" | "ask_every_call" | "ask_once_per_session"): Optional default mode to include in the resolved tool-router permissions config.

**Example:**

```json
{
  "connected_account_ids": [
    "string"
  ],
  "connected_accounts": {
    "key": [
      "string"
    ]
  },
  "default": "allow_all"
}
```

### Responses

#### 200 - Consumer permissions resolved successfully.

**Response Schema:**

- `experimental` (object) *(required)*
  - `permissions` (object) *(required)*
    - `default` (enum: "allow_all" | "ask_every_call" | "ask_once_per_session") *(required)*: Default elicitation behavior when no override matches. `allow_all` runs every tool without prompting; `ask_every_call` prompts on each invocation; `ask_once_per_session` prompts once and remembers the answer for the rest of the session.
    - `overrides` (object): Per-tool overrides keyed by `${toolSlug}:${connectedAccountId ?? "__none__"}`, plus account-wide overrides keyed by `*:${connectedAccountId ?? "__none__"}`. Exact tool overrides take precedence over account-wide overrides. `always_allow` skips the prompt and runs the tool; `always_deny` blocks the tool; `ask_once` prompts once per session (allow/deny) and remembers; `ask_always` prompts on every call with allow-once/allow-session/deny, ignoring any cached session allow. Overrides take precedence over `default`.
      - `[key: string]` (enum: "always_allow" | "always_deny" | "ask_once" | ...)

**Example Response:**

```json
{
  "experimental": {
    "permissions": {
      "default": "allow_all",
      "overrides": {
        "key": "..."
      }
    }
  }
}
```

#### 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 POST "https://backend.composio.dev/api/v3.1/consumer/permissions/resolve" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "connected_account_ids": [
      "string"
    ],
    "connected_accounts": {
      "key": [
        "string"
      ]
    },
    "default": "allow_all"
  }'
```