OpenPhone / Quo Hub
OpenPhone rebranded to Quo in 2025. The API base URL, webhook format, and HMAC signing remain unchanged — only the brand and docs URL changed. This hub covers the SMS and voice channel used primarily by the acquisitions pipeline (CH outreach Stages 1-4), plus inbound call routing. 34 active phone lines. Read this hub before modifying quo-handler-enhanced.js, changing webhook registration, or adjusting acquisitions SMS behavior. Owned by Henry Hill; primary consumer is the acquisitions agent and Aurora orchestrator.
⚠️ A2P 10DLC Cross-Impact Flag
A2P 10DLC repeat-denial on the Twilio channel also affects this channel’s compliance posture. Both Quo/OpenPhone SMS and Twilio SMS share the same TCPA compliance envelope. Until osil-twilio-10dlc-resubmission-2026-05-03 B14 (Henry signoff B14a pending), treat all conversational SMS tiers as operationally constrained. See twilio for the authoritative 10DLC compliance alert.
Quick reference
| Field | Value |
|---|---|
| Vendor | Quo (formerly OpenPhone) — quo.com |
| URL | https://api.openphone.com/v1 (unchanged post-rebrand) |
| KB doc | API · WEBHOOKS · CREDENTIALS |
| Auth method | Authorization: {API_KEY} — raw key, NO Bearer prefix |
| Auth credential | op://Aurora/openphone/api-key |
| Cred-proxy port | n/a (until B1-B6 ratified) |
| Webhook port | :18792 |
| Webhook handler | quo-handler-enhanced (quo-handler-enhanced.js) |
| Webhook auth | ✅ HMAC — HMAC-SHA256(secret, timestamp + "." + body); X-OpenPhone-Signature header |
| Webhook dedup table | processed_webhook_events (24h TTL) |
| Tunnel path (canonical) | https://webhook.reri.co/webhook/openphone · alias: /webhook/quo |
| Tunnel path (fallback) | https://srv1347501.tailb025a7.ts.net/webhook/openphone |
| Outbound API base | https://api.openphone.com/v1 |
| Rate limits | 10 req/s per API key |
| Rate-limit action | 429 → exponential backoff (3 retries), Discord ops alert |
| Active lines | 34 phone numbers |
| LineID requirement | ✅ REQUIRED — every outbound/inbound action must specify phoneNumberId (per feedback_quo_lineid_required) |
| SMS coverage | US + Canada (0.01 + country rate. MMS not supported in API. |
| Webhook registration | ⚠️ Dashboard-managed webhooks ONLY — API webhooks are invisible in dashboard; always register via app UI, not API |
| Process manager | systemd openphone-webhook.service (NOT PM2 — moved off PM2 post-OOM cascade recovery) |
| Cost | $0.01/SMS segment; voice per-minute (see Quo billing) |
| Backup/recovery | REST API backfill: node scripts/openphone-backfill.js --since=YYYY-MM-DD |
| Discord alert channel | ops |
| Staleness monitor | scripts/ops/webhook-staleness-monitor.js — alerts ops if no inbound SMS for >3h during 7am-11pm PT |
| Drift cadence | Weekly (security-audit-funnel.timer) |
| Status | production |
Components
webhooks/quo-handler-enhanced.js— main inbound webhook handler on :18792; routescall.ringing,call.completed,call.summary.completed,call.transcript.completed,message.received,message.delivered,contact.updated,contact.deletedscripts/openphone-backfill.js— REST API backfill for gap recovery; run with--since=YYYY-MM-DDscripts/ops/webhook-staleness-monitor.js— heartbeat monitor; runs every 30 min via cron; staleness log at/tmp/openclaw/webhook-staleness.logsystemd: openphone-webhook.service— process manager (migrated from PM2 during OOM cascade recovery); logs viajournalctl --user -u openphone-webhook- Supabase tables:
openphone_messages,openphone_calls,omni_events— primary write targets from handler
Known limitations (verified 2026-03-10 via live OpenAPI spec)
| Feature | Status | Notes |
|---|---|---|
note.created webhook | ❌ Does not exist | No webhook fires when team member adds an internal note |
| Internal thread read | ❌ API write-only | POST /v1/conversations/{id}/notes works; no GET endpoint |
| Feedback via notes | ⚠️ Playwright only | Reading Henry’s notes requires browser automation (blocked on noVNC login) |
| Feedback channel (interim) | ✅ SMS from Henry’s number | Henry’s number (+16194033648) can send directives via SMS |
message.updated | ❌ Not a webhook event | Delivery status only available via GET /v1/messages |
Unverified fields (NEEDS VERIFICATION)
typefield naming in webhook payload: docs showtype: "callSummary"but subscription event iscall.summary.completed— verify via live testcallRoute+aiHandledfields incall.completedwebhook: may only be available viaGET /v1/calls, not webhook payload — verify via live testcontact.updated/contact.deletedevents: listed in docs but not shown in official Quo webhook docs — verify via live test
How it’s used
- Trigger: Inbound SMS fires
message.receivedwebhook →quo-handler-enhanced.js→ Supabase write + acquisitions agent dispatch - Inbound call:
call.ringing→call.completed→ (optional)call.summary.completed+call.transcript.completed— all routed through handler → OpenClaw gateway → appropriate agent - Outbound: Acquisitions agent calls
POST /v1/messageswithphoneNumberId(required) +to+content— no auto-local-presence (unlike SalesMsg); must specify line explicitly - Agents involved: acquisitions agent (CH outreach SMS), Aurora (orchestration, thread routing), atlas agent (call routing decisions)
- Failure mode: Staleness monitor fires if no inbound event for >3h during business hours → check
journalctl --user -u openphone-webhook --since "1h"+ verify Cloudflare Tunnel status - Backfill on gap:
node scripts/openphone-backfill.js --since=YYYY-MM-DDrecovers missed events via REST API - Success criteria: webhook events arrive at
webhook.reri.co/webhook/openphone→ handler writes toomni_events+ channel-specific table → agent dispatched within 30s
Cross-links
Agents that touch this
- _summary — primary consumer; CH outreach SMS via Quo lines
- _summary — orchestrates thread routing, dispatches to sub-agents
- _summary — call routing decisions;
call.ringinghandler escalation
Skills that invoke this
- acquisitions-outreach — Stage 1 initial CH outreach via Quo SMS lines
- acquisitions-followup — Stage 2-4 follow-up cadence; inbound A-G classifier reads Quo events
Plans that govern this
- osil-twilio-10dlc-resubmission-2026-05-03 — B14 10DLC compliance gating; cross-impacts this channel (see ⚠️ alert above)
- openclaw-fragmentation-fix-2026-05-01 — Phase 8 migration to Cloudflare Tunnel canonical URL (completed 2026-04-21)
- openclaw-self-improvement-layer-2026-05-03 — OSIL conversational SMS tiers dependent on 10DLC resolution
Feedback rules
- feedback_quo_lineid_required — every call to Quo API must include
phoneNumberId; bare calls without line ID will fail or misdirect - feedback_action_gate_violation_repeated — service restarts require explicit Henry auth; do not restart
openphone-webhook.servicewithout confirmation - feedback_aurora_outbound_guardrails — Aurora outbound guardrails apply to Quo-mediated SMS
- feedback_never_use_henry_name — agents must not use Henry’s personal name in any SMS routed through Quo
KB / source docs
- API — full API reference, auth, rate limits, endpoint inventory
- WEBHOOKS — event types, HMAC signing, payload schemas, staleness monitor, backfill pattern
- CREDENTIALS — API key location, rotation procedure
System maps
- vm-integrations-overview — full integration topology
- sms-inbound-flow — inbound SMS routing diagram
- voice-call-routing — call routing diagram (forward-ref; may not exist yet)
Related: SMS/Carrier compliance cluster
- salesmsg — primary blast channel;
?secret=auth (NOT HMAC) - openphone-quo — this hub — acquisitions SMS + voice
- twilio — voice anchor; ⚠️ A2P 10DLC repeat-denial active — see osil-twilio-10dlc-resubmission-2026-05-03 B14 (Henry signoff B14a pending). TCPA risk uncapped; gates ALL OSIL conversational SMS tiers.
- compliance-gates — 5-gate pre-send enforcement shared across all three channels
Related: Webhook/tunnel cluster
- cloudflare — tunnel + WAF; canonical URL
webhook.reri.co; FUNNEL-REGISTRY.md is authoritative - salesmsg — sibling handler on :18793
- twilio — sibling handler on :18797; voice fallback path
Related: Voice subsystem cluster
Quo/OpenPhone handles inbound/outbound voice calls alongside Twilio. Both channels share the same TCPA/10DLC compliance envelope.
- twilio — primary voice infrastructure; HMAC-SHA1 auth; 10DLC anchor
- openphone-quo — this hub — Quo voice events (call.ringing, call.completed, summaries, transcripts)
- livekit-deferred — real-time voice/video layer; deferred to OSIL Phase 6 (B10); not operational; do not build against until nemoclaw-audit-2026-05-03 B10 ships
Open issues / TODOs
- Verify
typefield naming in live webhook payload (callSummaryvscall.summary.completed) via live call test - Verify
callRoute+aiHandledfields are present incall.completedwebhook payload (or backfill-only) - Verify
contact.updated/contact.deletedwebhook events fire in practice - Confirm
feedback_quo_lineid_requiredis enforced in ALL call sites inquo-handler-enhanced.jsand all skills that POST to Quo API - Add Quo lines to cred-proxy rotation when B1-B6 ratified (see 1password)
- B14 Henry signoff (10DLC resubmission) — track in osil-twilio-10dlc-resubmission-2026-05-03
Recent activity
- 2026-05-03: hub created (W1-S2)
- 2026-04-21: migrated to Cloudflare Tunnel canonical URL
webhook.reri.co(Phase 8 complete) - 2026-04-13: WEBHOOKS.md last updated; confirmed HMAC signing pattern