> 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/getting-started/first-message.md).

# Your first message

After a successful [**connection**](/product-docs/getting-started/first-connection.md), you can send a **1:1 realtime message** to another user. This hub explains the concept; language pages have runnable code.

## What you are building

A minimal flow with two logical users:

```
  user-alice (your SDK)                    user-bob (another client)
         │                                          │
         │  send({ receiverId: "user-bob", ... })   │
         ├─────────────────────────────────────────►│
         │                                          │
         │◄─────────────────────────────────────────┤
         │         onMessage on bob's client          │
```

Both users connect with the **same `appId`** but different **`userId`** values. Messages route by `senderId` and `receiverId`.

## Requirements

* **`transport: "ws"`** — realtime send/receive uses WebSocket
* **`connect()` completed** — `isConnected === true`
* **Receiver exists conceptually** — the receiver does not need to be online; DNotifier delivers when they connect (subject to plan and app rules)

## The `send()` call

All SDKs expose a similar `send()` shape:

| Field         | Description                                                           |
| ------------- | --------------------------------------------------------------------- |
| `senderId`    | Must match the connecting user's id (your `userId`)                   |
| `receiverId`  | Target user's id (single recipient)                                   |
| `data`        | JSON-serializable payload — typically `{ type: "text", text: "..." }` |
| `saveHistory` | Optional; default `true` — persist for chat history APIs              |

Example payload:

```json
{
  "type": "text",
  "text": "Hello from DNotifier!"
}
```

Use any `type` string your app understands (`text`, `image`, `audio`, `doc`, custom types).

## Receiving messages

Incoming messages arrive on the **`onMessage`** callback registered at construction time. Each message has:

* **`metadata`** — sender, timestamp, id, type
* **`payload`** — body with helpers like `toJSON()`

See [**Understanding messages**](/product-docs/getting-started/understanding-messages.md) for the full model.

## Language guides

| Language                | Guide                                                                                            |
| ----------------------- | ------------------------------------------------------------------------------------------------ |
| JavaScript / TypeScript | [javascript-typescript.md](/product-docs/getting-started/first-message/javascript-typescript.md) |
| Dart / Flutter          | [dart-flutter.md](/product-docs/getting-started/first-message/dart-flutter.md)                   |
| Python                  | [python.md](/product-docs/getting-started/first-message/python.md)                               |

## Test with two clients

To see end-to-end delivery:

1. Run two terminal processes (or two browser tabs)
2. Connect as `user-alice` in one and `user-bob` in the other
3. Send from alice to bob and watch bob's `onMessage` fire

## Next steps

* [**Understanding messages**](/product-docs/getting-started/understanding-messages.md) — Metadata, payload, and types
* [**Realtime communication overview**](/product-docs/realtime-communication/overview.md) — Deeper messaging patterns
* [**Chat overview**](/product-docs/chat/overview.md) — Building chat on top of realtime
