Agent Quickstart — Cursor, Claude Code, Codex
What a coding agent needs to wire Dial SMS in under 5 minutes using dial_live_* keys.
Agent Quickstart
Instructions for coding agents (Cursor, Claude Code, Codex) to onboard a human repo with Dial SMS using DIAL_API_KEY — no Privy session refresh.
One-click opens Cursor with a prefilled Payphone setup prompt — review and confirm. Or copy the full setup command for your terminal.
Full setup: pnpm cursor:agent:setup -- --api-key dial_live_… --phone +1… — plugin, Plugin MCP, rules, skills, env, operator policy, and pool test SMS. Then MCP → dial → Login. Skip --with-project-mcp unless you need Installed MCP too.
1. Read machine surfaces first
Fetch these URLs before writing integration code:
| Resource | URL |
|---|---|
| Onboarding manifest | https://payphone.wtf/.well-known/dial-onboarding.json |
| Full API (plain text) | https://payphone.wtf/llms-full.txt |
| Skill playbook | https://payphone.wtf/skill.md |
| Human quickstart | https://payphone.wtf/docs/onboarding/quickstart |
The manifest includes scopes, routes, self-setup steps, and catalog prices — generated from the same sources as production.
2. Install the skill / plugin
Cursor: use Install in Cursor above, or run from a Payphone clone:
pnpm cursor:agent:setup -- --api-key dial_live_… --phone +1…Add --with-project-mcp only if you need Installed MCP in addition to the plugin (usually skip — duplicate dial entries). See Agent stack.
| Tool | Command |
|---|---|
| Cursor | pnpm cursor:agent:setup or Connect → Skill |
| Claude Code | /plugin install dial@dial-wtf |
| Codex / OpenCode | Copy .agents/skills/dial/SKILL.md into your project |
Optional thin wrapper: .agents/skills/dial-quickstart/SKILL.md — points at manifest + this page.
3. Required environment
The human must set (or you prompt them to set):
export DIAL_API_URL=https://payphone.wtf
export DIAL_API_KEY=dial_live_…
export DIAL_NOTIFY_PHONE=+1… # operator recipient
# export DIAL_OWNED_LINE_E164=+1… # only when sending from your leased lineOmit DIAL_OWNED_LINE_E164 for pool send (default). Set it to your active leased E.164 for owned-line send (two-way). Workspace fallback: ownedLineE164 in .payphone/operator-notifications.json.
Default onboarding scopes: account:read, sms:send, numbers:read, numbers:buy.
4. Self-setup loop
Run these steps in order (same as dashboard onboarding blob):
- Read
https://payphone.wtf/skill.mdand/.well-known/dial-onboarding.json→ checksmsSendModes - Verify key:
GET /api/v1/accountwithAuthorization: Bearer $DIAL_API_KEY - Test SMS (pool, default):
POST /api/v1/sms/sendwith{ "to": "<user E.164>", "message": "…" }— outbound-only; user cannot reply by SMS - Verify credits:
GET /api/v1/account/credits - Dedicated line (when SMS replies needed):
POST /api/v1/numbers/buy/us→ pollGET /api/v1/numbers/buy/status?jobId=…→ send viaPOST /api/v1/numbers/mine/sendwith{ phoneNumber, to, message } - Confirm delivery before saying "done" — see below
Source of truth for step text: buildAgentSetupBlob() in apps/web/lib/onboarding-agent-blob.ts (dashboard copies this for users).
5. Copy-paste prompt for humans
Give your user this block to paste into their agent:
Read https://payphone.wtf/llms-full.txt and
https://payphone.wtf/.well-known/dial-onboarding.json.
Wire deploy-failure SMS alerts into this repo using DIAL_API_KEY
(credits mode). Use POST /api/v1/sms/send for one-way pool alerts.
Buy a dedicated line and use POST /api/v1/numbers/mine/send only if
the user must reply by SMS. Confirm pool sends via GET /api/v1/account/history;
confirm dedicated sends via GET /api/v1/sms/inbox.6. Delivery is not HTTP 200
POST /api/v1/sms/send → 200 means the message was queued, not that Cheogram delivered it.
Pool vs inbox: GET /api/v1/sms/inbox applies to dedicated lines only. Pool sends have no inbound path — do not expect SMS replies on pool numbers.
Before telling the user "SMS works end-to-end":
- Pool: Poll
messages.statusorGET /api/v1/account/history - Dedicated line:
GET /api/v1/sms/inbox(requiresnumbers:read) or dashboard threads
7. Example: GitHub Actions failure SMS
- name: SMS on failure
if: failure()
env:
DIAL_API_URL: https://payphone.wtf
DIAL_API_KEY: ${{ secrets.DIAL_API_KEY }}
run: |
curl -sf -X POST "$DIAL_API_URL/api/v1/sms/send" \
-H "Authorization: Bearer $DIAL_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"to\":\"${{ secrets.ALERT_PHONE }}\",\"message\":\"CI failed: ${{ github.workflow }}\"}"Links
- Agent stack — plugin, MCP, skills, REST alone or together
- Human quickstart
- API keys & scopes
- Connect hub
- MCP setup