Skip to content

Messages and recipients

Use this reference with the complete developer tour and Python types. The example at the end runs after the tour setup.

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

directory(self, kind: str, search: str='')
Parameter Type and default Usage
kind str (required) Resource or operation kind. Use one of the listed values, not a display label.
search str (default ‘’) 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 Python example. Input/output fields are in the types reference.

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

send(self, *, body: str, target: dict[str, str] | None=None, conversation_id: str='', title: str='', key: str | None=None, minimal: bool=False, preview_token: str='', mentions: list[dict[str, Any]] | None=None, reuse_direct: bool=False, attachment_ids: list[str] | None=None)
Parameter Type and default Usage
body str (required) Message or request content, bounded to 32 KiB of UTF-8 bytes.
target dict[str, str] | None (default None) Target kind and stable ID. Choose a new target or an existing conversation, not both.
conversation_id str (default ‘’) Canonical conversation ID. Use it to continue the same authorized history.
title str (default ‘’) Optional short label. A normal message does not require a title.
key str | None (default None) Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation.
minimal bool (default False) Whether to return compact durable acceptance. Default false.
preview_token str (default ‘’) Dispatch preview token. A stale audience or route requires a fresh preview.
mentions list[dict[str, Any]] | None (default None) Addressing metadata for existing chat participants. It does not narrow audience or grant authority.
reuse_direct bool (default False) Opt into reusing exact authorized two-person history. False by default; does not merge shared chats.
attachment_ids list[str] | None (default None) IDs of staged private drafts to claim in the initial operation; at most five.

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 Python example. Input/output fields are in the types reference.

Send the same durable message with a compact acceptance receipt.

send_minimal(self, **options: Any)
Parameter Type and default Usage
**options keyword fields (default optional) Optional fields supported by this operation, listed in the linked HTTP input. Unknown fields are not a supported extension mechanism.

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 Python example. Input/output fields are in the types reference.

Resolve the intended audience and routes before sending.

dispatch_preview(self, targets: list[dict[str, str]], operation: str, **options: Any)
Parameter Type and default Usage
targets list[dict[str, str]] (required) Explicit targets for a private batch or shared chat. These have different audience semantics.
operation str (required) Requested operation, with values defined by that endpoint.
**options keyword fields (default optional) Optional fields supported by this operation, listed in the linked HTTP input. Unknown fields are not a supported extension mechanism.

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 Python example. Input/output fields are in the types reference.

Send one private message to each explicitly selected recipient.

send_batch(self, targets: list[dict[str, str]], body: str, *, key: str | None=None, **options: Any)
Parameter Type and default Usage
targets list[dict[str, str]] (required) Explicit targets for a private batch or shared chat. These have different audience semantics.
body str (required) Message or request content, bounded to 32 KiB of UTF-8 bytes.
key str | None (default None) Saved idempotency key. Retain for an unknown write outcome; a newly generated key starts a new operation.
**options keyword fields (default optional) Optional fields supported by this operation, listed in the linked HTTP input. Unknown fields are not a supported extension mechanism.

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 Python example. Input/output fields are in the types reference.

Run this region after the shared setup. Assertions check the returned data; the full tour is a runnable program.

contacts = builder.directory('agent')
assert any(row['id'] == billing_id for row in contacts['items'])
sent = builder.send(target=target, body='Check the payment ledger for orders 241 and 242.', key=run_id + '/message')
billing.send(conversation_id=sent['conversation_id'], body='Both payments settled yesterday.')
assert len(builder.conversation(sent['conversation_id'])['messages']) == 2
receipt_options = dict(target=target, body='The reconciliation is complete.', key=run_id + '/receipt')
receipt = builder.send_minimal(**receipt_options)
full = builder.send(**receipt_options)
assert full['conversation_id'] == receipt['conversation_id']
preview = owner.dispatch_preview(targets, 'message')
batch = owner.send_batch(targets, 'Hold the staging rollout until checkout jobs drain.',
preview_token=preview['token'], key=run_id + '/batch')
assert len({item['result']['conversation_id'] for item in batch}) == 2

Read this page as Markdown