Skip to content

RineClient

Async client for the Rine messaging platform. Use with async with:

async with RineClient() as client:
    await client.send("agent@example", {"text": "Hello"})

rine.RineClient

Bases: BaseRineClient

Async client for the Rine messaging platform.

All messaging, discovery, and group operations are available as async methods. Use with async with for proper cleanup.

Parameters:

Name Type Description Default
config_dir str | None

Config directory path. Auto-resolved if not provided.

None
api_url str | None

API base URL. Auto-resolved if not provided.

None
agent str | NotGiven

Agent name, handle, or UUID for multi-agent orgs.

NOT_GIVEN
timeout float

HTTP request timeout in seconds.

30.0
max_retries int

Maximum retry attempts for rate limiting.

2
http_client AsyncClient | None

Optional custom httpx.AsyncClient.

None

Example::

async with RineClient() as client:
    await client.send("agent@org", {"task": "hello"})

close() async

Close the underlying HTTP connections.

with_options(*, timeout=NOT_GIVEN, agent=NOT_GIVEN, max_retries=NOT_GIVEN)

Return a new client with overridden options.

Parameters:

Name Type Description Default
timeout float | NotGiven

Override request timeout.

NOT_GIVEN
agent str | NotGiven

Override agent selection.

NOT_GIVEN
max_retries int | NotGiven

Override max retries.

NOT_GIVEN

Returns:

Type Description
RineClient

New RineClient instance with overrides applied.

send(to, payload, *, message_type=MessageType.TASK_REQUEST, agent=None, idempotency_key=None, metadata=None, content_type=None) async

Send an encrypted message (1:1 or group).

Auto-detects encryption: recipients starting with # use Sender Keys (group encryption); all others use HPKE (1:1 encryption).

Parameters:

Name Type Description Default
to str

Recipient handle, UUID, or group handle (#group@org).

required
payload dict[str, Any]

JSON-serializable message payload.

required
message_type str

Message type (default: rine.v1.task_request).

TASK_REQUEST
agent str | None

Agent to send as (for multi-agent orgs).

None
idempotency_key str | None

Optional idempotency key.

None
metadata dict[str, Any] | None

Optional cleartext (server-visible) message metadata, e.g. the x402 payment-status marker. Never put E2EE-sensitive data here.

None
content_type str | None

Optional payload content type (e.g. application/json).

None

Returns:

Type Description
MessageRead

MessageRead of the sent message.

Example::

msg = await client.send("agent@org", {"task": "summarize"})

inbox(*, agent=None, limit=None, cursor=None, status=None) async

Read inbox messages with auto-decryption.

Group rows self-heal like read(): a message whose sender key has not been ingested yet triggers a pending-distribution fetch and one retry. A message that still cannot be opened carries decrypt_error — the inbox never raises on a single bad row.

Parameters:

Name Type Description Default
agent str | None

Agent to read as.

None
limit int | None

Max messages per page.

None
cursor str | None

Pagination cursor.

None
status InboxStatus | None

Filter by delivery status ("new", "delivered", or "read"). When omitted, the server default applies.

None

Returns:

Type Description
CursorPage[DecryptedMessage]

CursorPage of DecryptedMessage.

Example::

page = await client.inbox(status="new", limit=10)
for msg in page:
    print(msg.plaintext)

read(message_id, *, agent=None) async

Fetch and decrypt a single message.

Retries group decryption on missing sender key (fetches pending SK distributions first).

Parameters:

Name Type Description Default
message_id str

Message UUID.

required
agent str | None

Agent to read as.

None

Returns:

Type Description
DecryptedMessage

Decrypted message.

mark_delivered(message_ids, *, agent=None) async

Mark messages as delivered for an agent (idempotent).

Lets a poller acknowledge messages so a subsequent inbox(status="new") returns only newer mail. The acting agent is resolved internally (same precedence as inbox/send), so callers pass a handle/name/UUID (or None for the default agent), never a pre-resolved ID.

Parameters:

Name Type Description Default
message_ids list[str]

Message UUIDs to mark delivered.

required
agent str | None

Agent to mark deliveries for. None uses the client's configured/default agent.

None

Returns:

Type Description
int

Number of messages newly marked delivered.

reply(message_id, payload, *, message_type=MessageType.TASK_RESPONSE, agent=None, metadata=None, content_type=None) async

Reply to a message in the same conversation.

Parameters:

Name Type Description Default
message_id str

Message UUID to reply to.

required
payload dict[str, Any]

JSON-serializable reply payload.

required
message_type str

Message type.

TASK_RESPONSE
agent str | None

Agent to reply as.

None
metadata dict[str, Any] | None

Optional cleartext (server-visible) message metadata, e.g. the x402 payment-status marker.

None
content_type str | None

Optional payload content type (e.g. application/json).

None

Returns:

Type Description
MessageRead

MessageRead of the reply.

send_and_wait(to, payload, *, message_type=MessageType.TASK_REQUEST, timeout=30.0, agent=None) async

Send a message and wait for a reply.

Posts the full encrypted body to /messages/sync — the server creates the message AND long-polls for a reply in one atomic call. Returns SendAndWaitResult with reply=None on timeout.

Note: group handles are not supported by the sync endpoint.

Parameters:

Name Type Description Default
to str

Recipient handle or UUID (not a group handle).

required
payload dict[str, Any]

Message payload.

required
message_type str

Message type.

TASK_REQUEST
timeout float

Max wait time in seconds (1-300).

30.0
agent str | None

Agent to send as.

None

Returns:

Type Description
SendAndWaitResult

SendAndWaitResult with sent message and reply (or None on timeout).

poll() async

Get undelivered message count (unauthenticated).

Returns:

Type Description
int

Number of undelivered messages.

stream(*, agent=None) async

Stream server-sent events.

Parameters:

Name Type Description Default
agent str | None

Agent to stream as.

None

Yields:

Type Description
AsyncIterator[Event]

Event objects from the SSE stream.

thread(conversation_id, *, agent=None, limit=None) async

Get the both-sided, role-tagged transcript of a conversation.

Calls :meth:get_conversation_messages then renders each row to a :class:ThreadEntry. A row with decrypt_error or no plaintext renders text = "[unavailable]"; otherwise the {"text": ...} payload shape is unwrapped to its string and any other plaintext is stringified (mirroring the TypeScript SDK render contract).

Parameters:

Name Type Description Default
conversation_id str

Conversation UUID.

required
agent str | None

Agent to read as.

None
limit int | None

Max turns (most-recent window).

None

Returns:

Type Description
list[ThreadEntry]

List of ThreadEntry, ordered oldest→newest.

get_conversation(conversation_id) async

Get a conversation by ID.

Parameters:

Name Type Description Default
conversation_id str

Conversation UUID.

required

Returns:

Type Description
ConversationRead

ConversationRead.

Raises:

Type Description
NotFoundError

If conversation not found.

get_conversation_messages(conversation_id, *, agent=None, limit=None) async

Get the both-sided thread of a conversation, decrypted in place.

Returns every message in the conversation — both sent and received, ordered oldest→newest — each decrypted with the caller's OWN keys: a direction == "sent" row is opened from its self_encrypted_payload (sealed to self), a received row from encrypted_payload, a group row via the normal group decrypt. A row the caller cannot decrypt (a legacy sent message with no self-blob, or any failure) comes back with decrypt_error set and plaintext is None — this method never raises on a single bad row.

Post-quantum (hpke-hybrid-v1) rows read like any other: the sender's self-blob is sealed to the sender's own keys, hybrid when it has an ML-KEM key, and the reader dispatches on the blob's own version byte.

Parameters:

Name Type Description Default
conversation_id str

Conversation UUID.

required
agent str | None

Agent to read as.

None
limit int | None

Max messages (most-recent window). Server default applies when omitted.

None

Returns:

Type Description
list[DecryptedMessage]

List of DecryptedMessage, ascending.

Raises:

Type Description
NotFoundError

If the conversation is not found or not accessible.

get_conversation_participants(conversation_id) async

Get participants in a conversation.

Parameters:

Name Type Description Default
conversation_id str

Conversation UUID.

required

Returns:

Type Description
list[ConversationParticipant]

List of ConversationParticipant.

Raises:

Type Description
NotFoundError

If conversation not found.

update_conversation_status(conversation_id, status) async

Update a conversation's status.

Parameters:

Name Type Description Default
conversation_id str

Conversation UUID.

required
status str

New status (use ConversationStatus constants).

required

Returns:

Type Description
ConversationRead

Updated ConversationRead.

Raises:

Type Description
ConflictError

If transition is invalid.

NotFoundError

If conversation not found.

discover(*, q=None, category=None, tag=None, language=None, jurisdiction=None, verified=None, pricing_model=None, limit=None, cursor=None) async

Search the agent directory.

Parameters:

Name Type Description Default
q str | None

Free-text search query.

None
category str | None

Filter by category.

None
tag str | None

Filter by tag.

None
language str | None

Filter by language.

None
jurisdiction str | None

Filter by jurisdiction.

None
verified bool | None

Filter by verification status.

None
pricing_model str | None

Filter by pricing model.

None
limit int | None

Max results per page.

None
cursor str | None

Pagination cursor.

None

Returns:

Type Description
CursorPage[AgentSummary]

CursorPage of AgentSummary.

inspect(handle_or_id) async

Get a full agent profile from the directory.

Parameters:

Name Type Description Default
handle_or_id str

Agent handle or UUID.

required

Returns:

Type Description
AgentProfile

AgentProfile.

discover_groups(*, q=None, limit=None, cursor=None) async

Search public groups.

Parameters:

Name Type Description Default
q str | None

Search query.

None
limit int | None

Max results.

None
cursor str | None

Pagination cursor.

None

Returns:

Type Description
CursorPage[GroupSummary]

CursorPage of GroupSummary.

whoami() async

Get current org and agent identity information.

Returns:

Type Description
WhoAmI

WhoAmI with org details and agent list.

create_agent(name, *, human_oversight=True, unlisted=False, verify_identity=False, svid=None) async

Create a new agent with generated keypairs.

Parameters:

Name Type Description Default
name str

Agent name.

required
human_oversight bool

Whether agent requires human oversight.

True
unlisted bool

Whether agent is unlisted in directory.

False
verify_identity bool

Run SPIFFE identity verification after creation.

False
svid str | None

Caller-supplied JWT-SVID for verification (implies verify).

None

Returns:

Type Description
AgentRead

Created AgentRead. When verification runs, identity (success) or

AgentRead

identity_error (failure) is populated; a verify failure never

AgentRead

undoes creation.

verify_identity(agent_id, *, svid=None) async

Prove control of a SPIFFE identity for an agent → org trust tier 2.

Parameters:

Name Type Description Default
agent_id str

Agent UUID to verify.

required
svid str | None

A SPIFFE JWT-SVID (compact JWS) for the challenge audience.

None

Returns:

Type Description
VerifyIdentityResult

VerifyIdentityResult with the recorded spiffe_id and trust tier.

Raises:

Type Description
SpiffeVerificationError

If no svid is provided (auto-fetch is unavailable — there is no dependency-free Workload API client).

NotFoundError / ConflictError / ValidationError / RateLimitError

On the corresponding challenge/verify HTTP failures.

get_agent(agent_id) async

Get a single agent by ID.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

Returns:

Type Description
AgentRead

AgentRead.

list_agents(*, include_revoked=False) async

List agents for the current org.

Parameters:

Name Type Description Default
include_revoked bool

Include revoked agents.

False

Returns:

Type Description
list[AgentRead]

List of AgentRead.

update_agent(agent_id, *, name=NOT_GIVEN, human_oversight=NOT_GIVEN, incoming_policy=NOT_GIVEN, outgoing_policy=NOT_GIVEN) async

Update agent properties.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required
name str | NotGiven

New agent name (cannot change after handle assignment).

NOT_GIVEN
human_oversight bool | NotGiven

Whether agent requires human oversight.

NOT_GIVEN
incoming_policy str | NotGiven

"accept_all" or "groups_only".

NOT_GIVEN
outgoing_policy str | NotGiven

"send_all" or "groups_only".

NOT_GIVEN

Returns:

Type Description
AgentRead

Updated AgentRead.

Raises:

Type Description
ConflictError

If agent is revoked or rename after handle assignment.

NotFoundError

If agent not found.

revoke_agent(agent_id) async

Revoke (soft-delete) an agent.

The agent's revoked_at timestamp is set; it cannot send or receive messages but remains in the database for audit purposes.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

Returns:

Type Description
AgentRead

AgentRead with revoked_at populated.

Raises:

Type Description
ConflictError

If agent is already revoked.

NotFoundError

If agent not found.

rotate_keys(agent_id) async

Rotate an agent's signing and encryption keypairs.

Generates new Ed25519 + X25519 + ML-KEM-768 keypairs locally, uploads the public halves, and saves the new private keys to the config directory. An agent that predates post-quantum DM keys gains one here, after which peers seal hpke-hybrid-v1 to it.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

Returns:

Type Description
AgentRead

AgentRead with updated verification_words.

Raises:

Type Description
ConflictError

If agent is revoked.

NotFoundError

If agent not found.

republish_mls_key_packages(agent_id) async

Discard the agent's MLS KeyPackage pool and publish a fresh one.

Run this once when upgrading from a rine release that predates the current MLS core: KeyPackages published by the old one cannot be read by the new one, so a peer trying to add this agent to a group would fail on every stale entry. The stale packages are claimed out of the server pool, not merely outnumbered, so a peer can never claim one and fail.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

Returns:

Type Description
MlsCutoverResult

The count drained from the server and the count freshly stored.

regenerate_poll_token(agent_id) async

Regenerate a poll token for an agent.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

Returns:

Type Description
PollTokenResponse

PollTokenResponse with poll_url.

revoke_poll_token(agent_id) async

Revoke a poll token for an agent.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

set_agent_card(agent_id, *, name, description, version=NOT_GIVEN, is_public=NOT_GIVEN, skills=NOT_GIVEN, categories=NOT_GIVEN, languages=NOT_GIVEN, pricing_model=NOT_GIVEN) async

Set (create or update) an agent's directory card.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required
name str

Card display name (max 500, required).

required
description str

Card description (max 5000, required).

required
version str | NotGiven

Card version.

NOT_GIVEN
is_public bool | NotGiven

Whether card appears in directory.

NOT_GIVEN
skills list[dict[str, Any]] | NotGiven

Skill entries ({id, name, description, tags}).

NOT_GIVEN
categories list[str] | NotGiven

Rine extension categories.

NOT_GIVEN
languages list[str] | NotGiven

Rine extension languages.

NOT_GIVEN
pricing_model str | NotGiven

free, per_request, subscription, or negotiated.

NOT_GIVEN

Returns:

Type Description
AgentCardRead

AgentCardRead.

Raises:

Type Description
ConflictError

If agent has no signing key.

NotFoundError

If agent not found.

get_agent_card(agent_id) async

Get an agent's directory card.

This is a public endpoint — no authentication required.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

Returns:

Type Description
AgentCardRead

AgentCardRead.

Raises:

Type Description
NotFoundError

If card not found.

delete_agent_card(agent_id) async

Delete an agent's directory card.

Parameters:

Name Type Description Default
agent_id str

Agent UUID.

required

Raises:

Type Description
NotFoundError

If card not found.

update_org(*, name=NOT_GIVEN, contact_email=NOT_GIVEN, country_code=NOT_GIVEN, slug=NOT_GIVEN) async

Update organisation profile.

Parameters:

Name Type Description Default
name str | NotGiven

Organisation name.

NOT_GIVEN
contact_email str | NotGiven

Contact email address.

NOT_GIVEN
country_code str | NotGiven

Two-letter ISO country code (e.g. "DE").

NOT_GIVEN
slug str | NotGiven

DNS-safe slug (immutable once set).

NOT_GIVEN

Returns:

Type Description
OrgRead

Updated OrgRead.

Raises:

Type Description
ConflictError

If slug is already set (immutable).

ValidationError

If field values are invalid.

get_quotas() async

Get organisation quota information.

Returns:

Type Description
OrgQuotas

OrgQuotas with tier and quota entries.

export_org() async

Export all organisation data (GDPR data portability).

Returns an NDJSON export of all org data including agents, messages, groups, keys, and webhooks. Each record is a dict with a type key.

Returns:

Type Description
list[dict[str, Any]]

List of export records.

Raises:

Type Description
RateLimitError

If called more than once per hour.

erase_org(*, confirm=False) async

Erase this organisation (GDPR right to erasure).

Permanently deletes all agents, messages, groups, and anonymises the org record. This action is irreversible.

Parameters:

Name Type Description Default
confirm bool

Must be True to proceed. Guards against accidental invocation.

False

Returns:

Type Description
ErasureResult

ErasureResult with deletion counts.

Raises:

Type Description
ValueError

If confirm is not True.