Trial and browser calls
Ten live minutes, then Personal $20/175. Trial is not a SKU.
TelDev is an AI Voice Call Platform. Verify a number, then place a live voice call in the browser. The homepage dialer talks only to /v1. It never sees TELNYX_API_KEY.
Identity is SMS OTP on an E.164. No email, no account signup. Minutes are bound to that number on the server — not a cookie, not localStorage. The page may keep a trl_ token in sessionStorage so a refresh can call GET /v1/trial; remaining seconds always come from /v1.
Contract
| Method | Path | Auth | Body / notes |
| --- | --- | --- | --- |
| POST | /v1/trial/otp | none | { "phone" } → { object: "trial_otp", phone, expires_in, mock, code? } |
| POST | /v1/trial/verify | none | { "phone", "code" } → trial view + token (trl_…) |
| GET | /v1/trial | trl_ | Remaining seconds, plan (null during the 10, then personal unless they picked Build / Ship / Scale), calls_allowed, ip_warning |
| GET | /v1/plans | none | Personal / Build / Ship / Scale only. checkout is null. |
| POST | /v1/billing/subscribe | trl_ | { "plan": "personal" \| "build" \| "ship" \| "scale" } mock attach |
| POST | /v1/webrtc/token | trl_ or API key | { object: "webrtc_token", token, mock, expires_at } |
| POST | /v1/calls | trl_ or API key | action: create (default), answer, hangup, mute, unmute, hold, unhold |
| GET | /v1/sessions/:id/events | trl_ or API key | SSE stub of session events |
OTP
- Live (
TELNYX_API_KEYset): TelDev sends SMS fromnum_demo. The code is not in the JSON. - Mock (no API key): no Telnyx hop. Code is
000000and is returned ascodeso a visitor can finish verify.
The first 10 live minutes are one-time on a verified E.164. A new browser or a new E.164 does not mint another 10. Same number, second verify, returns the existing remaining / plan. There is no Free $0 SKU.
Ten live minutes, then Personal
remaining_seconds starts at 600. plan is null during those 10 minutes — trial is not a SKU.
After those 10, TelDev attaches Personal ($20) unless the identity already picked Build, Ship, or Scale. Checkout is not in /v1. POST /v1/billing/subscribe attaches a published plan; landing on Personal after the 10 is the same attach.
TelDev fails closed on POST /v1/calls create / answer when remaining is 0 (trial with no grant, or a published included pack that is empty) → 402 trial_exhausted or 402 included_exhausted. Hangup / mute / hold still work.
The page disables Call when calls_allowed is false or remaining is 0. 402 / 403 from /v1 are authoritative.
Personal is the default sell for a single developer. After landing they can still pick Build or Ship.
Plans
Published monthly plans only. There is no Free $0 SKU.
| id | Name | Amount | Included live minutes |
| --- | --- | --- | --- |
| personal | Personal | $20 | 175 (then Telnyx list plus spread — no public per-minute rate) |
| build | Build | $49 | none published |
| ship | Ship | $199 | none published |
| scale | Scale | $599 | none published |
Usage is Telnyx list plus TelDev spread. There is no public per-minute rate.
On Personal, /v1 tracks the 175-minute included pool. When that pool is gone, included_exhausted is true and /v1 fails closed on the next live create / answer. The published overage is still Telnyx list plus spread — /v1 does not invent a per-minute price. Build / Ship / Scale have no included pack; once attached they may place live calls (usage at list plus spread).
Example usage totals ($323.30 billed / $56.70 carrier) are a Ship example, not a fifth plan.
WebRTC vs session events
stream_url(wss://rt.teldev.bot/sessions/ses_…) is session events, stubbed. Same-origin stub:GET /v1/sessions/:id/eventsandGET /v1/events?after=.- Audio is a separate Telnyx WebRTC peer.
/v1mints the client token. Test keys and missingTELNYX_API_KEYreturnmock: true; the browser must not openrtc.telnyx.com. - The browser client does not call
/v1/numbersor/v1/messages.