> For the complete documentation index, see [llms.txt](https://dnotifier.gitbook.io/product-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dnotifier.gitbook.io/product-docs/reference/types-and-payloads.md).

# Types & payloads

Shared data shapes used across realtime messaging, AI, and workflows.

## `DNotifierMessage`

Delivered to `onMessage` on WebSocket transport.

| Field      | Type      | Description               |
| ---------- | --------- | ------------------------- |
| `metadata` | object    | Routing and envelope info |
| `payload`  | `Payload` | Body wrapper              |

### `metadata` fields

| Field       | Type     | Description           |
| ----------- | -------- | --------------------- |
| `id`        | `string` | Message or session id |
| `sender`    | `string` | Prefixed sender id    |
| `timestamp` | `number` | Unix ms               |
| `type`      | `string` | Packet type           |

Dart uses typed classes: `DNotifierMessage`, `DNotifierMessageMetadata`.

## `Payload`

Wraps the raw frame body.

| Method                | Returns                               | Description                                  |
| --------------------- | ------------------------------------- | -------------------------------------------- |
| `toJSON()`            | `object \| null`                      | Parse JSON body; revives binary fields in JS |
| `toString(encoding?)` | `string`                              | UTF-8 string (default)                       |
| `toBase64()`          | `string`                              | Base64 encoding                              |
| `raw()`               | `Buffer` / `Uint8Array` / `List<int>` | Raw bytes                                    |

## Outgoing `send()` data shapes

The SDK does not enforce a schema — use conventions that fit your app:

| `data.type` | Typical fields                        |
| ----------- | ------------------------------------- |
| `"text"`    | `text: string`                        |
| `"image"`   | `content: bytes`                      |
| `"audio"`   | `content: bytes`, `mimeType?: string` |
| `"doc"`     | `content: bytes`, `filename?: string` |
| custom      | Any JSON-serializable fields          |

## AI `message` shapes

### Simple prompt

```json
{ "text": "Summarize this ticket." }
```

### Chat-style

```json
{
  "useKnowledgeBase": true,
  "messages": [
    { "role": "system", "content": "You are helpful." },
    { "role": "user", "content": "Question here." }
  ]
}
```

## Knowledge-base document payload

| Field      | Type     | Required |
| ---------- | -------- | -------- |
| `recordId` | `string` | ✅        |
| `content`  | `string` | ✅        |
| `type`     | `string` | —        |
| `metadata` | `object` | —        |

Aliases accepted: `record_id`, `text` (instead of `content`).

## `getPlanLimits()` return value

| Field                   | Type      | Description                 |
| ----------------------- | --------- | --------------------------- |
| `messagesHardLimit`     | `number`  | Message hard cap            |
| `maxAIRequestsPerMonth` | `number`  | AI requests (0 if disabled) |
| `maxAIWordsPerMonth`    | `number`  | AI word quota               |
| `knowledgeBaseMaxWords` | `number`  | KB word cap                 |
| `aiEnabled`             | `boolean` | AI feature flag             |
| `maxUsers`              | `number`  | Storage users               |
| `maxRowsPerUser`        | `number`  | Rows per user               |

Dart: `DNotifierPlanLimits` class with nullable `int?` fields.

## `runWorkflow()` return value

| Field         | Type     | Description                        |
| ------------- | -------- | ---------------------------------- |
| `result`      | `*`      | Return value of workflow `entry`   |
| `state`       | `object` | Shared workflow state              |
| `executionId` | `string` | Present when `observability: true` |

## Server packet codes (reference)

| Code        | Type        | Meaning                          |
| ----------- | ----------- | -------------------------------- |
| `101`       | handshake   | Client auth frame                |
| `102`       | handshake   | Server ack                       |
| `200`       | text        | Send message                     |
| `201`       | text        | Fetch chat history               |
| `202`       | text/binary | Delete chat message / raw binary |
| `300`       | ai          | AI prompt / response             |
| `301`       | ai          | Fetch AI history                 |
| `302`       | ai          | Delete AI message                |
| `303`       | ai          | Semantic search                  |
| `306`–`310` | ai          | Knowledge-base CRUD              |

## Framed packets

WebSocket messages use a binary frame format combining metadata JSON and payload bytes. Large payloads are split into chunks sharing the same `id` with `totalPackets` and `currentPacket` fields. The SDK reassembles chunks before calling `onMessage`.

See [Large messages & chunking](/product-docs/realtime-communication/chunking.md).
