---
title: "Message Browser - Pilot Docs"
description: "Browse and inspect Kafka messages"
url: "https://docs.calinora.io/features/message-browser/"
---

# Message Browser

Pilot includes a message browser that lets you inspect Kafka messages directly from the UI or API without setting up a separate consumer.

## Features

- **Tail mode** - stream new messages as they arrive
- **Offset-based browsing** - fetch messages from a specific partition and offset
- **Single message lookup** - retrieve a specific message by partition and offset
- **Watermark inspection** - view partition watermarks (earliest and latest offsets)

## API Endpoints

| Method | Path | Description |
| - | - | - |
| `GET` | `/api/v1/topics/{topic}/messages/tail` | New messages over Server-Sent Events (SSE) |
| `GET` | `/api/v1/topics/{topic}/messages` | Message range fetch |
| `GET` | `/api/v1/topics/{topic}/messages/{partition}/{offset}` | Single message by partition and offset |
| `GET` | `/api/v1/topics/{topic}/watermarks` | Partition watermarks |

### Example: Tail New Messages

```bash
curl -N "http://localhost:8080/api/v1/topics/my-topic/messages/tail"
```

Tail starts at the current end of each requested partition. The `ready` event confirms that every requested partition reader has started; `message` events may arrive before it. A terminal `error` event ends the stream. Inspect the error and retry the connection when the cause is resolved. Reconnecting starts a new tail rather than replaying the previous connection’s records.

### Example: Browse Recent Messages

Use the range endpoint to read existing records:

```bash
curl "http://localhost:8080/api/v1/topics/my-topic/messages?seek=latest&limit=10"
```

### Example: Fetch from Offset

```bash
curl "http://localhost:8080/api/v1/topics/my-topic/messages?partition=0&offset=100&limit=50"
```

### Example: Get Watermarks

```bash
curl "http://localhost:8080/api/v1/topics/my-topic/watermarks"
```

### Pagination and Ordering

For browsing across all partitions, pass `data.meta.nextCursor.token` unchanged as `cursor` on the next request. Treat it as opaque and retain the same filters and direction. A filtered page can contain no matching messages while `data.meta.hasMore` is true; continue with its next cursor rather than treating the empty page as the end.

Offsets order records within a partition. Results across partitions do not provide a global timestamp ordering. See the [OpenAPI specification](https://github.com/julianbergner/Pilot/blob/WIP/api-docs/openapi.yaml) for cursor fields and query parameters.

## Message Display

Messages are deserialized and displayed with:

- **Key** - message key (if present)
- **Value** - message value (automatically detected as JSON, string, or binary)
- **Headers** - Kafka message headers
- **Metadata** - partition, offset, timestamp
