Skip to main content
Triage agent A discussion is where users talk to your agent inside Plain. Any user can click Ask Sidekick from any page, pick your agent, and send a message. Plain sends you a webhook, and your agent replies through the API. Discussions are completely internal and not visible to your customers. A discussion can be attached to a thread or be standalone. When a user starts a discussion from a thread, the webhook payload will include discussion.threadId to tell you which thread the discussion is linked to. Discussions can also be started from a workflow. In the workflow builder you can pick your agent as well.

High-level flow

  1. A user starts a discussion with your agent.
  2. Plain sends discussion.message_created to your webhook target.
  3. Your agent sets the discussion status to IN_PROGRESS, does its work, posts a reply, and sets IDLE.
  4. Your agent can then log its tool calls as well as ask for a user’s approval. See tool calls for more info.

Permissions

For working with discussions, your machine user’s API key must have the following permissions:
  • threadDiscussion:read and threadDiscussion:edit to read discussions, report status, request approvals, resolve or reopen discussions
  • threadDiscussionMessage:create and threadDiscussionMessage:edit to post messages to the discussion
  • thread:read and customer:read if the agent needs to read the linked thread

Webhooks

Subscribe your webhook target to these events:

Decide whether to answer

discussion.message_created fires for every discussion in the workspace, including your own replies. Answer only when all of these are true: Load your machine user once at startup and deduplicate on message.id:
In the webhook payload, message.markdown is what the user wrote. message.workspaceFiles lists any files they attached. You must respond with a status code of 200 before your agent starts work so that Plain doesn’t retry the webhook delivery.

Replying

You can use the sendDiscussionMessage mutation to reply to the discussion using markdown. This also marks the discussion as having unread messages within the Plain app.

Updating the discussion status

Set the discussion’s agent status to IN_PROGRESS when a turn starts and IDLE when it ends. If the turn fails, post the error as a message first, then set IDLE.
Asking for a tool call approval will automatically update the discussion status to TOOL_CALL_APPROVAL_PENDING.When a discussion is pending a tool call approval, you cannot change its status manually.

Stop when asked

A user can stop your agent mid-turn. Plain sends discussion.turn_stop_requested with the discussion to stop. Cancel the model call, post what you have if useful, and set the discussion status to IDLE. The discussion stays open for the next message.

Resolve the discussion

You can use changeThreadDiscussionStatus to resolve a discussion when the user needs nothing further, or set the status to OPEN to reopen it.

Replying to customers on behalf of the user

A user in a discussion can ask your agent to message the customer. The agent can do this by calling the replyToThread mutation. By default the reply is from the machine user. To send it as the user who asked, add them to the API key’s impersonation allow list and pass impersonation.asUser. See reply as a user. The allow list belongs to the API key, not the machine user. Open the API key from the machine user’s page and, under Impersonation, add who it may reply as:
  • individual team members
  • everyone holding a built-in role: Owner, Admin, or Support
  • everyone holding a custom role