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
triggersEnabledmust betrue. 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.mentionsEnabledset totrue(defaultfalse). 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.
| What | Status |
|---|---|
| Slack DMs: workspace-rule reminders, approval cards, notices, brokered questions | Live |
| Jira comments, proposed by an agent rule on a ticket event | Live, needs a Jira writer and a workspace rule |
| Slack channel posts | Not reachable yet: nothing creates a channel destination |
| GitHub pull request comments | Not reachable yet |
| Linear comments | Not reachable yet |
| Notion comments and appends | Not 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 tool | Destination | Default rung | Highest rung | Body limit (characters) | Reachable today |
|---|---|---|---|---|---|
send_dm | A linked workspace member in Slack | auto | auto | 12,000 | Yes |
reply_on_ticket | A Jira issue | ask | auto | 30,000 | Yes, through an agent rule |
post_to_channel | A Slack channel or thread | ask | ask | 12,000 | No |
reply_on_github_issue | A GitHub pull request (pull requests only) | ask | auto | 60,000 | No |
reply_on_linear_issue | A Linear issue | ask | ask | 30,000 | No |
notion_comment | A Notion page | ask | auto | 6,000 | No |
notion_append | A Notion page | ask | ask | 30,000 | No |
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:
- Take the most specific policy row: a rule (
subscriptionscope) beats a project, and a project beats the whole workspace (org). With no row, use the tool's default rung. - Cap it at the tool's highest rung. Setting a rung above the highest is refused with a 400, not silently lowered.
- Force it down to
askwhen any of these hold: text from someone outside the workspace is in play, the message involves a low-assurance identity, or the writer is aconnector_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:
- 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.
- 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. - Edit lets you reply in the thread with new wording. nima replaces the card with a new one.
- 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. - 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.
| Limit | Value |
|---|---|
| Replies per ticket | 3 per rolling 24 hours (a policy row can set 0 to 1,000) |
| Cooldown between replies on one ticket | 600 seconds (a policy row can set 0 to 604,800) |
| Actions per workspace | 200 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 fire | 1 |
| Send attempts | 5, with exponential backoff |
| Approval window and question window | 24 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:
| State | Meaning |
|---|---|
proposed | nima created the action |
awaiting_approval | An approval card is out; expires after 24 hours |
approved | Approved or set to auto; queued to send |
executing | Being sent |
succeeded | Sent |
failed | Not sent after retries, or a permanent error |
uncertain | The send may or may not have happened; not retried |
discarded | An approver discarded it |
expired | Nobody approved within 24 hours |
refused | A 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_writerand the approval tools are in Outbound MCP tools. Admin tools need an API key with theintegrations:writescope, which only an owner or admin can create, with/nima mcp-key integrationsin Slack. - Routes: Actions, Action policies and Writers.
- Workspace switches: Workspace settings.
- Jira specifics: Jira. Slack specifics: Slack.
Watches, inbox and reminders
How to have nima tell you when something changes (watches, the inbox, the 09:00 digest) and how one-time Slack reminders work.
People, identities and mentions
How nima links people's Slack, Jira, Linear and Notion accounts to workspace members, and how that decides who it answers, messages and tags.