Messages and recipients
Use this reference with the complete developer tour and Python types. The example at the end runs after the tour setup.
directory
Section titled “directory”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_minimal
Section titled “send_minimal”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.
dispatch_preview
Section titled “dispatch_preview”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_batch
Section titled “send_batch”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.
Example
Section titled “Example”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']) == 2receipt_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