# Biller Messages API

Canonical message retrieval, read state, consent, reporting, and scoped suppression.

> **Scope of this file.** It is the OPERATION reference for THIS resource, generated from the BillerAPI OpenAPI document served at [/docs/openapi.json](/docs/openapi.json): each API-key endpoint the resource owns, with its parameters, request body, responses and schemas. Narrative and catalog sections the rendered page also carries (walkthroughs, event taxonomies, payload catalogs) are NOT reproduced here — read [/docs/api/customer-messaging](/docs/api/customer-messaging) for those. Endpoints the hosted flow drives from inside the iframe, and dashboard-session endpoints, are absent by design: they are not API-key operations. [/docs/api.md](/docs/api.md) enumerates the full API-key surface, including the endpoints that have no reference page yet.

All request and response field names are snake_case. Errors use the coded envelope described in [/docs/concepts/errors.md](/docs/concepts/errors.md).

## Endpoints

- [`POST /v1/customers/{user_aid}/messages`](#post-v1customersuser_aidmessages)
- [`GET /v1/customers/{user_aid}/consents`](#get-v1customersuser_aidconsents)
- [`POST /v1/customers/{user_aid}/consents`](#post-v1customersuser_aidconsents)
- [`POST /v1/customers/{user_aid}/complaints`](#post-v1customersuser_aidcomplaints)
- [`GET /v1/biller_messages`](#get-v1biller_messages)
- [`GET /v1/biller_messages/{message_id}`](#get-v1biller_messagesmessage_id)
- [`POST /v1/biller_messages/{message_id}/read`](#post-v1biller_messagesmessage_idread)
- [`POST /v1/biller_messages/{message_id}/report`](#post-v1biller_messagesmessage_idreport)
- [`GET /v1/clients/me/suppressions`](#get-v1clientsmesuppressions)
- [`DELETE /v1/clients/me/suppressions/{user_aid}`](#delete-v1clientsmesuppressionsuser_aid)

## POST /v1/customers/{user_aid}/messages

> **Deprecated.**

Deprecated compatibility message sender

Fintech client credentials do not authorize a caller to speak for a biller. Use the authenticated biller producer surface instead.

Operation ID: `sendMessage`

Auth: `client-api-key`

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 403 | Fintech credentials cannot speak for a biller. | — |

## GET /v1/customers/{user_aid}/consents

Inspect customer's per-category consent state

Operation ID: `getConsents`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `user_aid` | path | yes | string | — | — |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 200 | — | — |

## POST /v1/customers/{user_aid}/consents

Update customer's per-category consent

Operation ID: `updateConsent`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `user_aid` | path | yes | string | — | — |

**Request body** (required)

Schema: `UpdateCustomerConsentDto`

> The OpenAPI document declares this body but does not describe its fields, so this file cannot list them and will not guess. Read [/docs/api/customer-messaging](/docs/api/customer-messaging) for the fields this endpoint expects.

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 200 | — | — |

## POST /v1/customers/{user_aid}/complaints

Record a customer complaint about a message

Operation ID: `recordComplaint`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `user_aid` | path | yes | string | — | — |

**Request body** (required)

Schema: `RecordCustomerComplaintDto`

> The OpenAPI document declares this body but does not describe its fields, so this file cannot list them and will not guess. Read [/docs/api/customer-messaging](/docs/api/customer-messaging) for the fields this endpoint expects.

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 202 | Complaint recorded; suppression added; webhook fan-out triggered. | — |

## GET /v1/biller_messages

List canonical biller messages for a client user

Operation ID: `list`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `client_user_id` | query | yes | string | — | Your stable user identifier. |
| `account_link_id` | query | no | string | — | Limit results to one connected account. |
| `unread_only` | query | no | `true` \| `false` | — | Return only unread messages. |
| `limit` | query | no | number | default `50`; minimum `1`; maximum `100` | — |
| `cursor` | query | no | string | — | Opaque pagination cursor. |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 200 | — | `BillerMessagesPageDto` |

Response body — `BillerMessagesPageDto` (200)

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `data` | yes | array<BillerMessageResourceDto> | — | — |
| `next_cursor` | no | string | — | — |

## GET /v1/biller_messages/{message_id}

Retrieve a canonical biller message

Operation ID: `retrieve`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `message_id` | path | yes | string | — | — |
| `client_user_id` | query | yes | string | — | Your stable user identifier. |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 200 | — | `BillerMessageResourceDto` |

Response body — `BillerMessageResourceDto` (200)

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `id` | yes | string | — | — |
| `client_user_id` | yes | string | — | — |
| `biller_id` | yes | string | — | — |
| `biller_name` | yes | string | — | — |
| `account_link_id` | yes | string | — | — |
| `account_id` | no | string | — | — |
| `category` | yes | `marketing` \| `account_update` | — | — |
| `subject` | yes | string | — | — |
| `body` | yes | string | — | — |
| `created_at` | yes | string | — | — |
| `received_at` | yes | string | — | — |
| `read_at` | no | string | — | — |
| `reported_at` | no | string | — | — |
| `consent_basis` | yes | string | — | Consent source recorded when the message was accepted. |
| `delivery_status` | yes | string | — | — |

## POST /v1/biller_messages/{message_id}/read

Persist canonical read state

Operation ID: `markRead`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `message_id` | path | yes | string | — | — |
| `client_user_id` | query | yes | string | — | Your stable user identifier. |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 200 | — | `BillerMessageReadResponseDto` |

Response body — `BillerMessageReadResponseDto` (200)

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `id` | yes | string | — | — |
| `read_at` | yes | string | — | — |

## POST /v1/biller_messages/{message_id}/report

Report a message and apply scoped suppression

Operation ID: `report`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `message_id` | path | yes | string | — | — |
| `client_user_id` | query | yes | string | — | Your stable user identifier. |

**Request body** (required)

Schema: `ReportBillerMessageDto`

| Field | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `reason` | yes | `spam` \| `misleading` \| `never_signed_up` \| `other` | — | — |
| `note` | no | string | maximum length `280` | — |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 202 | Report recorded for the message biller and category. | `BillerMessageReportResponseDto` |

Response body — `BillerMessageReportResponseDto` (202)

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `message_id` | yes | string | — | — |
| `recorded_at` | yes | string | — | — |

## GET /v1/clients/me/suppressions

List suppression rows for this client

Operation ID: `list`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `limit` | query | yes | string | — | — |
| `cursor` | query | yes | string | — | — |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 200 | Paginated list | — |

## DELETE /v1/clients/me/suppressions/{user_aid}

Manually remove a suppression row

Operation ID: `remove`

Auth: `client-api-key`

**Parameters**

| Parameter | In | Required | Type | Notes | Description |
| --- | --- | --- | --- | --- | --- |
| `user_aid` | path | yes | string | — | — |
| `biller_id` | query | yes | string | — | — |
| `category` | query | yes | string | — | — |

**Responses**

| Status | Description | Body |
| --- | --- | --- |
| 200 | — | — |

## Schemas

### BillerMessageReadResponseDto

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `id` | yes | string | — | — |
| `read_at` | yes | string | — | — |

### BillerMessageReportResponseDto

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `message_id` | yes | string | — | — |
| `recorded_at` | yes | string | — | — |

### BillerMessageResourceDto

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `id` | yes | string | — | — |
| `client_user_id` | yes | string | — | — |
| `biller_id` | yes | string | — | — |
| `biller_name` | yes | string | — | — |
| `account_link_id` | yes | string | — | — |
| `account_id` | no | string | — | — |
| `category` | yes | `marketing` \| `account_update` | — | — |
| `subject` | yes | string | — | — |
| `body` | yes | string | — | — |
| `created_at` | yes | string | — | — |
| `received_at` | yes | string | — | — |
| `read_at` | no | string | — | — |
| `reported_at` | no | string | — | — |
| `consent_basis` | yes | string | — | Consent source recorded when the message was accepted. |
| `delivery_status` | yes | string | — | — |

### BillerMessagesPageDto

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `data` | yes | array<BillerMessageResourceDto> | — | — |
| `next_cursor` | no | string | — | — |

### RecordCustomerComplaintDto

No object properties are declared for this schema in the OpenAPI document.

### ReportBillerMessageDto

| Field | Always present | Type | Notes | Description |
| --- | --- | --- | --- | --- |
| `reason` | yes | `spam` \| `misleading` \| `never_signed_up` \| `other` | — | — |
| `note` | no | string | maximum length `280` | — |

### UpdateCustomerConsentDto

No object properties are declared for this schema in the OpenAPI document.


## See also

- [API reference index](/docs/api.md)
- [Authentication](/docs/guides/authentication.md)
- [Pagination](/docs/concepts/pagination.md)
- [Error handling](/docs/concepts/errors.md)
