Documentation menu

Docs/Pause requests

Pause Requests

The pause_request is the core entity in PausePoint. Creating one pauses your agent, sends a notification, and waits for a human response.


Status State Machine#

text
                ┌─────────────────────────────────────────┐
                │               CREATE                      │
                │         POST /v1/pause                   │
                └──────────────┬──────────────────────────┘
                               │
                               ▼
                          ┌─────────┐
                          │ pending │ ◄── polling happens here
                          └────┬────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                 │
              ▼                ▼                 ▼
        ┌──────────┐    ┌───────────┐    ┌───────────┐
        │responded │    │ timed_out │    │ cancelled │
        └──────────┘    └───────────┘    └───────────┘

Once a request leaves pending, it cannot change status again.


Create a Pause Request#

POST /v1/pause

Request Fields#

Field Type Required Default Description
recipient string Yes · Phone (E.164), Telegram chat ID, email address, or Slack webhook URL
channel string Yes · "sms" | "email" | "slack" | "telegram"
message string Yes · The question shown to the human. Max 2000 chars.
options string[] Yes · 2–5 answer choices. e.g. ["Approve", "Reject"]
allow_text_response bool No false Show a freetext note input on the response page
timeout_hours int No 24 Hours before auto-timeout. Capped by plan.
timeout_default string|null No null Option to auto-select on timeout. null = no auto-choice.
metadata object No null Arbitrary key-value data. Returned in webhooks and polls.

Channel-Specific Recipient Formats#

Channel Recipient format Example
sms E.164 phone number "+15550100"
telegram Numeric chat ID (message the bot first to get yours) "123456789"
email Email address "cfo@company.com"
slack Slack incoming webhook URL "https://hooks.slack.com/services/..."

Example · SMS#

bash
curl -X POST https://api.pausepoint.dev/v1/pause \
  -H "Authorization: Bearer $PP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "+15550100",
    "channel": "sms",
    "message": "Your agent wants to send a $340 wire to Acme Corp. Approve?",
    "options": ["Approve", "Reject"],
    "timeout_hours": 4,
    "timeout_default": "Reject",
    "metadata": {"amount": 340, "recipient_name": "Acme Corp"}
  }'

Example · Email#

bash
curl -X POST https://api.pausepoint.dev/v1/pause \
  -H "Authorization: Bearer $PP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "cfo@company.com",
    "channel": "email",
    "message": "The sales agent has drafted a campaign email to 200 leads. Send it?",
    "options": ["Send it", "Edit first", "Cancel"],
    "timeout_hours": 24,
    "timeout_default": "Cancel"
  }'

Example · Slack#

bash
curl -X POST https://api.pausepoint.dev/v1/pause \
  -H "Authorization: Bearer $PP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "https://hooks.slack.com/services/T.../B.../...",
    "channel": "slack",
    "message": "Delete 14,000 stale user records from the test environment?",
    "options": ["Delete", "Keep", "Ask me tomorrow"],
    "timeout_hours": 8
  }'

Wait for the Response#

GET /v1/pause/{pause_id}/wait?timeout=60

The easiest way to get the outcome: a long-poll that blocks until the pause is resolved (responded, timed out, or cancelled), then returns its full state. If nothing has happened after timeout seconds (1 to 120, default 60), it returns the current pending state; call it again to keep waiting.

python
import requests

while True:
    result = requests.get(
        f"https://api.pausepoint.dev/v1/pause/{pause_id}/wait",
        params={"timeout": 120},
        headers={"Authorization": f"Bearer {api_key}"},
        timeout=130,
    ).json()

    if result["status"] != "pending":
        decision = result["response_choice"]  # "Approve", or timeout_default
        break

One request replaces a polling loop, and your agent resumes within about 2 seconds of the person acting.

Poll for Response#

GET /v1/pause/{pause_id}

A single non-blocking status check, if you'd rather manage the loop yourself (or check from a cron job):

python
import requests, time

while True:
    result = requests.get(
        f"https://api.pausepoint.dev/v1/pause/{pause_id}",
        headers={"Authorization": f"Bearer {api_key}"}
    ).json()

    if result["status"] == "responded":
        decision = result["response_choice"]  # "Approve"
        break
    elif result["status"] in ("timed_out", "cancelled"):
        decision = result["response_choice"]  # timeout_default or None
        break

    time.sleep(5)

Response Fields#

Field Type Description
pause_id UUID Unique identifier
status string pending | responded | timed_out | cancelled
response_choice string|null The human's choice (or timeout_default)
response_text string|null Freetext note if allow_text_response was true
response_at ISO timestamp|null When the response was recorded
expires_at ISO timestamp When timeout fires
metadata object|null Whatever you passed in

Metadata Field#

Pass any JSON object in metadata. It is returned unchanged in every poll response and webhook payload. Use it to correlate responses with your internal state:

json
{
  "metadata": {
    "agent_run_id": "run_abc123",
    "customer_id": "cust_9876",
    "amount_usd": 340
  }
}