Skip to main content
The Conversation Hub SDK (@runflow-ai/sdk/conversation) lets an agent operate inside the Conversation Hub — Runflow’s WhatsApp/human-in-the-loop console. Answer the conversation that triggered the agent, show a typing indicator, send templates and media, open a ticket for a human attendant, and keep the contact’s profile (tags, internal notes) up to date.
Requires the Conversation Hub feature enabled for your tenant. All calls are authenticated with a tenant-scoped API key; conversations from other tenants return 404 (existence is never leaked).

Setup

One click: with the feature enabled, open Credentials in the Runflow portal, pick Conversation Hub in the credential type dropdown and hit Generate key. The key is minted by the Conversation Hub, stored encrypted as the conversation-api-key credential, and never shown in the browser. Re-running it rotates the key (the previous one is revoked instantly). That’s it — the SDK resolves the key from the credentials store on the first call and talks to the production Conversation Hub by default. Just import the default instance:

Getting the conversation

fromTrigger

The conversation that activated this agent — the standard path for triggered agents.

byId

Lazy handle for a known conversation id.

byPhone

Proactive sends — resolve (or create) the thread from a phone number.
Proactive flows (cron jobs, external events) usually only know the phone number:
byPhone matches every stored phone variant (with/without +, with/without the Brazilian mobile 9).

Sending messages

Safe retries (idempotency)

Every send accepts an idempotencyKey. Retrying with the same key returns the original message instead of double-sending — the reply carries deduplicated: true.

Typing indicator & read receipts

Both anchor on the contact’s last inbound message (Meta requires it), so they return 422 on a conversation with no inbound yet. The typing bubble auto-dismisses in ~25s or when your reply arrives — call typing() right when the trigger fires, before slow work.

Handoff & resolution

transfer opens a ticket in the attendants’ queue and flips the conversation out of AI mode. resolve closes the case.

Choosing where to hand off

conversation.directory is a read-only view of your workspace’s service structure — the departments and the attendants (human agents) registered in the Conversation Hub. Use it when the agent needs to decide the transfer target at runtime instead of hard-coding a department name.
Each attendant carries two live signals: status (presence: online / busy / away / offline) and load (how many human conversations they are handling at this moment). A common pattern — route to the least-busy online attendant, falling back to the department queue when nobody is available:

Legacy sync agents

Agents invoked through the direct execution endpoint (no HTTP trigger) answer with the reply helper — intent drives the handoff:

Contacts, tags & notes

Agent-authored notes have no human author — the portal shows the agentName label (default: Agente AI).

Error handling

API failures throw ConversationApiError with status, a typed code when available, and the raw body:
Common codes: OUTSIDE_24H_WINDOW (free-form send outside Meta’s window), CONTACT_NOT_FOUND / CONVERSATION_NOT_FOUND (byPhone without create), CONNECTION_NOT_FOUND (unknown connectionId).

API surface