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.
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.
notify send ask "Hold package PKG-42 until tomorrow?" \
--approval --title "Warehouse desk" --wait --timeout 15mFor 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.
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.
{
"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.
{
"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.
{
"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.
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{
"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"
}
}
}pendingmeans no settled answer. Terminal statuses areapproved,denied,yes,no,replied,expired, andcanceled.- A text answer has
action: "reply"and a populatedtext; choice answers carry the selected canonical action andtext: null. - Reading an overdue pending question settles it as
expired. - Only pending responses can be canceled; other states return
404from cancel. The webhook can only inspect events belonging to its service.
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.
notify permissions setup all
notify permissions doctorKeep 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.
Send an update
Send a useful message, file it into the inbox, and give the recipient a clear next step. Webhook and terminal examples below describe the same package-pickup workflow.
Track work
Keep one task’s current stage visible as work progresses. iOS uses ActivityKit on capable builds; native Android uses an ordinary ongoing progress notification through the same API.