# Ask for a decision

Pause work for a person’s approval, choice, or reply. Creating a prompt is the beginning of that exchange; use its confirmed server outcome to decide what happens next.

HTML: https://notify.belweave.ai/docs/ask-decision

## Ask and wait in the terminal

Use `notify send ask <prompt>` when later work depends on an answer. Select one of `--approval`, `--yes-no`, or `--text`; ordinary send appearance flags also apply. The example asks whether a package should be held for collection.

```bash
notify send ask "Hold package PKG-42 until tomorrow?" \
  --approval --title "Warehouse desk" --wait --timeout 15m
```

For approval or yes/no, `--live-activity` requests an iOS interactive card (iOS 17+) with `approval`, `shell`, `verdict`, or `signal` style. Native Android receives an ordinary actionable alert for this presentation. The prompt is limited to 240 characters, labels to 1–24 characters, and expiry to eight hours. This presentation accepts no text replies, images, or URLs. Custom primary/secondary labels change displayed verbs; returned actions remain canonical.

```bash
notify send ask "Send the pickup reminder?" \
  --approval --live-activity --style signal \
  --primary-label Send --secondary-label Deny \
  --wait --timeout 15m
```

`--wait` waits for a terminal answer, subject to `--timeout` (by default, the requested prompt expiry: 15 minutes unless changed). `--poll` waits up to 20 seconds. Either wait may time out while the prompt stays pending; neither cancels it. Prompt expiry defaults to 15 minutes and is set separately with `--expires-in`. Resume with `notify interaction wait <id>`; that standalone command defaults to a 60-second wait. A pending `interaction get` can exit successfully, so do not treat a successful read as approval.

```json
{
  "interaction": {
    "id": "int_7MFuml-SqoUmpPLo",
    "kind": "reply",
    "status": "replied",
    "response": "Leave it at the desk",
    "respondedAt": "2026-10-12T11:54:17.927Z"
  },
  "accepted": 1,
  "timedOut": false
}
```

## Ask from a webhook

For a webhook question, include `response` next to the message. Choose `approval` for Approve/Deny, `yes_no` for Yes/No, or `text` for a typed reply. The warehouse example asks whether a delayed parcel should be held.

```json
{
  "title": "Warehouse pickup",
  "body": "Hold package PKG-42 for collection?",
  "response": {
    "type": "approval",
    "expiresInSeconds": 900,
    "correlationId": "pickup-42",
    "callback": {
      "url": "https://warehouse.example.com/notify-answer",
      "token": "callback_token_placeholder_32_chars"
    }
  }
}
```

| Field | Type | Description |
| --- | --- | --- |
| `type` | string, required | Required choice of `approval`, `yes_no`, or `text`. |
| `expiresInSeconds` | integer | Answer window: integer from 30 to 86,400 seconds; default 900. |
| `correlationId` | string | Optional sender-defined correlation value, maximum 100 characters, echoed in the callback. |
| `callback.url` | string | Classic answered-callback destination. Requires public HTTPS and a paired callback token. |
| `callback.token` | string | Classic callback bearer credential and HMAC key, 16–512 characters. |
| `callback.target` | object | Connector destination `{ connectorId, route, path }`; use instead of callback.url/token. See the connector receiver guide. |
| `webhookId` | string | Account-owned saved reply webhook ID (`whk_…`) selected for this interaction, in addition to applicable service/account defaults. |

A successful question send adds pending-response metadata. Store the event ID and deadline; acceptance of the push does not authorize the requested action.

```json
{
  "ok": true,
  "eventId": "evt_example_pickup",
  "delivered": 1,
  "response": { "status": "pending", "expiresAt": "2026-10-11T18:19:04.000Z" }
}
```

## Read or cancel the outcome

Read the saved event ID to find a webhook question’s current outcome. To stop accepting answers before its deadline, POST to `/cancel`. Canceling the question and withdrawing the displayed notification are separate operations.

```bash
curl https://notify.belweave.ai/hooks/whk_your_token/events/evt_example_pickup

curl -X POST https://notify.belweave.ai/hooks/whk_your_token/events/evt_example_pickup/cancel
```

```json
{
  "ok": true,
  "event": {
    "id": "evt_example_pickup",
    "response": {
      "status": "approved",
      "action": "approve",
      "text": null,
      "correlationId": "pickup-42",
      "respondedAt": "2026-10-11T18:06:52.000Z",
      "expiresAt": "2026-10-11T18:19:04.000Z"
    }
  }
}
```

- `pending` means no settled answer. Terminal statuses are `approved`, `denied`, `yes`, `no`, `replied`, `expired`, and `canceled`.
- A text answer has `action: "reply"` and a populated `text`; choice answers carry the selected canonical action and `text: null`.
- Reading an overdue pending question settles it as `expired`.
- Only pending responses can be canceled; other states return `404` from cancel. The webhook can only inspect events belonging to its service.

> An offline client may queue an answer locally. Queued is not server-confirmed: another valid answer, expiry, cancellation, or removal of access can win before synchronization. Continue automation only after the server reports the required terminal outcome.

## Route agent permission requests

Permission hooks let Claude Code, Codex, and OpenCode V1/V2 pause for a person’s decision. A grant requires an explicit, valid approval and applies once. Denial, timeout, invalid input, authentication or network errors, and no accepted or queued device delivery all deny the request. Queued delivery keeps waiting; only a server-confirmed explicit approval grants permission.

```bash
notify permissions setup all
notify permissions doctor
```

Keep `notifications:send`, `interactions:create`, and `interactions:read` on the connection. The default login includes them; narrowed logins must request them. Setup and `permissions doctor` check scopes before installing hooks.

Install one integration with `permissions setup claude`, `codex`, or `opencode`. Codex also requires review/trust in `/hooks`. On macOS, OpenCode setup installs its V1 plugin and V2 background connector. `notify permissions uninstall all` removes Notify-owned hooks and services.

The phone receives a limited request summary: agent name, permission/tool name, project-directory basename, and resource count. It does not receive raw commands, patches, prompts, file contents, URLs, environment values, transcript paths, or absolute paths.
