/api/v1/register
Create a free or pending paid account.
The contract for account access, one-time phone pairing, idempotent queueing, leased delivery, suppression, billing, and administration.
https://your-sms-host.example/api/v1
Access model
| Context | Credential | Lifecycle |
|---|---|---|
| Account client | Authorization: Bearer <JWT> | Account session |
| Web dashboard | Secure auth_token cookie | Exact-Origin protected |
| Initial pairing | Pairing-Grant | Short-lived, one use |
| Paired phone | Device-UUID + Device-Token | Revoked on device removal |
| Stripe webhook | Stripe-Signature | Verified per request |
Never log credentials, pairing or lease tokens, SMS content, recipient numbers, or Stripe Checkout URLs. Cookie-authenticated mutations require the exact configured application origin.
Phone setup
An authenticated browser calls POST /pairing/grants only when the phone is ready.
Flutter validates the server origin and presents Pairing-Grant.
POST /device/register consumes the grant and returns the device token once.
The phone uses its UUID/token for heartbeat, one-job claims, and status updates.
Queue, do not promise delivery
Send a fresh idempotency key. The response confirms durable queueing; the phone later claims the job with a lease.
POST /sms/send
Authorization: Bearer <JWT>
Idempotency-Key: unique-request-key
{
"phone": "+447700900123",
"message": "Your appointment is confirmed.",
"purpose": "transactional",
"consent_confirmed": false,
"fallback_to_any": false
}
Endpoint catalogue
/api/v1/register
Create a free or pending paid account.
/api/v1/login
Create a user session and account JWT.
/api/v1/verify_payment
Verify an owned Stripe Checkout Session.
/api/v1/billing/add-payment
Start or resume Stripe-hosted Checkout.
/api/v1/billing/portal
Open the owned Stripe Billing Portal.
/api/v1/billing/cancel
Confirm cancellation before removing paid access.
/api/v1/user/settings
Update username and/or password.
/api/v1/user/delete
Confirm billing cleanup, then delete the account.
/api/v1/stripe/webhook
Apply verified, deduplicated billing events.
Endpoint catalogue
/api/v1/pairing/grants
Create a short-lived, one-time phone pairing grant.
/api/v1/pairing/validate
Validate a grant without consuming it.
/api/v1/device/register
Pair a new phone or refresh its own registration.
/api/v1/device/heartbeat
Refresh online and SIM inventory state.
/api/v1/device/delete
Revoke a paired phone.
Endpoint catalogue
/api/v1/sms/send
Queue one policy-compliant, one-segment SMS.
/api/v1/sms/send-bulk
Validate and queue a consent-confirmed batch.
/api/v1/sms/pending?limit=1
Claim one leased job for carrier handoff.
/api/v1/sms/update
Acknowledge one claimed job outcome.
/api/v1/sms/update-batch
Acknowledge several outcomes independently.
/api/v1/info
Read safe account, device, job, and batch state.
Endpoint catalogue
/api/v1/suppression
List canonical suppressed recipients.
/api/v1/suppression/add
Add up to 100 suppression entries.
/api/v1/suppression/remove
Remove up to 100 suppression entries.
/api/v1/admin/login
Create an administrator session.
/api/v1/admin/users
List safe account summaries.
/api/v1/admin/user/update
Audit suspension or entitlement changes.
Failures are part of the contract
200
Accepted
Inspect the JSON result; queued is not delivered.
400
Invalid input
Correct the request before retrying.
401 / 403
Authentication or policy
Refresh credentials or resolve origin, plan, consent, or route policy.
409 / 410
State conflict or gone
Reconcile idempotency/lease state or pair a removed device again.
413 / 422
Size or application error
Reduce or correct the valid-shaped request.
429
Rate limited
Honor Retry-After and back off.
500 / 502 / 503
Server or upstream unavailable
Retry only safe/idempotent operations with bounded backoff.
Download the maintained Markdown reference for examples, lifecycle rules, suppression, billing safeguards, pagination, and operational limits.