What's new — MCP server now in beta

The human-approval API for AI agents.

Pause your agent and text a human in one API call, instead of building a webhook server, response page, and SMS infrastructure yourself.

No credit card required.

agent.py Python · 8 lines
import requests

resp = requests.post(
    "https://api.pausepoint.dev/v1/pause",
    headers={"Authorization": "Bearer pp_live_..."},
    json={
        "recipient":      "+1 (312) 847-1928",
        "channel":        "sms",
        "message":        "Wire $8,400 to Meridian?",
        "options":        ["Approve", "Reject"],
        "timeout_hours":  4,
        "timeout_default": "Reject",
    }
)
# returns immediately
pause_id = resp.json()["pause_id"]
Messages 14:07 · now
PausePoint: Wire $8,400 to Meridian Supplies?

Tap to respond — pausepoint.dev/r/a1b2
Approve Reject

"Replaced our entire approval webhook stack."

ME Marcus Eriksson · Synthetic Labs

"Dropped into our LangGraph workflow on a Thursday afternoon."

JW James Woo · Arcadian Finance

"The hosted response page is the part I didn't know I needed."

PN Priya Nair · Fieldwork Systems

Works with

LangChain LangGraph CrewAI OpenAI Agents AutoGen n8n Dify
The shortcut

Build it yourself in weeks, or call PausePoint in minutes.

Every team building AI agents that need human approval ends up writing the same infrastructure — Twilio setup, webhook handlers, response pages, token auth, state storage, timeout workers. Every time.

Without PausePoint ~400 lines · 2–4 weeks · per agent
# Twilio client, Redis for state, JWT for tokens...
from twilio.rest import Client
import hmac, hashlib, redis, jwt, json
from time import time

client = Client(TWILIO_SID, TWILIO_TOKEN)
r = redis.Redis()

@app.post("/send-approval")
async def send_approval(req):
    token = jwt.encode({"id": req.pause_id,
                        "exp": time() + 14400}, SECRET)
    r.setex(f"pause:{token}", 14400,
             json.dumps({"id": req.pause_id, "used": False}))
    client.messages.create(
        body=f"{req.message}\n\nRespond: {BASE_URL}/r/{token}",
        from_=TWILIO_FROM, to=req.recipient
    )

@app.post("/respond/{token}")
async def handle_response(token, choice):
    data = r.get(f"pause:{token}")
    if not data: raise HTTPException(400)
    pause = json.loads(data)
    if pause["used"]: raise HTTPException(410)
    db.execute("UPDATE pauses SET status='responded'...")
    requests.post(pause["webhook"], json={"choice": choice})
    r.delete(f"pause:{token}")
    # Plus: response page HTML, timeout jobs, audit log,
    # HMAC verification, replay protection, retry logic...
With PausePoint 8 lines · 5 minutes · any agent
import requests

resp = requests.post(
    "https://api.pausepoint.dev/v1/pause",
    headers={"Authorization": "Bearer pp_live_..."},
    json={
        "recipient":      "+1 (312) 847-1928",
        "channel":        "sms",
        "message":        "Wire $8,400 to Meridian?",
        "options":        ["Approve", "Reject"],
        "timeout_default": "Reject",
    }
)
pause_id = resp.json()["pause_id"]
# PausePoint handles everything else.
Average integration 8 lines From requests.post to a human approving on their phone.
Median SMS deliver < 4 sec From API call to text on the recipient's lock screen.
Frameworks supported All of them Pure REST. If your code can POST, it works.
How it works

Four steps. Zero infrastructure.

Your agent calls one endpoint. PausePoint handles delivery, the response page, timeouts, retries, and the audit log.

01

POST one request

Your agent sends the recipient, message, and options. PausePoint returns a pause_id immediately. Block-poll or use a webhook — your choice.

POST /v1/pausereturns immediately
02

SMS in seconds

A text arrives with a tap-to-respond link. No app. No login. Works globally. Email and Slack on paid plans.

SMS Email Slack
03

One tap. Done.

A mobile-optimized page shows the question and choices. Under 10 seconds from SMS to decision. No technical knowledge needed.

04

Agent resumes

Poll GET /v1/pause/{id} or receive a signed webhook. Every event written to the immutable audit log automatically.

Integration ready

Use the language you love.

Pure REST. No SDK to install. Drop into any agent codebase in eight lines.

curl -X POST https://api.pausepoint.dev/v1/pause \
  -H "Authorization: Bearer pp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "recipient":       "+1 (312) 847-1928",
    "channel":         "sms",
    "message":         "Deploy build #4712 to production?",
    "options":         ["Deploy", "Abort"],
    "timeout_default": "Abort"
  }'

# Then poll for the response, or register a webhook.
curl https://api.pausepoint.dev/v1/pause/$PAUSE_ID \
  -H "Authorization: Bearer pp_live_..."
import requests, time

resp = requests.post(
    "https://api.pausepoint.dev/v1/pause",
    headers={"Authorization": "Bearer pp_live_..."},
    json={
        "recipient":       "+1 (312) 847-1928",
        "channel":         "sms",
        "message":         "Deploy build #4712 to production?",
        "options":         ["Deploy", "Abort"],
        "timeout_default": "Abort",
    },
)
pause_id = resp.json()["pause_id"]

while True:
    r = requests.get(
        f"https://api.pausepoint.dev/v1/pause/{pause_id}",
        headers={"Authorization": "Bearer pp_live_..."},
    ).json()
    if r["status"] == "responded":
        decision = r["response_choice"]
        break
    time.sleep(5)
const resp = await fetch("https://api.pausepoint.dev/v1/pause", {
  method: "POST",
  headers: {
    "Authorization": "Bearer pp_live_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    recipient:       "+1 (312) 847-1928",
    channel:         "sms",
    message:         "Deploy build #4712 to production?",
    options:         ["Deploy", "Abort"],
    timeout_default: "Abort",
  }),
});
const { pause_id } = await resp.json();

// Poll, or register a webhook for the response event.
while (true) {
  const r = await fetch(`https://api.pausepoint.dev/v1/pause/${pause_id}`, {
    headers: { "Authorization": "Bearer pp_live_..." },
  }).then(r => r.json());
  if (r.status === "responded") return r.response_choice;
  await new Promise(r => setTimeout(r, 5000));
}
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
)

body, _ := json.Marshal(map[string]interface{}{
    "recipient":       "+1 (312) 847-1928",
    "channel":         "sms",
    "message":         "Deploy build #4712 to production?",
    "options":         []string{"Deploy", "Abort"},
    "timeout_default": "Abort",
})

req, _ := http.NewRequest("POST",
    "https://api.pausepoint.dev/v1/pause",
    bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer pp_live_...")
req.Header.Set("Content-Type", "application/json")

resp, _ := http.DefaultClient.Do(req)
// Decode pause_id from resp.Body, then poll or register webhook.
require "net/http"
require "json"

uri = URI("https://api.pausepoint.dev/v1/pause")
req = Net::HTTP::Post.new(uri,
  "Authorization" => "Bearer pp_live_...",
  "Content-Type"  => "application/json")

req.body = {
  recipient:       "+1 (312) 847-1928",
  channel:         "sms",
  message:         "Deploy build #4712 to production?",
  options:         ["Deploy", "Abort"],
  timeout_default: "Abort",
}.to_json

resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
pause_id = JSON.parse(resp.body).fetch("pause_id")

# Then poll GET /v1/pause/:id, or register a webhook.
What you get

Everything your agent needs to pause safely.

SMS-first delivery, signed webhooks, immutable audit logs, and a hosted response page — out of the box.

Pure REST. No SDK required.

LangChain, LangGraph, CrewAI, AutoGen, n8n, or raw requests.post(). If it can make an HTTP call, it works. No decorator, no import, no framework constraint.

POST https://api.pausepoint.dev/v1/pause

SMS-first delivery

Average SMS response time is under 3 minutes. Email and Slack available on paid plans. WhatsApp on Enterprise.

SMS Email Slack WhatsApp · soon

Timeout fallbacks

Set timeout_default and your agent continues automatically if no one responds. 24h on Free, up to 30 days on Pro.

Hosted response page

The human taps a link, sees your question, taps their answer. No login, no app, nothing to build or host on your side.

Wire $8,400 to Meridian?
Approve
Reject

Immutable audit log

Every pause, response, timeout, and cancellation recorded with timestamp, actor, and full context. Query, export, and satisfy EU AI Act Article 14 compliance requirements automatically.

EU AI Act ready SOC 2 in progress GDPR compliant
pause.createddeveloper14:00:01
pause.respondedhuman14:07:34
pause.webhook_deliveredsystem14:07:35

Signed webhooks

Receive pause.responded, pause.timed_out, pause.cancelled events. HMAC-SHA256 signed with replay protection built in.

Claude Code · Claude Desktop

Use PausePoint from inside Claude.

The PausePoint MCP server lets Claude Code create pause requests, poll for responses, and query audit logs — without writing any HTTP code. Add it to your mcp.json and it's available as a native tool.

create_pause_request
poll_pause_request
cancel_pause_request
list_pause_requests
get_audit_log
Read the MCP docs
~/.claude/mcp.json
{
  "servers": {
    "pausepoint": {
      "command": "python",
      "args": ["mcp_server/server.py"],
      "env": {
        "PAUSEPOINT_API_KEY": "pp_live_..."
      }
    }
  }
}
Example Claude prompt

"Before proceeding, use PausePoint to ask +1 (312) 847-1928 via SMS whether to approve the $500 transfer. Options: Approve, Reject. Default to Reject after 2 hours."

Use cases

When automation needs a signature.

Four shipped patterns. Four irreversible decisions a human still owns.

01 / Finance
"Wire $8,400 to Meridian Supplies?"

The finance agent prepares a transfer. Before any money moves, PausePoint texts the CFO. One tap approves. No response in 4 hours — automatically rejected and logged.

02 / Outreach
"Send this campaign to 340 contacts?"

The outreach agent drafts and stages a campaign. The founder reviews on their phone and approves before a single message is sent. Brand safety by default.

03 / Data ops
"Purge 14,000 records from staging?"

The cleanup agent identifies deletion candidates. Before the query runs, it texts the data engineer. Irreversible actions stay reversible until a human says go.

04 / Legal
"Sign and submit this contract?"

The contract agent prepares an agreement. Legal reviews the summary on their phone. One tap, and the signing workflow proceeds. Compliance logged automatically.

Customer story
We were reinventing the Twilio webhook loop on every new agent deployment. PausePoint replaced 400 lines of infrastructure with one API call — in a Thursday afternoon.
ME
Marcus Eriksson
Senior Engineer, Synthetic Labs
Pricing

Start free. Scale when it counts.

Free
$0 /month

Build and test. No credit card.

Start free
  • 50 pauses / month
  • SMS only
  • 24-hour max timeout
  • Audit log access
Pro
$99 /month

High-volume with Slack and priority support.

Get started
  • 5,000 pauses / month
  • SMS Email Slack
  • 30-day max timeout
  • Webhooks + retry logic
  • Priority support

Need unlimited pauses, WhatsApp, or an SLA? Talk to us about Enterprise →

FAQ

Straight answers.

Still have questions? Email us — we reply within a business day.

Do I need a Twilio account?

No. PausePoint handles all SMS delivery infrastructure. You pass a phone number and message — we handle the rest. You never touch Twilio credentials.

What happens if the human doesn't respond?

Set timeout_default in your pause request (e.g. "Reject") and that option fires automatically when the timeout expires. If no default is set, the pause becomes timed_out — your agent handles it however it wants.

Does this work with LangGraph, CrewAI, AutoGen?

Yes — PausePoint is a pure REST API. requests.post() is all you need. No SDK to install, no decorator, no framework constraint. See the integrations section above for copy-pasteable code.

How is the response link secured?

Each pause generates a unique HMAC-SHA256 signed token encoding the pause ID and expiry timestamp. It is single-use — the moment a human submits, the token is permanently invalidated. API keys are stored as SHA-256 hashes, never in plain text.

Can my agent receive the decision via webhook instead of polling?

Yes. Register a webhook endpoint when you create the pause and receive a signed pause.responded event the instant the human taps their answer. HMAC-SHA256 signature included in every payload. Retry logic is built in.

Is there a Python SDK?

Not yet — today it's a pure REST API. A Python SDK wrapping the polling loop into a single blocking call is on the roadmap. The REST API will never be deprecated.

Start with PausePoint

Your agent, with a human in the loop.

Start with 50 free pauses per month. No credit card. No infrastructure to run. First pause in under two minutes.