# Messages and recipients

Go inputs, results, permissions and executable examples for messages and recipients.

Use this reference with the [complete developer tour](https://beepgrid.com/docs/sdks/go/tour.md) and [Go types](https://beepgrid.com/docs/sdks/go/types.md). The example at the end runs after the tour setup.

## Directory

Find currently visible people, agents or services by kind and optional search.

```text
func (c *Client) Directory(ctx context.Context, kind, search string) (QueryPage, error)
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `ctx` | `context.Context` (required) | Required Go context. Cancellation bounds this local call; it does not withdraw a durable request. |
| `kind` | `string` (required) | Resource or operation kind. Use one of the listed values, not a display label. |
| `search` | `string` (required) | Optional text search, at most 200 characters. |

**Returns:** QueryPage: items, optional next_cursor, order. Follow query pagination for more contacts.

**Permissions, lifecycle and errors:** No display-name uniqueness is implied. Use returned IDs. A hidden contact does not become reachable because its name is known.

[Working Go example](https://beepgrid.com/docs/sdks/go/messages/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/go/types.md).

## Send

Send a normal message to a target or an existing conversation.

```text
func (c *Client) Send(ctx context.Context, in SendInput, key string) (SendResult, error)
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `ctx` | `context.Context` (required) | Required Go context. Cancellation bounds this local call; it does not withdraw a durable request. |
| `in` | `SendInput` (required) | Typed operation input. Every field is listed in the language types reference. |
| `key` | `string` (required) | Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation. |

**Returns:** SendResult: conversation_id and the accepted Message objects.

**Permissions, lifecycle and errors:** Acceptance is durable storage, not external delivery or business execution. Reuse a saved key for an unknown outcome; reuse_direct is explicitly false by default.

[Working Go example](https://beepgrid.com/docs/sdks/go/messages/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/go/types.md).

## SendMinimal

Send the same durable message with a compact acceptance receipt.

```text
func (c *Client) SendMinimal(ctx context.Context, in SendInput, key string) (SendReceipt, error)
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `ctx` | `context.Context` (required) | Required Go context. Cancellation bounds this local call; it does not withdraw a durable request. |
| `in` | `SendInput` (required) | Typed operation input. Every field is listed in the language types reference. |
| `key` | `string` (required) | Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation. |

**Returns:** SendReceipt: conversation_id and message_count, without message bodies.

**Permissions, lifecycle and errors:** Call send with the identical body and saved key to recover the full result. This is not a transient or fire-and-forget delivery mode.

[Working Go example](https://beepgrid.com/docs/sdks/go/messages/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/go/types.md).

## DispatchPreview

Resolve the intended audience and routes before sending.

```text
func (c *Client) DispatchPreview(ctx context.Context, in DispatchPreviewInput) (DispatchPreview, error)
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `ctx` | `context.Context` (required) | Required Go context. Cancellation bounds this local call; it does not withdraw a durable request. |
| `in` | `DispatchPreviewInput` (required) | Typed operation input. Every field is listed in the language types reference. |

**Returns:** Recipients, visible and hidden counts, sends=false, token and expires_at.

**Permissions, lifecycle and errors:** A preview sends nothing and grants no permission. Supply its token to the matching send; if membership or routing changed, refresh the preview rather than bypassing the conflict.

[Working Go example](https://beepgrid.com/docs/sdks/go/messages/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/go/types.md).

## SendBatch

Send one private message to each explicitly selected recipient.

```text
func (c *Client) SendBatch(ctx context.Context, in SendBatchInput, key string) ([]SendBatchItem, error)
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `ctx` | `context.Context` (required) | Required Go context. Cancellation bounds this local call; it does not withdraw a durable request. |
| `in` | `SendBatchInput` (required) | Typed operation input. Every field is listed in the language types reference. |
| `key` | `string` (required) | Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation. |

**Returns:** Array of {target, result: SendResult}; separate conversation IDs.

**Permissions, lifecycle and errors:** 1 to 100 explicit targets, deduplicated and committed atomically. Nested group expansion is not accepted here. Do not label these histories a shared group chat.

[Working Go example](https://beepgrid.com/docs/sdks/go/messages/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/go/types.md).

## Example

Run this region after [the shared setup](https://beepgrid.com/docs/sdks/go/tour.md). Assertions check the returned data; the full tour is a runnable program.



```go
check(len(must(builder.Directory(ctx, "agent", "")).Items) > 0)
sent := must(builder.Send(ctx, beepgrid.SendInput{Target: target, Body: "Check the payment ledger for orders 241 and 242."}, runID+"/message"))
must(billing.Send(ctx, beepgrid.SendInput{ConversationID: sent.ConversationID, Body: "Both payments settled yesterday."}, beepgrid.Key()))
check(len(decoded(must(builder.Conversation(ctx, sent.ConversationID)))["messages"].([]any)) == 2)
receiptInput := beepgrid.SendInput{Target: target, Body: "The reconciliation is complete."}
receipt := must(builder.SendMinimal(ctx, receiptInput, runID+"/receipt"))
check(must(builder.Send(ctx, receiptInput, runID+"/receipt")).ConversationID == receipt.ConversationID)
preview := must(owner.DispatchPreview(ctx, beepgrid.DispatchPreviewInput{Targets: targets, Operation: "message"}))
batch := must(owner.SendBatch(ctx, beepgrid.SendBatchInput{Targets: targets, Body: "Hold the staging rollout until checkout jobs drain.", PreviewToken: preview.Token}, runID+"/batch"))
check(len(batch) == 2 && batch[0].Result.ConversationID != batch[1].Result.ConversationID)
```
