# Advisory Firms — DayZero API

> Advisory firm management for multi-tenant accounting.

38 endpoints. OpenAPI for just this tag: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json · HTML: https://www.ondayzero.com/docs/reference/advisory-firms · All tags: https://www.ondayzero.com/docs/reference/index.md

## Endpoints

- `GET /api/v1/advisory-firms` — List advisory firms
- `POST /api/v1/advisory-firms` — Create advisory firm
- `DELETE /api/v1/advisory-firms/{firm_id}` — Delete advisory firm
- `GET /api/v1/advisory-firms/{firm_id}` — Get advisory firm
- `PUT /api/v1/advisory-firms/{firm_id}` — Update advisory firm
- `POST /api/v1/advisory-firms/{firm_id}/ai-insights` — AI cross-client insights
- `GET /api/v1/advisory-firms/{firm_id}/businesses` — List firm businesses
- `POST /api/v1/advisory-firms/{firm_id}/businesses` — Assign business to firm
- `PATCH /api/v1/advisory-firms/{firm_id}/businesses/accounting-basis` — Bulk-set client accounting basis
- `DELETE /api/v1/advisory-firms/{firm_id}/businesses/{business_id}` — Unassign business from firm
- `POST /api/v1/advisory-firms/{firm_id}/businesses/{business_id}/invite-client` — Invite a client user to a business
- `GET /api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics` — Get a business notification topic policy
- `PUT /api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics` — Update a business notification topic policy
- `GET /api/v1/advisory-firms/{firm_id}/clients` — List firm clients
- `GET /api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses` — List client business access
- `POST /api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses` — Grant client business access
- `DELETE /api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses/{business_id}` — Revoke client business access
- `GET /api/v1/advisory-firms/{firm_id}/invitations` — List pending invitations
- `DELETE /api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}` — Cancel an invitation
- `POST /api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}/resend` — Resend an invitation
- `GET /api/v1/advisory-firms/{firm_id}/logo` — Get firm logo download URL
- `GET /api/v1/advisory-firms/{firm_id}/preferences/notifications/topics` — Get firm notification topic policy
- `PUT /api/v1/advisory-firms/{firm_id}/preferences/notifications/topics` — Update firm notification topic policy
- `PUT /api/v1/advisory-firms/{firm_id}/slack` — Save firm Slack webhook
- `GET /api/v1/advisory-firms/{firm_id}/slack/status` — Get firm Slack status
- `POST /api/v1/advisory-firms/{firm_id}/slack/test` — Test Slack webhook
- `DELETE /api/v1/advisory-firms/{firm_id}/slack/{webhook_id}` — Disconnect Slack
- `PUT /api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/preferences` — Update firm Slack notification preferences
- `POST /api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/test` — Test Slack webhook
- `PUT /api/v1/advisory-firms/{firm_id}/stripe-customer` — Link Stripe customer
- `GET /api/v1/advisory-firms/{firm_id}/users` — List firm users
- `POST /api/v1/advisory-firms/{firm_id}/users` — Add user to firm
- `POST /api/v1/advisory-firms/{firm_id}/users/invite` — Invite a staff member to the firm
- `DELETE /api/v1/advisory-firms/{firm_id}/users/{user_id}` — Remove user from firm
- `PATCH /api/v1/advisory-firms/{firm_id}/users/{user_id}/api-access` — Set firm user API access
- `GET /api/v1/advisory-firms/{firm_id}/users/{user_id}/menu` — Get a firm staff member's sidebar menu
- `PUT /api/v1/advisory-firms/{firm_id}/users/{user_id}/menu` — Set a firm staff member's sidebar menu
- `PUT /api/v1/advisory-firms/{firm_id}/users/{user_id}/role` — Update user role in firm

---

## GET /api/v1/advisory-firms

> List advisory firms

- **Tag:** advisory-firms
- **Operation ID:** `list_advisory_firms`

### Description

List advisory firms for a user. Defaults to the authenticated user; pass `user_id` to filter by a different user.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `user_id` (query, string, optional) — Filter firms by this user's memberships
- `cursor` (query, string, optional) — Cursor for pagination
- `limit` (query, integer, optional) — Pagination limit
- `direction` (query, string, optional) — Pagination direction: 'next' or 'prev'
- `include_total_count` (query, boolean, optional) — Whether to include total count (expensive - avoid if possible)
- `sort_by` (query, string, optional) — Column name to sort by (e.g. 'created_at', 'amount', 'name'). When changing sort, reset cursor to None.
- `descending` (query, boolean, optional) — Sort direction: true for descending (newest/largest first), false for ascending

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_AdvisoryFirmListResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (AdvisoryFirmListResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/list-advisory-firms
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/list-advisory-firms/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms

> Create advisory firm

- **Tag:** advisory-firms
- **Operation ID:** `create_advisory_firm`

### Description

Create a new advisory firm. Operators only: sign-up links and checkout are how firms come to exist otherwise.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Request body

Schema: `AdvisoryFirmCreateRequest`

- `name` (string · required) — Firm name.
- `address` (string) — Firm business address.
- `ein` (string) — Tax Employer Identification Number.
- `logo_url` (string) — URL or S3 key for the firm logo.
- `stripe_customer_id` (string) — Stripe customer ID for subscription billing.
- `client_messaging_enabled` (boolean) — Whether clients can use the messaging portal.
- `ap_automation_enabled` (boolean) — Whether clients see the AP automation bills page in the client portal.
- `client_visible_integrations` (array · string) — Integration IDs visible to clients in the client portal.
- `client_ai_assistant_enabled` (boolean) — Whether clients can use the read-only AI assistant in the client portal.
- `client_digest_email_enabled` (boolean) — Whether clients receive the proactive financial digest email.
- `client_digest_frequency` (string) (one of: weekly, monthly) — Cadence of the client digest email: 'weekly' or 'monthly'.
- `mfa_enforced` (boolean) — When true, firm owners/admins must use Clerk MFA for sensitive actions.

### Example request

```json
{
  "address": "100 Financial District, Suite 500, San Francisco, CA 94105",
  "ein": "12-3456789",
  "name": "Smith & Associates CPA"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_AdvisoryFirmResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (AdvisoryFirmResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 409 — Conflict - Resource already exists or is in an incompatible state

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "address": "100 Financial District, Suite 500, San Francisco, CA 94105",
  "ein": "12-3456789",
  "name": "Smith & Associates CPA"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "address": "100 Financial District, Suite 500, San Francisco, CA 94105",
  "ein": "12-3456789",
  "name": "Smith & Associates CPA"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'address': '100 Financial District, Suite 500, San Francisco, CA '
            '94105',
 'ein': '12-3456789',
 'name': 'Smith & Associates CPA'}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/create-advisory-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/create-advisory-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## DELETE /api/v1/advisory-firms/{firm_id}

> Delete advisory firm

- **Tag:** advisory-firms
- **Operation ID:** `delete_firm`

### Description

Delete an advisory firm and all associations. Requires a JSON body with 'confirm_password' — the caller's own account password.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `AdvisoryFirmDeleteRequest`

- `confirm_password` (string · password) — Deprecated and ignored. Retained so clients sending the old body keep working during rollout. Step-up is now proven by Clerk re-verification (an emailed code, or the account's own factor), which works for SSO accounts that have no password.

### Responses

#### 200 — Successful Response

Schema: `app__core__success__MessageResponse`

- `success` (boolean)
- `message` (string)
- `code` (string)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X DELETE 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "confirm_password": "string"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "confirm_password": "string"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'confirm_password': 'string'}

response = httpx.delete("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/delete-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/delete-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}

> Get advisory firm

- **Tag:** advisory-firms
- **Operation ID:** `get_firm`

### Description

Get details of a specific advisory firm.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_AdvisoryFirmResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (AdvisoryFirmResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}

> Update advisory firm

- **Tag:** advisory-firms
- **Operation ID:** `update_firm`

### Description

Update advisory firm details.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `AdvisoryFirmUpdateRequest`

- `name` (string)
- `address` (string)
- `ein` (string)
- `logo_url` (string)
- `stripe_customer_id` (string)
- `client_messaging_enabled` (boolean)
- `ap_automation_enabled` (boolean)
- `client_ai_assistant_enabled` (boolean)
- `client_digest_email_enabled` (boolean)
- `client_digest_frequency` (string)
- `slack_webhook_url` (string) — Slack Incoming Webhook URL. Set to empty string to disconnect.
- `client_visible_integrations` (array · string) — Integration IDs visible to clients. Valid values: stripe, plaid, ramp, square, shopify, slack.
- `mfa_enforced` (boolean) — Require Clerk MFA for firm owners/admins on sensitive actions.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_AdvisoryFirmResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (AdvisoryFirmResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "address": "string",
  "ein": "string",
  "logo_url": "string",
  "stripe_customer_id": "string",
  "client_messaging_enabled": false
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "name": "string",
  "address": "string",
  "ein": "string",
  "logo_url": "string",
  "stripe_customer_id": "string",
  "client_messaging_enabled": false
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'name': 'string',
 'address': 'string',
 'ein': 'string',
 'logo_url': 'string',
 'stripe_customer_id': 'string',
 'client_messaging_enabled': False}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/update-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/update-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/ai-insights

> AI cross-client insights

- **Tag:** advisory-firms
- **Operation ID:** `get_firm_ai_insights`

### Description

Get AI-powered cross-client insights for an advisory firm.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_GetFirmAIInsightsResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (GetFirmAIInsightsResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/ai-insights' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/ai-insights', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/ai-insights", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-ai-insights
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-ai-insights/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/businesses

> List firm businesses

- **Tag:** advisory-firms
- **Operation ID:** `list_firm_businesses`

### Description

List all businesses assigned to an advisory firm.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `cursor` (query, string, optional) — Cursor for pagination
- `limit` (query, integer, optional) — Pagination limit
- `direction` (query, string, optional) — Pagination direction: 'next' or 'prev'
- `include_total_count` (query, boolean, optional) — Whether to include total count (expensive - avoid if possible)
- `sort_by` (query, string, optional) — Column name to sort by (e.g. 'created_at', 'amount', 'name'). When changing sort, reset cursor to None.
- `descending` (query, boolean, optional) — Sort direction: true for descending (newest/largest first), false for ascending

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_FirmBusinessesCursorResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (FirmBusinessesCursorResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-businesses
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-businesses/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/businesses

> Assign business to firm

- **Tag:** advisory-firms
- **Operation ID:** `assign_business_to_firm`

### Description

Assign a business to an advisory firm.

The caller must administer both the firm (owner/admin) **and** the
business being linked. The business-side check prevents a firm admin from
attaching an arbitrary business by ID and inheriting cross-tenant access
to its data (IDOR).

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `BusinessFirmAssociationCreateRequest`

- `business_id` (string · required)
- `notes` (string)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BusinessFirmAssociationResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (BusinessFirmAssociationResponse)

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "business_id": "string"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "business_id": "string"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'business_id': 'string'}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/assign-business-to-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/assign-business-to-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PATCH /api/v1/advisory-firms/{firm_id}/businesses/accounting-basis

> Bulk-set client accounting basis

- **Tag:** advisory-firms
- **Operation ID:** `set_firm_businesses_accounting_basis`

### Description

Set the default accounting basis (cash or accrual) that financial reports open on for several of the firm's client businesses at once. Every id must be an active client of the firm; otherwise the whole batch is rejected and nothing is changed. Firm owners/admins only.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `FirmBusinessAccountingBasisRequest`

- `business_ids` (array · string · required) — Client business IDs to update. Every id must be an active client of the firm.
- `accounting_basis` (string · required) (one of: cash, accrual) — Default basis financial reports open on for the selected businesses: 'accrual' or 'cash'.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_FirmBusinessAccountingBasisResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (FirmBusinessAccountingBasisResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PATCH 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/accounting-basis' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "business_ids": [],
  "accounting_basis": "cash"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/accounting-basis', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "business_ids": [],
  "accounting_basis": "cash"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'business_ids': [], 'accounting_basis': 'cash'}

response = httpx.patch("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/accounting-basis", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/set-firm-businesses-accounting-basis
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/set-firm-businesses-accounting-basis/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## DELETE /api/v1/advisory-firms/{firm_id}/businesses/{business_id}

> Unassign business from firm

- **Tag:** advisory-firms
- **Operation ID:** `unassign_business_from_firm`

### Description

Unassign a business from an advisory firm.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `business_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `app__core__success__MessageResponse`

- `success` (boolean)
- `message` (string)
- `code` (string)

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X DELETE 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.delete("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/unassign-business-from-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/unassign-business-from-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/businesses/{business_id}/invite-client

> Invite a client user to a business

- **Tag:** advisory-firms
- **Operation ID:** `invite_client_to_business`

### Description

Invite a user by email to access a client business. If the user already exists they are added immediately; otherwise an invitation email is sent and they are added on signup.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `business_id` (path, string, required)

### Request body

Schema: `InviteClientRequest`

- `email` (string · required) — Email address of the client to invite.
- `first_name` (string) — Optional first name to personalize the invitation.
- `last_name` (string) — Optional last name to personalize the invitation.
- `message` (string) — Optional personal message from the inviter included in the email.

### Example request

```json
{
  "email": "client@example.com"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_InviteClientResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (InviteClientResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 409 — Conflict - Resource already exists or is in an incompatible state

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/invite-client' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "client@example.com"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/invite-client', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "email": "client@example.com"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'email': 'client@example.com'}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/invite-client", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/invite-client-to-business
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/invite-client-to-business/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics

> Get a business notification topic policy

- **Tag:** advisory-firms
- **Operation ID:** `get_business_notification_topic_policy`

### Description

Per-topic channel toggles applied to a client business's users.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `business_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_TopicChannelOverridesResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (TopicChannelOverridesResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/get-business-notification-topic-policy
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/get-business-notification-topic-policy/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics

> Update a business notification topic policy

- **Tag:** advisory-firms
- **Operation ID:** `update_business_notification_topic_policy`

### Description

Replace the per-topic channel policy for a client business.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `business_id` (path, string, required)

### Request body

Schema: `TopicChannelOverridesUpdate`

- `overrides` (object)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_TopicChannelOverridesResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (TopicChannelOverridesResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "overrides": {}
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "overrides": {}
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'overrides': {}}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/businesses/{business_id}/preferences/notifications/topics", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/update-business-notification-topic-policy
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/update-business-notification-topic-policy/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/clients

> List firm clients

- **Tag:** advisory-firms
- **Operation ID:** `list_firm_clients`

### Description

List all users with the 'client' role in this firm, with their assigned businesses.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `search` (query, string, optional) — Search by client name or email

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_FirmClientsListResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (FirmClientsListResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-clients
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-clients/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses

> List client business access

- **Tag:** advisory-firms
- **Operation ID:** `list_client_business_access`

### Description

List which businesses a specific client can access.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_ListClientBusinessAccessResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (ListClientBusinessAccessResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/list-client-business-access
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/list-client-business-access/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses

> Grant client business access

- **Tag:** advisory-firms
- **Operation ID:** `grant_client_business_access`

### Description

Grant a client user access to a specific business within the firm.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)

### Request body

Schema: `ClientBusinessAccessRequest`

- `business_id` (string · required) — Business ID to grant access to.

### Example request

```json
{
  "business_id": "019ab37c-b051-7000-8000-000000000001"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_ClientBusinessAccessResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (ClientBusinessAccessResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 409 — Conflict - Resource already exists or is in an incompatible state

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "business_id": "019ab37c-b051-7000-8000-000000000001"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "business_id": "019ab37c-b051-7000-8000-000000000001"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'business_id': '019ab37c-b051-7000-8000-000000000001'}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/grant-client-business-access
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/grant-client-business-access/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## DELETE /api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses/{business_id}

> Revoke client business access

- **Tag:** advisory-firms
- **Operation ID:** `revoke_client_business_access`

### Description

Revoke a client's access to a specific business.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)
- `business_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `app__core__success__MessageResponse`

- `success` (boolean)
- `message` (string)
- `code` (string)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X DELETE 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses/{business_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses/{business_id}', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.delete("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/clients/{user_id}/businesses/{business_id}", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/revoke-client-business-access
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/revoke-client-business-access/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/invitations

> List pending invitations

- **Tag:** advisory-firms
- **Operation ID:** `list_firm_invitations`

### Description

List all invitations for a firm, optionally filtered by type (client, staff, or all) and status.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `type` (query, string, optional) — Filter by invitation type
- `status` (query, string, optional) — Filter by status (e.g. pending)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_InvitationListResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (InvitationListResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-invitations
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-invitations/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## DELETE /api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}

> Cancel an invitation

- **Tag:** advisory-firms
- **Operation ID:** `cancel_invitation`

### Description

Cancel a pending invitation. Cannot undo.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `invitation_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `app__core__success__MessageResponse`

- `success` (boolean)
- `message` (string)
- `code` (string)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X DELETE 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.delete("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/cancel-invitation
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/cancel-invitation/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}/resend

> Resend an invitation

- **Tag:** advisory-firms
- **Operation ID:** `resend_invitation`

### Description

Resend the invitation email and reset the expiry to 7 days from now. Only works on pending invitations.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `invitation_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_ResendInvitationResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (ResendInvitationResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}/resend' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}/resend', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/invitations/{invitation_id}/resend", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/resend-invitation
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/resend-invitation/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/logo

> Get firm logo download URL

- **Tag:** advisory-firms
- **Operation ID:** `get_firm_logo`

### Description

Generate a short-lived presigned download URL for the firm logo.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_GetFirmLogoResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (GetFirmLogoResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/logo' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/logo', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/logo", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-logo
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-logo/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/preferences/notifications/topics

> Get firm notification topic policy

- **Tag:** advisory-firms
- **Operation ID:** `get_firm_notification_topic_policy`

### Description

Per-topic channel toggles applied firm-wide to firm staff.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_TopicChannelOverridesResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (TopicChannelOverridesResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/preferences/notifications/topics' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/preferences/notifications/topics', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/preferences/notifications/topics", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-notification-topic-policy
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-notification-topic-policy/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}/preferences/notifications/topics

> Update firm notification topic policy

- **Tag:** advisory-firms
- **Operation ID:** `update_firm_notification_topic_policy`

### Description

Replace the firm-wide per-topic channel policy.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `TopicChannelOverridesUpdate`

- `overrides` (object)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_TopicChannelOverridesResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (TopicChannelOverridesResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/preferences/notifications/topics' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "overrides": {}
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/preferences/notifications/topics', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "overrides": {}
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'overrides': {}}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/preferences/notifications/topics", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/update-firm-notification-topic-policy
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/update-firm-notification-topic-policy/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}/slack

> Save firm Slack webhook

- **Tag:** advisory-firms
- **Operation ID:** `save_firm_slack_webhook`

### Description

Configure a Slack Incoming Webhook URL for the advisory firm.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `SlackWebhookSaveRequest`

- `slack_webhook_url` (string) — Slack Incoming Webhook URL, or empty/null to disconnect
- `channel_name` (string) — Optional name for the channel or webhook
- `preferences` (object) — Optional per-category enabled flags for the new webhook. Omitted categories default to enabled.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_SlackIntegrationStatus_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (SlackIntegrationStatus)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "slack_webhook_url": "string",
  "channel_name": "string",
  "preferences": {}
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "slack_webhook_url": "string",
  "channel_name": "string",
  "preferences": {}
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'slack_webhook_url': 'string',
 'channel_name': 'string',
 'preferences': {}}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/save-firm-slack-webhook
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/save-firm-slack-webhook/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/slack/status

> Get firm Slack status

- **Tag:** advisory-firms
- **Operation ID:** `get_firm_slack_status`

### Description

Check whether a Slack webhook is configured and get notification preferences.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_SlackIntegrationStatus_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (SlackIntegrationStatus)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/status' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/status', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/status", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-slack-status
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-slack-status/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/slack/test

> Test Slack webhook

- **Tag:** advisory-firms
- **Operation ID:** `test_firm_slack_webhook_legacy`

### Description

Send a test message to the firm's first configured Slack webhook (legacy).

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_SlackTestSendResult_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (SlackTestSendResult)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/test' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/test', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/test", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/test-firm-slack-webhook-legacy
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/test-firm-slack-webhook-legacy/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## DELETE /api/v1/advisory-firms/{firm_id}/slack/{webhook_id}

> Disconnect Slack

- **Tag:** advisory-firms
- **Operation ID:** `disconnect_firm_slack`

### Description

Remove the firm's Slack webhook URL and notification preferences.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `webhook_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_SlackDisconnectResult_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (SlackDisconnectResult)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X DELETE 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.delete("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/disconnect-firm-slack
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/disconnect-firm-slack/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/preferences

> Update firm Slack notification preferences

- **Tag:** advisory-firms
- **Operation ID:** `update_firm_slack_preferences`

### Description

Toggle which notification categories are sent to the firm's Slack.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `webhook_id` (path, string, required)

### Request body

Schema: `SlackPreferencesUpdateRequest`

- `preferences` (object · required) — Map of category key to enabled flag, e.g. {'workflow_completions': false}. Unknown keys are silently ignored.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_SlackIntegrationStatus_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (SlackIntegrationStatus)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/preferences' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "preferences": {}
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/preferences', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "preferences": {}
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'preferences': {}}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/preferences", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/update-firm-slack-preferences
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/update-firm-slack-preferences/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/test

> Test Slack webhook

- **Tag:** advisory-firms
- **Operation ID:** `test_firm_slack_webhook`

### Description

Send a test message to the firm's configured Slack webhook.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `webhook_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_SlackTestSendResult_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (SlackTestSendResult)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/test' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/test', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/slack/{webhook_id}/test", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/test-firm-slack-webhook
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/test-firm-slack-webhook/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}/stripe-customer

> Link Stripe customer

- **Tag:** advisory-firms
- **Operation ID:** `update_stripe_customer`

### Description

Link an advisory firm to a Stripe customer for billing.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `UpdateStripeCustomerRequest`

- `stripe_customer_id` (string · required) — Stripe customer ID (e.g., cus_xxx)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_UpdateStripeCustomerResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (UpdateStripeCustomerResponse)

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/stripe-customer' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "stripe_customer_id": "string"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/stripe-customer', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "stripe_customer_id": "string"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'stripe_customer_id': 'string'}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/stripe-customer", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/update-stripe-customer
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/update-stripe-customer/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/users

> List firm users

- **Tag:** advisory-firms
- **Operation ID:** `list_firm_users`

### Description

List all users in an advisory firm.

DayZero superusers on the roster are only listed to another superuser;
regular firm staff never see them (see ``app.utils.hidden_members``).

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_FirmUsersListResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (FirmUsersListResponse)

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-users
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/list-firm-users/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/users

> Add user to firm

- **Tag:** advisory-firms
- **Operation ID:** `add_user_to_firm`

### Description

Add a user to an advisory firm by user_id or email.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `UserFirmAssociationCreateRequest`

- `user_id` (string) — User UUID. Supply either user_id or email.
- `email` (string) — User email. When provided without user_id, the backend resolves it.
- `role` (string) (one of: owner, admin, member, client) — User's role in the firm. `owner`: Full access + billing + user management. `admin`: Full access + user management (no billing). `member`: Access to assigned businesses only.

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_UserFirmAssociationResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (UserFirmAssociationResponse)

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "user_id": "string",
  "email": "string",
  "role": "owner"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "user_id": "string",
  "email": "string",
  "role": "owner"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'user_id': 'string', 'email': 'string', 'role': 'owner'}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/add-user-to-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/add-user-to-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/advisory-firms/{firm_id}/users/invite

> Invite a staff member to the firm

- **Tag:** advisory-firms
- **Operation ID:** `invite_staff_to_firm`

### Description

Invite a user by email to join the firm as staff (admin or member). If the user already exists they are added immediately; otherwise an invitation email is sent and they are added on signup. Owner role cannot be assigned via invitation.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)

### Request body

Schema: `InviteStaffRequest`

- `email` (string · required) — Email address of the person to invite.
- `role` (string) (one of: admin, member) — Role to assign: 'admin' or 'member'. Owner cannot be invited.
- `first_name` (string) — Optional first name to personalize the invitation.
- `last_name` (string) — Optional last name to personalize the invitation.
- `message` (string) — Optional personal message from the inviter included in the email.
- `business_ids` (array · string) — For 'member' role: explicit list of businesses the invitee should be assigned to on acceptance. Ignored for 'admin' (admins see every firm business).
- `team_id` (string) — For 'member' role: team to add the invitee to on acceptance. Mutually exclusive with 'business_ids' and 'assign_all_firm_businesses'.
- `assign_all_firm_businesses` (boolean) — For 'member' role: if true, grant the invitee direct assignment to every currently active firm business on acceptance.

### Example request

```json
{
  "business_ids": [
    "b1111111-1111-1111-1111-111111111111"
  ],
  "email": "staff@example.com",
  "role": "member"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_InviteStaffResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (InviteStaffResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 409 — Conflict - Resource already exists or is in an incompatible state

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X POST 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/invite' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "business_ids": [
    "b1111111-1111-1111-1111-111111111111"
  ],
  "email": "staff@example.com",
  "role": "member"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/invite', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "business_ids": [
    "b1111111-1111-1111-1111-111111111111"
  ],
  "email": "staff@example.com",
  "role": "member"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'business_ids': ['b1111111-1111-1111-1111-111111111111'],
 'email': 'staff@example.com',
 'role': 'member'}

response = httpx.post("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/invite", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/invite-staff-to-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/invite-staff-to-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## DELETE /api/v1/advisory-firms/{firm_id}/users/{user_id}

> Remove user from firm

- **Tag:** advisory-firms
- **Operation ID:** `remove_user_from_firm`

### Description

Remove a user from an advisory firm.

Only firm owners (or superusers) may remove another owner, and the firm's
last owner can never be removed — transfer ownership first.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `app__core__success__MessageResponse`

- `success` (boolean)
- `message` (string)
- `code` (string)

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X DELETE 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.delete("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/remove-user-from-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/remove-user-from-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PATCH /api/v1/advisory-firms/{firm_id}/users/{user_id}/api-access

> Set firm user API access

- **Tag:** advisory-firms
- **Operation ID:** `set_firm_user_api_access`

### Description

Allow or block DayZero API access for a firm staff member. The firm-side switch is on by default and can only restrict: a member still needs DayZero to approve their API access request before they can create or use API tokens.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)

### Request body

Schema: `FirmUserApiAccessRequest`

- `api_access_enabled` (boolean · required) — Whether the user may use the DayZero API.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_FirmUserApiAccessResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (FirmUserApiAccessResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PATCH 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/api-access' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "api_access_enabled": false
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/api-access', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "api_access_enabled": false
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'api_access_enabled': False}

response = httpx.patch("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/api-access", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/set-firm-user-api-access
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/set-firm-user-api-access/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/advisory-firms/{firm_id}/users/{user_id}/menu

> Get a firm staff member's sidebar menu

- **Tag:** advisory-firms
- **Operation ID:** `get_firm_staff_menu`

### Description

The stored sidebar menus for a firm staff member: their firm-wide default plus any per-client overrides. Firm owners/admins can read any member's menu; a member can read their own. The menu that applies on a client resolves business-level first (a direct membership's menu, else the per-client override), then firm-wide, then all sections.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_FirmStaffMenuDetailResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (FirmStaffMenuDetailResponse)

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X GET 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/menu' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/menu', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
  },
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

response = httpx.get("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/menu", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-staff-menu
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/get-firm-staff-menu/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}/users/{user_id}/menu

> Set a firm staff member's sidebar menu

- **Tag:** advisory-firms
- **Operation ID:** `set_firm_staff_menu`

### Description

Restrict which app sections a firm staff member can reach, either firm-wide or for one client business. Firm staff reach clients *through the firm* and have no membership row there, so the per-membership menu could not be stored for them at all — this is where their menu lives instead. Unlike the per-membership menu, this one is enforced server-side: a request for a section outside the menu is rejected with 403, not merely hidden from the sidebar.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)

### Request body

Schema: `FirmStaffMenuRequest`

- `business_id` (string) — Client business to scope the menu to. Omit or null for the staff member's firm-wide default.
- `visible_sections` (array · string) — Sidebar section keys this staff member may reach. null clears the menu (all sections); an empty list grants none.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_FirmStaffMenuResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (FirmStaffMenuResponse)

#### 400 — Bad Request - Invalid input

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 401 — Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 403 — Forbidden - Insufficient permissions

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 404 — Not Found - Resource does not exist

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/menu' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "business_id": "string",
  "visible_sections": []
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/menu', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "business_id": "string",
  "visible_sections": []
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'business_id': 'string', 'visible_sections': []}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/menu", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/set-firm-staff-menu
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/set-firm-staff-menu/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PUT /api/v1/advisory-firms/{firm_id}/users/{user_id}/role

> Update user role in firm

- **Tag:** advisory-firms
- **Operation ID:** `update_user_role_in_firm`

### Description

Update a user's role in an advisory firm.

Only firm owners (or superusers) may grant the owner role or change an
existing owner's role, and the firm's last owner cannot be demoted.

### Authentication

Bearer token in `Authorization` header.
Required header: `x-business-id: <business uuid>`.

### Parameters

- `firm_id` (path, string, required)
- `user_id` (path, string, required)

### Request body

Schema: `UserRoleUpdateRequest`

- `role` (string · required) (one of: owner, admin, member, client) — New role for the user. `owner`: Full access + billing + user management. `admin`: Full access + user management (no billing). `member`: Access to assigned businesses only.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_UserFirmAssociationResponse_`

- `success` (boolean)
- `message` (string)
- `code` (string)
- `data` (UserFirmAssociationResponse)

#### 422 — Validation Error

Schema: `ErrorResponse`

- `error` (string · required) — Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`.
- `message` (string · required) — Human-readable explanation, safe to show to end users.
- `code` (string · required) — Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`).
- `request_id` (string) — Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied.
- `errors` (object) — Field-level validation messages keyed by field name. Present on 400/422 validation failures only.

### Code samples

#### cURL

```bash
curl -X PUT 'https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/role' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "role": "owner"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/role', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "role": "owner"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

headers = {
    "Authorization": "Bearer dz_your_token",
    "x-business-id": "YOUR_BUSINESS_ID",
}

payload = {'role': 'owner'}

response = httpx.put("https://api.ondayzero.com/api/v1/advisory-firms/{firm_id}/users/{user_id}/role", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/advisory-firms/update-user-role-in-firm
- OpenAPI slice: https://www.ondayzero.com/docs/reference/advisory-firms/update-user-role-in-firm/openapi.json
- Other endpoints in **advisory-firms**: https://www.ondayzero.com/docs/reference/advisory-firms (markdown bundle: https://www.ondayzero.com/docs/reference/advisory-firms.md, OpenAPI: https://www.ondayzero.com/docs/reference/advisory-firms/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md
