# Bills — DayZero API

> Accounts payable — create and manage vendor bills.

42 endpoints. OpenAPI for just this tag: https://www.ondayzero.com/docs/reference/bills/openapi.json · HTML: https://www.ondayzero.com/docs/reference/bills · All tags: https://www.ondayzero.com/docs/reference/index.md

## Endpoints

- `GET /api/v1/bills` — List bills
- `POST /api/v1/bills` — Create bill
- `GET /api/v1/bills/aging` — AP aging summary
- `POST /api/v1/bills/ai-create` — AI-extract draft bills from documents
- `POST /api/v1/bills/bulk` — Bulk create bills
- `GET /api/v1/bills/duplicate-check` — Check for possible duplicate bills
- `GET /api/v1/bills/expense-candidates` — List expense candidates
- `GET /api/v1/bills/metrics` — Get bill metrics
- `GET /api/v1/bills/payment-suggestions` — List bill payment suggestions
- `POST /api/v1/bills/payment-suggestions/bulk-approve` — Bulk approve bill payment suggestions
- `POST /api/v1/bills/payment-suggestions/trigger` — Trigger bill payment matching
- `POST /api/v1/bills/payment-suggestions/{suggestion_id}/accept` — Accept a bill payment suggestion
- `POST /api/v1/bills/payment-suggestions/{suggestion_id}/reject` — Reject a bill payment suggestion
- `POST /api/v1/bills/payments/batch` — Split one transaction across multiple bills
- `POST /api/v1/bills/received` — Create bill in received status
- `POST /api/v1/bills/suggest-payment-priority` — AI payment priority suggestions
- `GET /api/v1/bills/upcoming` — List upcoming (expected) bills
- `POST /api/v1/bills/upcoming` — Create an upcoming bill (optionally recurring)
- `DELETE /api/v1/bills/upcoming/{upcoming_bill_id}` — Delete an upcoming bill
- `GET /api/v1/bills/upcoming/{upcoming_bill_id}` — Get one upcoming bill
- `PATCH /api/v1/bills/upcoming/{upcoming_bill_id}` — Edit an upcoming bill
- `POST /api/v1/bills/upcoming/{upcoming_bill_id}/convert` — Push an upcoming bill into a real bill
- `POST /api/v1/bills/upcoming/{upcoming_bill_id}/link` — Match an upcoming bill to a bill that arrived
- `POST /api/v1/bills/upload` — Upload bill document
- `DELETE /api/v1/bills/{bill_id}` — Delete bill
- `GET /api/v1/bills/{bill_id}` — Get bill
- `PUT /api/v1/bills/{bill_id}` — Update bill
- `PATCH /api/v1/bills/{bill_id}/approval` — Approve bill
- `PATCH /api/v1/bills/{bill_id}/attachment` — Attach file to existing bill
- `PATCH /api/v1/bills/{bill_id}/cancellation` — Cancel bill
- `POST /api/v1/bills/{bill_id}/contract-comparison` — Compare bill against vendor contract
- `POST /api/v1/bills/{bill_id}/journal-entry` — Generate bill journal entry
- `POST /api/v1/bills/{bill_id}/journal-entry/link` — Attach journal entry to bill
- `PATCH /api/v1/bills/{bill_id}/payment-initiation` — Mark or clear bill payment-initiated
- `GET /api/v1/bills/{bill_id}/payments` — List bill payments
- `POST /api/v1/bills/{bill_id}/payments` — Add payment to bill
- `DELETE /api/v1/bills/{bill_id}/payments/{payment_id}` — Remove payment from bill
- `PATCH /api/v1/bills/{bill_id}/receipt` — Mark bill as received
- `POST /api/v1/bills/{bill_id}/resolve-approval` — Force-resolve a stuck pending-approval bill
- `POST /api/v1/bills/{bill_id}/revert-to-draft` — Revert bill to draft
- `POST /api/v1/bills/{bill_id}/submit-for-ap-approval` — Submit bill for AP approval
- `POST /api/v1/bills/{bill_id}/submit-for-approval` — Send bill for approval

---

## GET /api/v1/bills

> List bills

- **Tag:** bills
- **Operation ID:** `list_bills`

### Description

Retrieve all bills for a business with cursor-based pagination. Can filter by vendor name (fuzzy search) or associated journal entry.

### Authentication

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

### Parameters

- `id` (query, array · string, optional) — Filter bills by specific bill UUIDs (batch fetch — avoids N+1 single-bill requests)
- `vendor_search` (query, string, optional) — Fuzzy search bills by vendor name (uses PostgreSQL trigram matching)
- `journal_entry_id` (query, string, optional) — Filter bills by associated journal entry UUID
- `payment_method` (query, string, optional) — Filter bills by payment method: 'Wire Transfer', 'ACH', 'Check', 'Credit Card'
- `vendor_id` (query, string, optional) — Filter bills by vendor UUID
- `status` (query, string, optional) — Filter by bill status (e.g. draft, approved, received, paid, canceled)
- `search` (query, string, optional) — Search bills by bill number, description, or vendor name (case-insensitive partial match)
- `bill_number` (query, string, optional) — Filter bills by invoice/bill number (case-insensitive partial match)
- `due_date_from` (query, string, optional) — Filter bills with due date on or after this date (YYYY-MM-DD)
- `due_date_to` (query, string, optional) — Filter bills with due date on or before this date (YYYY-MM-DD)
- `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_BillsListResponse_`

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

#### 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/bills' \
  -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/bills', {
  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/bills", headers=headers)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills

> Create bill

- **Tag:** bills
- **Operation ID:** `create_bill`

### Description

Create a new bill in draft status. Optionally include 'recurring' config to also create a recurring template.

### Authentication

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

### Request body

Schema: `BillCreateRequest`

- `description` (string) — Description of what the bill is for.
- `currency` (string) — Currency for the bill (USD, CAD, AUD, EUR, or GBP). Defaults to business default.
- `vendor_id` (string) — UUID of the vendor this bill is from.
- `bill_number` (string) — Bill/invoice number from the vendor. Auto-generated if not provided.
- `type` (string) — Bill type: 'recurring' (monthly rent, subscriptions) or 'one_time'.
- `expected_amount` (integer) — Expected bill amount in cents.
- `expected_paid_on_date` (string · date-time | string) — Expected payment date (ISO 8601 format).
- `s3_key` (string) — S3 key of uploaded bill document (PDF/image).
- `recurring` (RecurringConfig) — If provided, creates a recurring template for this bill.
- `submitted_for_review` (boolean) — When true, marks this draft as a client-submitted expense and notifies the assigned advisor to confirm or deny it.

### Example request

```json
{
  "description": "Monthly office rent - January 2024",
  "expected_amount": 250000,
  "expected_paid_on_date": "2024-01-31T00:00:00Z",
  "type": "recurring",
  "vendor_id": "019ab37c-ae0d-7000-8000-000000000001"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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.

#### 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/bills' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "description": "Monthly office rent - January 2024",
  "expected_amount": 250000,
  "expected_paid_on_date": "2024-01-31T00:00:00Z",
  "type": "recurring",
  "vendor_id": "019ab37c-ae0d-7000-8000-000000000001"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "description": "Monthly office rent - January 2024",
  "expected_amount": 250000,
  "expected_paid_on_date": "2024-01-31T00:00:00Z",
  "type": "recurring",
  "vendor_id": "019ab37c-ae0d-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 = {'description': 'Monthly office rent - January 2024',
 'expected_amount': 250000,
 'expected_paid_on_date': '2024-01-31T00:00:00Z',
 'type': 'recurring',
 'vendor_id': '019ab37c-ae0d-7000-8000-000000000001'}

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

### See also

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

---

## GET /api/v1/bills/aging

> AP aging summary

- **Tag:** bills
- **Operation ID:** `get_bill_aging`

### Description

Returns accounts payable aging data grouped by vendor with Current, 1-30, 31-60, 61-90, and 91+ day buckets. Includes per-bill detail for drill-down.

### Authentication

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

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillAgingResponse_`

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

#### 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/bills/aging' \
  -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/bills/aging', {
  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/bills/aging", headers=headers)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/ai-create

> AI-extract draft bills from documents

- **Tag:** bills
- **Operation ID:** `ai_create_bill_payload`

### Description

Upload pasted text, PDFs, images, Excel files, or a CSV to extract draft bill entities using AI. Returns draft bills in 'received' status format ready for user review before creation.

### Authentication

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

### Request body

Schema: `BillAICreatePayloadRequest`

- `pasted_text` (string) — Raw text content to extract a bill from. Limit 1 bill per text input. Mutually exclusive with pasted_text_s3_key.
- `pasted_text_s3_key` (string) — S3 key of pasted text content. Limit 1 bill per text input. Mutually exclusive with pasted_text.
- `single_bill_s3_keys` (array · string) — S3 keys of individual bill documents (PDFs, images, Excel). Each file is processed independently.
- `multi_bill_s3_key` (string) — S3 key of a CSV file containing multiple bills.

### Example request

```json
{
  "single_bill_s3_keys": [
    "business-id/uuid-bill1.pdf",
    "business-id/uuid-bill2.png"
  ]
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillAICreatePayloadResponse_`

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

#### 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.

#### 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/bills/ai-create' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "single_bill_s3_keys": [
    "business-id/uuid-bill1.pdf",
    "business-id/uuid-bill2.png"
  ]
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/ai-create', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "single_bill_s3_keys": [
    "business-id/uuid-bill1.pdf",
    "business-id/uuid-bill2.png"
  ]
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'single_bill_s3_keys': ['business-id/uuid-bill1.pdf',
                         'business-id/uuid-bill2.png']}

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

### See also

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

---

## POST /api/v1/bills/bulk

> Bulk create bills

- **Tag:** bills
- **Operation ID:** `create_bulk_bills`

### Description

Create multiple bills from CSV data in a single request.

### Authentication

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

### Request body

Schema: `BillBulkRequest`

- `s3_key` (string) — S3 key of the uploaded CSV file containing bill data.
- `approve` (boolean) — If true, created bills are set to 'forecasted' status (approved). If false, bills remain as 'draft'.
- `create_as_received` (boolean) — If true, every row is created in 'received' status with an accounting journal entry. Each row must have a resolvable expense ledger (ledger_id, ledger_name, or expense_account column) and a valid amount. Overrides `approve` when set.
- `attachments` (object) — Optional mapping of source filename → pre-uploaded S3 key (from POST /bills/upload). Rows whose `attachment_filename` matches a key in this map have the corresponding document attached.

### Example request

```json
{
  "approve": false,
  "attachments": {
    "rent-jan.pdf": "attachments/019c30bb-dc4c-7e7e-8f9a-aaa",
    "supplies-feb.pdf": "attachments/019c30bb-dc4c-7e7e-8f9a-bbb"
  },
  "create_as_received": false,
  "s3_key": "uploads/bills/batch-2024-01.csv"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillsListResponse_`

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

#### 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.

#### 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/bills/bulk' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "approve": false,
  "attachments": {
    "rent-jan.pdf": "attachments/019c30bb-dc4c-7e7e-8f9a-aaa",
    "supplies-feb.pdf": "attachments/019c30bb-dc4c-7e7e-8f9a-bbb"
  },
  "create_as_received": false,
  "s3_key": "uploads/bills/batch-2024-01.csv"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/bulk', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "approve": false,
  "attachments": {
    "rent-jan.pdf": "attachments/019c30bb-dc4c-7e7e-8f9a-aaa",
    "supplies-feb.pdf": "attachments/019c30bb-dc4c-7e7e-8f9a-bbb"
  },
  "create_as_received": false,
  "s3_key": "uploads/bills/batch-2024-01.csv"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'approve': False,
 'attachments': {'rent-jan.pdf': 'attachments/019c30bb-dc4c-7e7e-8f9a-aaa',
                 'supplies-feb.pdf': 'attachments/019c30bb-dc4c-7e7e-8f9a-bbb'},
 'create_as_received': False,
 's3_key': 'uploads/bills/batch-2024-01.csv'}

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

### See also

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

---

## GET /api/v1/bills/duplicate-check

> Check for possible duplicate bills

- **Tag:** bills
- **Operation ID:** `check_duplicate_bills`

### Description

Advisory, read-only check used during bill entry. Returns existing bills that may duplicate the one being entered (same bill number, or same vendor and amount within ~90 days). Never blocks creation — it is purely a heads-up so the user can confirm before saving.

### Authentication

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

### Parameters

- `bill_number` (query, string, optional) — In-progress bill/invoice number to match (optional).
- `vendor_id` (query, string, optional) — In-progress vendor UUID to match (optional).
- `amount` (query, integer, optional) — In-progress amount in cents to match (optional).
- `received_on` (query, string · date, optional) — Invoice date (YYYY-MM-DD); bounds the vendor+amount lookback window.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_DuplicateBillCheckResponse_`

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

#### 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/bills/duplicate-check' \
  -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/bills/duplicate-check', {
  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/bills/duplicate-check", headers=headers)
data = response.json()
```

### See also

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

---

## GET /api/v1/bills/expense-candidates

> List expense candidates

- **Tag:** bills
- **Operation ID:** `list_expense_candidates`

### Description

Return outgoing transactions that may represent bill payments. Filters to posted expense transactions with unallocated balances, useful for the Record Payment modal on the bills page.

### Authentication

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

### Parameters

- `limit` (query, integer, optional) — Max results

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_ListExpenseCandidatesResponse_`

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

#### 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/bills/expense-candidates' \
  -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/bills/expense-candidates', {
  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/bills/expense-candidates", headers=headers)
data = response.json()
```

### See also

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

---

## GET /api/v1/bills/metrics

> Get bill metrics

- **Tag:** bills
- **Operation ID:** `get_bill_metrics`

### Description

Retrieve aggregated bill metrics for the business: total due and total balance due across all received and partially paid bills, plus the overdue balance across bills past their due date.

### Authentication

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

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillMetricsResponse_`

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

#### 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/bills/metrics' \
  -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/bills/metrics', {
  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/bills/metrics", headers=headers)
data = response.json()
```

### See also

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

---

## GET /api/v1/bills/payment-suggestions

> List bill payment suggestions

- **Tag:** bills
- **Operation ID:** `list_bill_payment_suggestions`

### Description

List auto-detected matches between bank transactions and open bills.

### Authentication

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

### Parameters

- `bill_id` (query, string, optional) — Filter by bill UUID
- `status` (query, string, optional) — Filter by status
- `min_confidence` (query, number, optional) — Minimum confidence threshold
- `start_date` (query, string · date, optional) — Only include suggestions whose transaction date is on or after this date (YYYY-MM-DD)
- `end_date` (query, string · date, optional) — Only include suggestions whose transaction date is on or before this date (YYYY-MM-DD)
- `limit` (query, integer, optional) — Max results

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillPaymentSuggestionsListResponse_`

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

#### 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/bills/payment-suggestions' \
  -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/bills/payment-suggestions', {
  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/bills/payment-suggestions", headers=headers)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/payment-suggestions/bulk-approve

> Bulk approve bill payment suggestions

- **Tag:** bills
- **Operation ID:** `bulk_approve_bill_suggestions`

### Description

Accept all pending suggestions above a confidence threshold.

### Authentication

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

### Request body

Schema: `BulkApproveSuggestionsRequest`

- `min_confidence` (number) — Only approve suggestions at or above this confidence

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BulkApproveSuggestionsResponse_`

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

#### 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 POST 'https://api.ondayzero.com/api/v1/bills/payment-suggestions/bulk-approve' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "min_confidence": 0
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/payment-suggestions/bulk-approve', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "min_confidence": 0
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'min_confidence': 0}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/payment-suggestions/bulk-approve", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/bulk-approve-bill-suggestions
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/bulk-approve-bill-suggestions/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/payment-suggestions/trigger

> Trigger bill payment matching

- **Tag:** bills
- **Operation ID:** `trigger_bill_payment_matching`

### Description

Run the AP matching engine to find bank transactions that match open bills.

### Authentication

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

### Request body

Schema: `TriggerBillMatchingRequest`

- `min_confidence` (number) — Minimum confidence threshold (0.0–1.0)
- `auto_match` (boolean) — If true, automatically accept high-confidence matches (>= 0.85)
- `bill_ids` (array · string) — Limit matching to specific bill UUIDs

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_TriggerBillMatchingResponse_`

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

#### 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 POST 'https://api.ondayzero.com/api/v1/bills/payment-suggestions/trigger' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "min_confidence": 0,
  "auto_match": false,
  "bill_ids": []
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/payment-suggestions/trigger', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "min_confidence": 0,
  "auto_match": false,
  "bill_ids": []
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'min_confidence': 0, 'auto_match': False, 'bill_ids': []}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/payment-suggestions/trigger", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/trigger-bill-payment-matching
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/trigger-bill-payment-matching/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/payment-suggestions/{suggestion_id}/accept

> Accept a bill payment suggestion

- **Tag:** bills
- **Operation ID:** `accept_bill_payment_suggestion`

### Description

Accept a suggestion and create the actual BillPayment.

### Authentication

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

### Parameters

- `suggestion_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillPaymentResponse_`

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

#### 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/bills/payment-suggestions/{suggestion_id}/accept' \
  -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/bills/payment-suggestions/{suggestion_id}/accept', {
  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/bills/payment-suggestions/{suggestion_id}/accept", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/accept-bill-payment-suggestion
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/accept-bill-payment-suggestion/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/payment-suggestions/{suggestion_id}/reject

> Reject a bill payment suggestion

- **Tag:** bills
- **Operation ID:** `reject_bill_payment_suggestion`

### Description

Reject a suggestion so it is no longer shown.

### Authentication

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

### Parameters

- `suggestion_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillPaymentSuggestionRejectResponse_`

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

#### 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/bills/payment-suggestions/{suggestion_id}/reject' \
  -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/bills/payment-suggestions/{suggestion_id}/reject', {
  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/bills/payment-suggestions/{suggestion_id}/reject", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/reject-bill-payment-suggestion
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/reject-bill-payment-suggestion/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/payments/batch

> Split one transaction across multiple bills

- **Tag:** bills
- **Operation ID:** `create_bill_payments_batch`

### Description

Apply a single bank transaction to multiple bills and/or direct expense lines in one atomic request. Validates the total allocation against the transaction's remaining unallocated balance before creating any payments.

### Authentication

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

### Request body

Schema: `BillBatchPaymentRequest`

- `transaction_id` (string · required) — UUID of the bank transaction representing the payment.
- `allocations` (array · BillBatchPaymentAllocation) → `BillBatchPaymentAllocation` — Bill slices (0+). Each `bill_id` must be unique.
  - `bill_id` (string · required) — UUID of the bill receiving this slice of the transaction.
  - `amount` (integer · required) — Amount in cents to allocate to this bill. Must be > 0.
- `expense_lines` (array · BillBatchExpenseLine) → `BillBatchExpenseLine` — Optional expense lines for any remaining balance. Each line debits an expense ledger on the transaction's journal entry.
  - `ledger_id` (string · required) — UUID of the expense ledger account to debit.
  - `amount` (integer · required) — Amount in cents to categorize as expense. Must be > 0.
  - `description` (string) — Optional memo stored on the journal-entry line.
- `paid_on` (string · date-time) — Override payment date applied to every allocation. Defaults to the transaction datetime if omitted.

### Example request

```json
{
  "allocations": [
    {
      "amount": 50000,
      "bill_id": "019ab37c-b111-7000-8000-000000000001"
    },
    {
      "amount": 75000,
      "bill_id": "019ab37c-b111-7000-8000-000000000002"
    }
  ],
  "transaction_id": "019ab37c-7801-7000-8000-000000000001"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillBatchPaymentResponse_`

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

#### 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/bills/payments/batch' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "allocations": [
    {
      "amount": 50000,
      "bill_id": "019ab37c-b111-7000-8000-000000000001"
    },
    {
      "amount": 75000,
      "bill_id": "019ab37c-b111-7000-8000-000000000002"
    }
  ],
  "transaction_id": "019ab37c-7801-7000-8000-000000000001"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/payments/batch', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "allocations": [
    {
      "amount": 50000,
      "bill_id": "019ab37c-b111-7000-8000-000000000001"
    },
    {
      "amount": 75000,
      "bill_id": "019ab37c-b111-7000-8000-000000000002"
    }
  ],
  "transaction_id": "019ab37c-7801-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 = {'allocations': [{'amount': 50000,
                  'bill_id': '019ab37c-b111-7000-8000-000000000001'},
                 {'amount': 75000,
                  'bill_id': '019ab37c-b111-7000-8000-000000000002'}],
 'transaction_id': '019ab37c-7801-7000-8000-000000000001'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/payments/batch", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/received

> Create bill in received status

- **Tag:** bills
- **Operation ID:** `create_bill_received`

### Description

Create a new bill directly in 'received' status, ready for payment. Creates both the bill AND journal entry when ledger_id is provided.

### Authentication

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

### Request body

Schema: `BillReceivedCreateRequest`

- `vendor_id` (string · required) — UUID of the vendor this bill is from (required).
- `amount` (integer · required) — Bill amount in cents (required).
- `description` (string) — Description of what the bill is for.
- `bill_number` (string) — Bill/invoice number from the vendor. Auto-generated if not provided.
- `currency` (string) — Currency for the bill (USD, CAD, AUD, EUR, or GBP). Defaults to business default.
- `type` (string) — Bill type: 'recurring' or 'one_time'. Defaults to 'one_time'.
- `received_on` (string · date-time | string) — Date the bill was received (ISO 8601). Defaults to now.
- `due_on` (string · date-time | string) — Payment due date (ISO 8601).
- `s3_key` (string) — S3 key of uploaded bill document (PDF/image).
- `ledger_id` (string) — UUID of the expense ledger for journal entry creation. If provided, creates journal entry automatically. Ignored when line_items is provided.
- `line_items` (array · JournalEntryLineItem) — Split journal entry lines. Each line specifies a debit account and amount. The credit side is always Accounts Payable. When provided, ledger_id is ignored.
- `journal_entry_date` (string · date-time | string · date | string) — Date for the accounting journal entry (ISO 8601 or YYYY-MM-DD). Defaults to received_on if not provided.

### Example request

```json
{
  "amount": 56135,
  "bill_number": "P054",
  "currency": "USD",
  "description": "Purchase Order (P054) issued by Artisan AI LLC",
  "due_on": "2025-03-29T12:00:00Z",
  "journal_entry_date": "2025-02-27T12:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2025-02-27T12:00:00Z",
  "s3_key": "attachments/019c30bb-dc4c-7e7e-8f9a-123456789abc",
  "type": "one_time",
  "vendor_id": "019ab37c-ae0d-7000-8000-000000000001"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/received' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 56135,
  "bill_number": "P054",
  "currency": "USD",
  "description": "Purchase Order (P054) issued by Artisan AI LLC",
  "due_on": "2025-03-29T12:00:00Z",
  "journal_entry_date": "2025-02-27T12:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2025-02-27T12:00:00Z",
  "s3_key": "attachments/019c30bb-dc4c-7e7e-8f9a-123456789abc",
  "type": "one_time",
  "vendor_id": "019ab37c-ae0d-7000-8000-000000000001"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/received', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "amount": 56135,
  "bill_number": "P054",
  "currency": "USD",
  "description": "Purchase Order (P054) issued by Artisan AI LLC",
  "due_on": "2025-03-29T12:00:00Z",
  "journal_entry_date": "2025-02-27T12:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2025-02-27T12:00:00Z",
  "s3_key": "attachments/019c30bb-dc4c-7e7e-8f9a-123456789abc",
  "type": "one_time",
  "vendor_id": "019ab37c-ae0d-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 = {'amount': 56135,
 'bill_number': 'P054',
 'currency': 'USD',
 'description': 'Purchase Order (P054) issued by Artisan AI LLC',
 'due_on': '2025-03-29T12:00:00Z',
 'journal_entry_date': '2025-02-27T12:00:00Z',
 'ledger_id': '019ab37c-1ed1-7000-8000-000000000001',
 'received_on': '2025-02-27T12:00:00Z',
 's3_key': 'attachments/019c30bb-dc4c-7e7e-8f9a-123456789abc',
 'type': 'one_time',
 'vendor_id': '019ab37c-ae0d-7000-8000-000000000001'}

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

### See also

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

---

## POST /api/v1/bills/suggest-payment-priority

> AI payment priority suggestions

- **Tag:** bills
- **Operation ID:** `suggest_payment_priority`

### Description

Get AI-powered bill payment priority recommendations.

### Authentication

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

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_SuggestPaymentPriorityResponse_`

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

#### 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 POST 'https://api.ondayzero.com/api/v1/bills/suggest-payment-priority' \
  -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/bills/suggest-payment-priority', {
  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/bills/suggest-payment-priority", headers=headers)
data = response.json()
```

### See also

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

---

## GET /api/v1/bills/upcoming

> List upcoming (expected) bills

- **Tag:** bills
- **Operation ID:** `list_upcoming_bills`

### Description

Forecast rows for bills the business expects — recurring contractor payments, retainers. These are estimates: they carry no journal entries and are excluded from AP totals, aged payables and the balance sheet.

### Authentication

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

### Parameters

- `status` (query, string, optional) — Filter by status: expected, converted, dismissed.
- `vendor_id` (query, string, optional) — Filter by vendor.
- `date_from` (query, string · date, optional) — Only occurrences expected on or after this date.
- `date_to` (query, string · date, optional) — Only occurrences expected on or before this date.
- `limit` (query, integer, optional) — Maximum rows to return.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_UpcomingBillListResponse_`

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

#### 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/bills/upcoming' \
  -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/bills/upcoming', {
  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/bills/upcoming", headers=headers)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/upcoming

> Create an upcoming bill (optionally recurring)

- **Tag:** bills
- **Operation ID:** `create_upcoming_bill`

### Description

Create one expected bill, or a recurring series. A recurring request materialises every projected occurrence up front (capped by `recurrence.occurrences`), so each one can be edited, deleted or matched independently. Returns every occurrence created.

### Authentication

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

### Request body

Schema: `UpcomingBillCreateRequest`

- `vendor_id` (string) — Vendor this is expected from, when one exists.
- `vendor_name` (string) — Payee name when there is no vendor record yet.
- `description` (string) — What the bill is for.
- `estimated_amount` (integer · required) — Estimated amount in cents. An estimate, not a payable.
- `expected_date` (string · date · required) — When the bill is expected (first occurrence for a series).
- `notes` (string) — Free-form notes.
- `recurrence` (UpcomingBillRecurrence) — Omit for a single expected bill.

### Example request

```json
{
  "description": "Quarterly liability insurance premium",
  "estimated_amount": 180000,
  "expected_date": "2026-04-01",
  "vendor_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f02"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_UpcomingBillListResponse_`

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

#### 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/bills/upcoming' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "description": "Quarterly liability insurance premium",
  "estimated_amount": 180000,
  "expected_date": "2026-04-01",
  "vendor_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f02"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/upcoming', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "description": "Quarterly liability insurance premium",
  "estimated_amount": 180000,
  "expected_date": "2026-04-01",
  "vendor_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f02"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'description': 'Quarterly liability insurance premium',
 'estimated_amount': 180000,
 'expected_date': '2026-04-01',
 'vendor_id': '0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f02'}

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

### See also

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

---

## DELETE /api/v1/bills/upcoming/{upcoming_bill_id}

> Delete an upcoming bill

- **Tag:** bills
- **Operation ID:** `delete_upcoming_bill`

### Description

Deletes this occurrence. Pass `series=true` to also drop every later still-expected occurrence in the same series; occurrences already converted into real bills are never touched.

### Authentication

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

### Parameters

- `upcoming_bill_id` (path, string, required)
- `series` (query, boolean, optional) — Also delete later still-expected occurrences.

### 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/bills/upcoming/{upcoming_bill_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/bills/upcoming/{upcoming_bill_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/bills/upcoming/{upcoming_bill_id}", headers=headers)
data = response.json()
```

### See also

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

---

## GET /api/v1/bills/upcoming/{upcoming_bill_id}

> Get one upcoming bill

- **Tag:** bills
- **Operation ID:** `get_upcoming_bill`

### Authentication

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

### Parameters

- `upcoming_bill_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_UpcomingBillResponse_`

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

#### 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/bills/upcoming/{upcoming_bill_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/bills/upcoming/{upcoming_bill_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/bills/upcoming/{upcoming_bill_id}", headers=headers)
data = response.json()
```

### See also

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

---

## PATCH /api/v1/bills/upcoming/{upcoming_bill_id}

> Edit an upcoming bill

- **Tag:** bills
- **Operation ID:** `update_upcoming_bill`

### Description

Edits this occurrence only, not the whole series — so a one-month change to a recurring estimate does not redefine the schedule.

### Authentication

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

### Parameters

- `upcoming_bill_id` (path, string, required)

### Request body

Schema: `UpcomingBillUpdateRequest`

- `vendor_id` (string)
- `vendor_name` (string)
- `description` (string)
- `estimated_amount` (integer)
- `expected_date` (string · date)
- `notes` (string)
- `status` (string) — Only expected/dismissed are settable. `converted` is set by the convert endpoint, which is the only path that creates a bill.

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_UpcomingBillResponse_`

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

#### 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/bills/upcoming/{upcoming_bill_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "vendor_id": "string",
  "vendor_name": "string",
  "description": "string",
  "estimated_amount": 0,
  "expected_date": "2026-01-01",
  "notes": "string"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/upcoming/{upcoming_bill_id}', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "vendor_id": "string",
  "vendor_name": "string",
  "description": "string",
  "estimated_amount": 0,
  "expected_date": "2026-01-01",
  "notes": "string"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'vendor_id': 'string',
 'vendor_name': 'string',
 'description': 'string',
 'estimated_amount': 0,
 'expected_date': '2026-01-01',
 'notes': 'string'}

response = httpx.patch("https://api.ondayzero.com/api/v1/bills/upcoming/{upcoming_bill_id}", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/upcoming/{upcoming_bill_id}/convert

> Push an upcoming bill into a real bill

- **Tag:** bills
- **Operation ID:** `convert_upcoming_bill`

### Description

Creates a **draft** bill from the estimate and marks the forecast row converted. The bill posts nothing to the ledger until it is approved and marked received, exactly like a hand-entered bill.

### Authentication

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

### Parameters

- `upcoming_bill_id` (path, string, required)

### Request body

Schema: `UpcomingBillConvertRequest`

- `amount` (integer) — Actual amount in cents. Defaults to the estimate.
- `due_date` (string · date) — Due date for the bill. Defaults to the expected date.
- `bill_number` (string) — Vendor's invoice number, when known.
- `s3_key` (string) — Attachment key for the received document.

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_UpcomingBillResponse_`

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

#### 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/bills/upcoming/{upcoming_bill_id}/convert' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 0,
  "due_date": "2026-01-01",
  "bill_number": "string",
  "s3_key": "string"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/upcoming/{upcoming_bill_id}/convert', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "amount": 0,
  "due_date": "2026-01-01",
  "bill_number": "string",
  "s3_key": "string"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'amount': 0,
 'due_date': '2026-01-01',
 'bill_number': 'string',
 's3_key': 'string'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/upcoming/{upcoming_bill_id}/convert", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/upcoming/{upcoming_bill_id}/link

> Match an upcoming bill to a bill that arrived

- **Tag:** bills
- **Operation ID:** `link_upcoming_bill`

### Description

Links the forecast row to an existing bill so the obligation stops being counted twice — once as a projection and once as a payable.

### Authentication

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

### Parameters

- `upcoming_bill_id` (path, string, required)

### Request body

Schema: `UpcomingBillLinkRequest`

- `bill_id` (string · required) — The real bill that satisfies this row.

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_UpcomingBillResponse_`

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

#### 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/bills/upcoming/{upcoming_bill_id}/link' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "bill_id": "string"
}'
```

#### JavaScript

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

#### Python

```python
import httpx

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

payload = {'bill_id': 'string'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/upcoming/{upcoming_bill_id}/link", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/upload

> Upload bill document

- **Tag:** bills
- **Operation ID:** `upload_bill_file`

### Description

Upload a PDF or image file for a bill. Returns s3_key to use when creating/updating bills.

### Authentication

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

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_UploadBillFileResponse_`

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

#### 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.

#### 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/bills/upload' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d ''
```

#### JavaScript

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

#### Python

```python
import httpx

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

payload = {}

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

### See also

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

---

## DELETE /api/v1/bills/{bill_id}

> Delete bill

- **Tag:** bills
- **Operation ID:** `delete_bill`

### Description

Delete a bill and its associated records.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)
- `force` (query, boolean, optional) — Force delete even if bill has associated records

### 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.

#### 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 DELETE 'https://api.ondayzero.com/api/v1/bills/{bill_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/bills/{bill_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/bills/{bill_id}", headers=headers)
data = response.json()
```

### See also

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

---

## GET /api/v1/bills/{bill_id}

> Get bill

- **Tag:** bills
- **Operation ID:** `get_bill`

### Description

Retrieve a specific bill by ID.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_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/bills/{bill_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/bills/{bill_id}", headers=headers)
data = response.json()
```

### See also

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

---

## PUT /api/v1/bills/{bill_id}

> Update bill

- **Tag:** bills
- **Operation ID:** `update_bill`

### Description

Update an existing bill. Optionally include 'recurring' config to create a recurring template.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `BillUpdateRequest`

- `status` (integer)
- `description` (string)
- `bill_number` (string)
- `vendor_id` (string)
- `type` (string)
- `expected_amount` (integer)
- `expected_paid_on_date` (string · date-time | string · date | string)
- `amount` (integer)
- `due_on` (string · date-time | string · date | string)
- `received_on` (string · date-time | string · date | string)
- `s3_key` (string)
- `source_inventory_order_id` (string)
- `payment_method` (string) — Payment method override: 'Wire Transfer', 'ACH', 'Check', 'Credit Card', or empty string to clear. Takes precedence over the method inferred from a linked payment transaction.
- `recurring` (RecurringConfig) — If provided, creates a recurring template from this bill.

### Example request

```json
{
  "amount": 250000,
  "description": "Office rent - March",
  "due_on": "2026-03-01",
  "payment_method": "ACH"
}
```

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 250000,
  "description": "Office rent - March",
  "due_on": "2026-03-01",
  "payment_method": "ACH"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "amount": 250000,
  "description": "Office rent - March",
  "due_on": "2026-03-01",
  "payment_method": "ACH"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'amount': 250000,
 'description': 'Office rent - March',
 'due_on': '2026-03-01',
 'payment_method': 'ACH'}

response = httpx.put("https://api.ondayzero.com/api/v1/bills/{bill_id}", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## PATCH /api/v1/bills/{bill_id}/approval

> Approve bill

- **Tag:** bills
- **Operation ID:** `approve_bill`

### Description

Approve a bill and change status to 'forecasted'

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/approval' \
  -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/bills/{bill_id}/approval', {
  method: 'PATCH',
  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.patch("https://api.ondayzero.com/api/v1/bills/{bill_id}/approval", headers=headers)
data = response.json()
```

### See also

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

---

## PATCH /api/v1/bills/{bill_id}/attachment

> Attach file to existing bill

- **Tag:** bills
- **Operation ID:** `attach_file_to_bill`

### Description

Attach a document file to an existing bill by updating its s3_key.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/attachment' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d ''
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/attachment', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {}

response = httpx.patch("https://api.ondayzero.com/api/v1/bills/{bill_id}/attachment", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/attach-file-to-bill
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/attach-file-to-bill/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PATCH /api/v1/bills/{bill_id}/cancellation

> Cancel bill

- **Tag:** bills
- **Operation ID:** `cancel_bill`

### Description

Cancel a bill and change status to 'canceled'

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/cancellation' \
  -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/bills/{bill_id}/cancellation', {
  method: 'PATCH',
  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.patch("https://api.ondayzero.com/api/v1/bills/{bill_id}/cancellation", headers=headers)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/{bill_id}/contract-comparison

> Compare bill against vendor contract

- **Tag:** bills
- **Operation ID:** `compare_bill_against_contract`

### Description

Compare a bill's amount against the vendor's active contract/MSA.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_CompareBillAgainstContractResponse_`

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

#### 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/bills/{bill_id}/contract-comparison' \
  -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/bills/{bill_id}/contract-comparison', {
  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/bills/{bill_id}/contract-comparison", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/compare-bill-against-contract
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/compare-bill-against-contract/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/{bill_id}/journal-entry

> Generate bill journal entry

- **Tag:** bills
- **Operation ID:** `generate_bill_journal_entry`

### Description

Create the outstanding AP journal entry for a received bill that has none linked.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `BillJournalEntryGenerateRequest`

- `ledger_id` (string · required) — UUID of the expense ledger account to debit.
- `journal_entry_date` (string · date-time | string · date | string) — Date for the accounting journal entry (ISO 8601 or YYYY-MM-DD). Defaults to received_on.

### Example request

```json
{
  "journal_entry_date": "2026-02-15",
  "ledger_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/journal-entry' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "journal_entry_date": "2026-02-15",
  "ledger_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/journal-entry', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "journal_entry_date": "2026-02-15",
  "ledger_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'journal_entry_date': '2026-02-15',
 'ledger_id': '0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/{bill_id}/journal-entry", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/generate-bill-journal-entry
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/generate-bill-journal-entry/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/{bill_id}/journal-entry/link

> Attach journal entry to bill

- **Tag:** bills
- **Operation ID:** `attach_journal_entry_to_bill`

### Description

Link an existing journal entry to a bill.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `JournalEntryLinkRequest`

- `journal_entry_id` (string · required) — UUID of the journal entry to attach.

### Example request

```json
{
  "journal_entry_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f22"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/journal-entry/link' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "journal_entry_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f22"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/journal-entry/link', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "journal_entry_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f22"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'journal_entry_id': '0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f22'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/{bill_id}/journal-entry/link", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/attach-journal-entry-to-bill
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/attach-journal-entry-to-bill/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## PATCH /api/v1/bills/{bill_id}/payment-initiation

> Mark or clear bill payment-initiated

- **Tag:** bills
- **Operation ID:** `set_bill_payment_initiation`

### Description

Track money in flight: mark that payment was initiated outside DayZero (e.g. a bank with no API) before the bank transaction exists to reconcile against.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `BillPaymentInitiationRequest`

- `initiated` (boolean · required) — True to mark payment initiated; False to clear the marker.
- `initiated_on` (string · date-time) — When the payment was initiated. Defaults to now when marking.

### Example request

```json
{
  "initiated": true,
  "initiated_on": "2026-02-20T15:30:00Z"
}
```

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/payment-initiation' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "initiated": true,
  "initiated_on": "2026-02-20T15:30:00Z"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/payment-initiation', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "initiated": true,
  "initiated_on": "2026-02-20T15:30:00Z"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'initiated': True, 'initiated_on': '2026-02-20T15:30:00Z'}

response = httpx.patch("https://api.ondayzero.com/api/v1/bills/{bill_id}/payment-initiation", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/set-bill-payment-initiation
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/set-bill-payment-initiation/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## GET /api/v1/bills/{bill_id}/payments

> List bill payments

- **Tag:** bills
- **Operation ID:** `list_bill_payments`

### Description

Retrieve all payments for a specific bill.

### Authentication

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

### Parameters

- `bill_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_ListBillPaymentsResponse_`

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

#### 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/bills/{bill_id}/payments' \
  -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/bills/{bill_id}/payments', {
  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/bills/{bill_id}/payments", headers=headers)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/{bill_id}/payments

> Add payment to bill

- **Tag:** bills
- **Operation ID:** `create_bill_payment`

### Description

Create a new payment for a specific bill.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `BillPaymentRequest`

- `transaction_id` (string · required) — UUID of the bank transaction representing the payment.
- `amount` (integer · required) — Payment amount in cents. Must be > 0.
- `paid_on` (string · date-time) — Override payment date (ISO 8601). Defaults to the transaction datetime if omitted.

### Example request

```json
{
  "amount": 125000,
  "transaction_id": "019ab37c-7801-7000-8000-000000000001"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillPaymentResponse_`

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

#### 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/bills/{bill_id}/payments' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 125000,
  "transaction_id": "019ab37c-7801-7000-8000-000000000001"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/payments', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "amount": 125000,
  "transaction_id": "019ab37c-7801-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 = {'amount': 125000,
 'transaction_id': '019ab37c-7801-7000-8000-000000000001'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/{bill_id}/payments", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## DELETE /api/v1/bills/{bill_id}/payments/{payment_id}

> Remove payment from bill

- **Tag:** bills
- **Operation ID:** `delete_bill_payment`

### Description

Un-link a payment record from a bill and recalculate status.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)
- `payment_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/bills/{bill_id}/payments/{payment_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/bills/{bill_id}/payments/{payment_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/bills/{bill_id}/payments/{payment_id}", headers=headers)
data = response.json()
```

### See also

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

---

## PATCH /api/v1/bills/{bill_id}/receipt

> Mark bill as received

- **Tag:** bills
- **Operation ID:** `mark_bill_received`

### Description

Mark a bill as received and create journal entry

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `BillReceivedRequest`

- `bill_id` (string) — UUID of the bill (set automatically from URL path).
- `amount` (integer · required) — Actual bill amount in cents. Must be greater than 0.
- `ledger_id` (string · required) — UUID of the expense ledger account to categorize this bill. Required for creating the journal entry.
- `s3_key` (string) — S3 key of the bill document.
- `journal_entry_date` (string · date-time | string · date | string) — Date for the accounting journal entry (ISO 8601 or YYYY-MM-DD).
- `received_on` (string · date-time | string · date | string) — Date the bill/goods were received (ISO 8601 or YYYY-MM-DD).
- `due_on` (string · date-time | string · date | string) — Payment due date (ISO 8601 or YYYY-MM-DD).

### Example request

```json
{
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}
```

### Responses

#### 200 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/receipt' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/receipt', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'amount': 250000,
 'due_on': '2024-01-31T00:00:00Z',
 'journal_entry_date': '2024-01-15T00:00:00Z',
 'ledger_id': '019ab37c-1ed1-7000-8000-000000000001',
 'received_on': '2024-01-15T00:00:00Z'}

response = httpx.patch("https://api.ondayzero.com/api/v1/bills/{bill_id}/receipt", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/{bill_id}/resolve-approval

> Force-resolve a stuck pending-approval bill

- **Tag:** bills
- **Operation ID:** `resolve_pending_approval`

### Description

Manually drive a bill that is wedged in 'pending_approval' to a terminal state when the normal Approve/Reject card is unavailable (the approval run never started, crashed before suspending, or suspended on a gate with no approvers). Cancels any in-flight approval run for the bill, then either approves it to 'received' (posting the journal entry) or rejects it to 'canceled'.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `ResolvePendingApprovalRequest`

- `action` (string · required) (one of: approve, reject) — 'approve' posts the bill to 'received'; 'reject' moves it to 'canceled'.
- `ledger_id` (string) — Expense ledger to debit when approving. Required unless the bill carries a persisted multi-account split. Ignored for 'reject'.
- `reason` (string) — Optional reason captured in the audit trail when rejecting.

### Example request

```json
{
  "action": "approve",
  "ledger_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/resolve-approval' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "action": "approve",
  "ledger_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/resolve-approval', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "action": "approve",
  "ledger_id": "0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'action': 'approve',
 'ledger_id': '0192a4f0-1b2c-7d3e-8f4a-5b6c7d8e9f11'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/{bill_id}/resolve-approval", headers=headers, json=payload)
data = response.json()
```

### See also

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

---

## POST /api/v1/bills/{bill_id}/revert-to-draft

> Revert bill to draft

- **Tag:** bills
- **Operation ID:** `revert_bill_to_draft`

### Description

Move a 'forecasted', 'pending_approval' or 'received' bill back to 'draft' so it can be edited. A received bill's journal entry is reversed on its original date (refused if that period is closed or any payment/credit is applied); a multi-account split is kept on the draft. Any in-flight approval run is cancelled. Bills raised by a purchase order or inventory transfer cannot be reverted.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/revert-to-draft' \
  -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/bills/{bill_id}/revert-to-draft', {
  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/bills/{bill_id}/revert-to-draft", headers=headers)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/revert-bill-to-draft
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/revert-bill-to-draft/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/{bill_id}/submit-for-ap-approval

> Submit bill for AP approval

- **Tag:** bills
- **Operation ID:** `submit_bill_for_ap_approval`

### Description

Manually route a forecasted bill into the firm's AP approval workflow. Use when a bill was approved before the workflow was provisioned or when automatic routing did not run. The bill moves from 'forecasted' to 'pending_approval' and posts to 'received' only once an approver signs off.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `BillReceivedRequest`

- `bill_id` (string) — UUID of the bill (set automatically from URL path).
- `amount` (integer · required) — Actual bill amount in cents. Must be greater than 0.
- `ledger_id` (string · required) — UUID of the expense ledger account to categorize this bill. Required for creating the journal entry.
- `s3_key` (string) — S3 key of the bill document.
- `journal_entry_date` (string · date-time | string · date | string) — Date for the accounting journal entry (ISO 8601 or YYYY-MM-DD).
- `received_on` (string · date-time | string · date | string) — Date the bill/goods were received (ISO 8601 or YYYY-MM-DD).
- `due_on` (string · date-time | string · date | string) — Payment due date (ISO 8601 or YYYY-MM-DD).

### Example request

```json
{
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_SubmitBillForApApprovalResponse_`

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

#### 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/bills/{bill_id}/submit-for-ap-approval' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/submit-for-ap-approval', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'amount': 250000,
 'due_on': '2024-01-31T00:00:00Z',
 'journal_entry_date': '2024-01-15T00:00:00Z',
 'ledger_id': '019ab37c-1ed1-7000-8000-000000000001',
 'received_on': '2024-01-15T00:00:00Z'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/{bill_id}/submit-for-ap-approval", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/submit-bill-for-ap-approval
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/submit-bill-for-ap-approval/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

## POST /api/v1/bills/{bill_id}/submit-for-approval

> Send bill for approval

- **Tag:** bills
- **Operation ID:** `submit_bill_for_approval`

### Description

Submit a cleaned-up draft bill into the AP approval workflow. The bill moves to 'pending_approval' and is NOT posted to the general ledger until an approver signs off, at which point it posts to 'received'. Requires the business to have the approval workflow enabled.

### Authentication

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

### Parameters

- `bill_id` (path, string, required)

### Request body

Schema: `BillReceivedRequest`

- `bill_id` (string) — UUID of the bill (set automatically from URL path).
- `amount` (integer · required) — Actual bill amount in cents. Must be greater than 0.
- `ledger_id` (string · required) — UUID of the expense ledger account to categorize this bill. Required for creating the journal entry.
- `s3_key` (string) — S3 key of the bill document.
- `journal_entry_date` (string · date-time | string · date | string) — Date for the accounting journal entry (ISO 8601 or YYYY-MM-DD).
- `received_on` (string · date-time | string · date | string) — Date the bill/goods were received (ISO 8601 or YYYY-MM-DD).
- `due_on` (string · date-time | string · date | string) — Payment due date (ISO 8601 or YYYY-MM-DD).

### Example request

```json
{
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}
```

### Responses

#### 201 — Successful Response

Schema: `SuccessEnvelope_BillResponse_`

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

#### 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/bills/{bill_id}/submit-for-approval' \
  -H 'Authorization: Bearer dz_your_token' \
  -H 'x-business-id: YOUR_BUSINESS_ID' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}'
```

#### JavaScript

```javascript
const response = await fetch('https://api.ondayzero.com/api/v1/bills/{bill_id}/submit-for-approval', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer dz_your_token',
    'x-business-id': 'YOUR_BUSINESS_ID',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "amount": 250000,
  "due_on": "2024-01-31T00:00:00Z",
  "journal_entry_date": "2024-01-15T00:00:00Z",
  "ledger_id": "019ab37c-1ed1-7000-8000-000000000001",
  "received_on": "2024-01-15T00:00:00Z"
}),
});
const data = await response.json();
```

#### Python

```python
import httpx

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

payload = {'amount': 250000,
 'due_on': '2024-01-31T00:00:00Z',
 'journal_entry_date': '2024-01-15T00:00:00Z',
 'ledger_id': '019ab37c-1ed1-7000-8000-000000000001',
 'received_on': '2024-01-15T00:00:00Z'}

response = httpx.post("https://api.ondayzero.com/api/v1/bills/{bill_id}/submit-for-approval", headers=headers, json=payload)
data = response.json()
```

### See also

- HTML version: https://www.ondayzero.com/docs/reference/bills/submit-bill-for-approval
- OpenAPI slice: https://www.ondayzero.com/docs/reference/bills/submit-bill-for-approval/openapi.json
- Other endpoints in **bills**: https://www.ondayzero.com/docs/reference/bills (markdown bundle: https://www.ondayzero.com/docs/reference/bills.md, OpenAPI: https://www.ondayzero.com/docs/reference/bills/openapi.json)
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md
