docs
Concepts

Outbound actions and approvals

When and how nima writes into Slack, Jira, Linear and GitHub on someone's behalf, how approvals, action policies and safety limits work, and what is live today.

An outbound action is anything nima writes into another tool for a person: a Slack DM, a comment on a Jira ticket, a question to a teammate. Every outbound action passes through one gate. nima proposes the action, checks the policy, cleans the text, then either asks a human to approve it or sends it, and records a receipt.

Availability: off until a workspace owner or admin turns it on. Outbound actions are available on the platform, but each workspace starts with them off. An owner or admin turns them on with PATCH /organizations/settings and the body { "dispatchEnabled": true }, from a signed-in session, or asks the nima team. There is no control for it in the admin panel, and no API key or MCP tool can change it.

Turn outbound actions on for a workspace

Outbound actions stay off for a workspace until an owner or admin sets dispatchEnabled to true in the workspace settings. Members cannot change it. While it is off, nima proposes, approves and sends no outbound actions (workspace-rule reminders, ticket replies, approval cards, brokered questions) and records none. Personal watch notifications, scheduled messages and nima's replies in Slack threads are not outbound actions and keep working.

Turning it on does not switch everything on. Some paths need more:

  • Workspace rules that message people or draft ticket replies also need watches on: the workspace setting triggersEnabled must be true. See Watches and reminders.
  • Jira replies need a Jira writer, a credential nima comments with. An admin connects it through the writer routes in Writers.
  • Mentions of people in messages need dispatch.mentionsEnabled set to true (default false). While it is off, nima writes plain display names and pings nobody.

The outbound switch is checked twice: when nima proposes an action and again just before it sends. An action approved while the switch was on, then sent after it went off, is refused. If you approve through the REST route while the switch is off, the request answers 409 with details.reason set to dispatch_off and the action keeps waiting. An approver the action was routed to can still discard it through the REST route from a signed-in session. An owner or admin who is not one of its approvers cannot. See Workspace settings for the fields.

What nima can send today

Today nima sends Slack DMs and, when an admin has set up the rule and the writer, Jira comments. Everything else exists as code but nothing proposes it yet.

WhatStatus
Slack DMs: workspace-rule reminders, approval cards, notices, brokered questionsLive
Jira comments, proposed by an agent rule on a ticket eventLive, needs a Jira writer and a workspace rule
Slack channel postsNot reachable yet: nothing creates a channel destination
GitHub pull request commentsNot reachable yet
Linear commentsNot reachable yet
Notion comments and appendsNot reachable yet

Writing to Linear, Notion and GitHub is not reachable yet. You can connect a Linear writer, but enabling it does not cause nima to comment on Linear, because no rule or conversation proposes a Linear reply and Linear emits no ticket events into this system. Only Jira produces ticket events: ticket.opened, ticket.assigned and ticket.comment_added.

Effect tools and their limits

Each kind of outbound action is an effect tool with a default rung, a highest allowed rung and a body limit.

Effect toolDestinationDefault rungHighest rungBody limit (characters)Reachable today
send_dmA linked workspace member in Slackautoauto12,000Yes
reply_on_ticketA Jira issueaskauto30,000Yes, through an agent rule
post_to_channelA Slack channel or threadaskask12,000No
reply_on_github_issueA GitHub pull request (pull requests only)askauto60,000No
reply_on_linear_issueA Linear issueaskask30,000No
notion_commentA Notion pageaskauto6,000No
notion_appendA Notion pageaskask30,000No

The GitHub writer holds only the pull request write permission, so a comment on a plain issue would be refused. Not in this build: creating issues, two-way sync, email and Telegram delivery.

Action rungs: never, ask, auto

A rung says how much human approval an outbound action needs: never refuses it, ask holds it until a person approves, and auto sends it without asking.

nima picks the effective rung in this order:

  1. Take the most specific policy row: a rule (subscription scope) beats a project, and a project beats the whole workspace (org). With no row, use the tool's default rung.
  2. Cap it at the tool's highest rung. Setting a rung above the highest is refused with a 400, not silently lowered.
  3. Force it down to ask when any of these hold: text from someone outside the workspace is in play, the message involves a low-assurance identity, or the writer is a connector_fallback.

Ticket replies are stricter. A reply goes auto only when all of these are true: an explicit auto policy row exists, the project is marked internal, and the person who asked is a workspace member with a verified (non-low-assurance) identity. Otherwise it waits for approval. Channel posts never reach auto.

Only owners and admins change rungs, with the set_action_policy tool or PATCH /v1/dispatch/policies. Changes are audited. See Action policies. A tightened policy also applies to actions not yet sent: a never row refuses any of them, even one already approved, and an auto action nobody approved is refused if the rung drops to ask.

Approve an outbound action in Slack

An approval card is a Slack DM from nima that shows the exact text it wants to send and two buttons, Approve and Discard. Nothing goes out until an approver presses Approve.

The card is titled "Approve: nima wants to ..." and says "Nothing goes out until you approve it." It shows:

  • Where the message would go.
  • Who could read it: "Only you", "Members of your workspace", "Your workspace only (project asserted internal)" or "May be visible outside your workspace".
  • Expires: approvals lapse after 24 hours.
  • The question or comment being answered, and the exact text nima would send in a quote block, with every link in the message.

If nima had to shorten the message itself, the card says so and the quoted text is exactly what will be sent. The card preview is capped at 9,000 characters; if the card could not show the whole message, it says so and points to GET /v1/dispatch/actions/{id} (or the get_action tool) for the full text.

After you press a button, nima rewrites the card in place to "Approved by <name>" or "Discarded". If outbound actions are off for the workspace, pressing Approve or Discard on the card does nothing and the action keeps waiting until it expires. If the writer account nima posts with is disconnected or turned off, pressing Approve shows you a private note that nothing was sent and the action stays waiting.

Who can approve an outbound action

For a ticket reply, the approvers are the rule owner and, when the spec is linked to the ticket, the spec owner, provided that person is a linked, verified member. All approvers must still be live workspace members. If none is left, the action is refused. A workspace with no Slack install gets no card.

Approving with an API key or an OAuth token needs the actions:approve scope. No API key and no OAuth client can hold that scope today, so approve_action, get_action, list_pending_actions and discard_action are unreachable for keys. Approvals happen on the Slack card, or through the REST routes from a signed-in session. The tools are documented in Outbound MCP tools and the routes in Actions.

Ask a teammate through nima (brokered questions)

A brokered question is a question nima asks another person in a Slack DM on your behalf, after you approve the exact wording. You start one from Slack (a mention of nima or a DM) or from nima's own assistant, never over MCP or with an API key.

How it works:

  1. In Slack you write something like "ask Dana about the export deadline". nima can address the owner of a spec, the assignee or reporter of a ticket you mentioned, or teammates you @-mentioned (up to five are offered per message). The recipient must be a linked workspace member and cannot be you.
  2. nima rewrites the question in its own words (1 to 1,000 characters) and posts a card in your thread: "I'd ask <name> in a Slack DM, on your behalf. This is exactly what they would read." The buttons are Approve, Edit and Discard.
  3. Edit lets you reply in the thread with new wording. nima replaces the card with a new one.
  4. On approval, the recipient gets a DM ending "nima, on behalf of <you>": "<you> is working on something and asked me to check one thing with you." They answer in that thread.
  5. The answer comes back to your original thread, and nima records it as a signal attributed to the recipient.

One open question exists per topic per recipient, and a repeat ask folds into it. A question expires after 24 hours. If it does, you get one DM saying the person has not answered and nima will not chase it. There is no automatic follow-up. If the recipient replies stop, nima stops sending questions from you to that person and tells you so.

The question needs dispatchEnabled on. Without it, nima refuses at once.

On behalf of: how nima signs what it sends

Every message nima sends names the person it acts for, so a reader can tell who asked and trace it to a record.

  • Slack DMs end with the line nima, on behalf of <person> · ref <id8>.
  • Jira comments end with a footer nima, on behalf of <person> · ref <id8>, and carry a hidden comment property that nima uses to ignore its own comments.
  • Linear, Notion and GitHub messages carry the same footer text. GitHub adds a hidden marker.
  • Messages nima writes itself, such as approval cards and digests, are signed plain nima.

The ref is the first eight characters of the action id. It ties the message to its audit row. For a workspace rule, the person is the rule's creator, and nima checks again at send time that they still hold admin rights. To link a Slack, Jira, Linear or Notion account to a member so mentions resolve, see People and identities.

Safety limits on outbound actions

nima cleans every outbound message and caps how much it can send. These limits apply to every outbound action except approval cards.

LimitValue
Replies per ticket3 per rolling 24 hours (a policy row can set 0 to 1,000)
Cooldown between replies on one ticket600 seconds (a policy row can set 0 to 604,800)
Actions per workspace200 per rolling hour, then refused as cap
Agent run spend$5 per UTC day by default; dispatch.dailyUsdCap accepts 0 to 1,000, and 0 stops agent runs
Actions per rule fire1
Send attempts5, with exponential backoff
Approval window and question window24 hours each

Approval cards are the only exception.

What the content guard changes

The content guard runs on every message before it renders. It redacts secrets and personal data, removes @here, @channel, @everyone and raw user mentions, and refuses messages that contain object ids nima never handed out. Links must use https. For agent runs and brokered questions, a link must point at the nima app, the ticket's own host, or a host that appeared in that run's tool results; any other link refuses the proposal. An agent's first over-long message in a fire is refused once with the limit named, so it can retry. Otherwise an over-long message is cut with a visible truncation marker.

What happens when an outbound send fails

A failure that can be retried is tried up to 5 times in total, with exponential backoff. A permanent or authorization failure ends as failed. When the outcome is unknown, for example a timeout, nima looks for the message it may already have sent. If it finds it, the action is succeeded. If not, the action ends as uncertain and is never retried, so nothing is sent twice. A ticket reply is also dropped if the ticket has since been closed, or if a workspace member has already answered it.

Outbound action states

Each outbound action has one state, and the states are:

StateMeaning
proposednima created the action
awaiting_approvalAn approval card is out; expires after 24 hours
approvedApproved or set to auto; queued to send
executingBeing sent
succeededSent
failedNot sent after retries, or a permanent error
uncertainThe send may or may not have happened; not retried
discardedAn approver discarded it
expiredNobody approved within 24 hours
refusedA gate, policy, cap or content rule stopped it, with a reason

Where to manage outbound actions

An owner or admin manages outbound actions through the REST API and MCP tools, and approvers use the Slack card. The admin panel has no page for approvals or policies.

  • Tools: set_action_policy, assert_project_audience, connect_jira_writer, connect_linear_writer and the approval tools are in Outbound MCP tools. Admin tools need an API key with the integrations:write scope, which only an owner or admin can create, with /nima mcp-key integrations in Slack.
  • Routes: Actions, Action policies and Writers.
  • Workspace switches: Workspace settings.
  • Jira specifics: Jira. Slack specifics: Slack.

On this page