Skip to API reference
SelfSMSPortal
REST API · JSON

Build against the gateway without guessing.

The contract for account access, one-time phone pairing, idempotent queueing, leased delivery, suppression, billing, and administration.

Base URL
https://your-sms-host.example/api/v1
JSON
Responses
HTTPS
Production
1
Job per claim

Access model

Use the narrowest credential

Context Credential Lifecycle
Account clientAuthorization: Bearer <JWT>Account session
Web dashboardSecure auth_token cookieExact-Origin protected
Initial pairingPairing-GrantShort-lived, one use
Paired phoneDevice-UUID + Device-TokenRevoked on device removal
Stripe webhookStripe-SignatureVerified 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

One-time pairing, then device-scoped access

  1. Step 1

    Create a grant

    An authenticated browser calls POST /pairing/grants only when the phone is ready.

  2. Step 2

    Scan or paste

    Flutter validates the server origin and presents Pairing-Grant.

  3. Step 3

    Register once

    POST /device/register consumes the grant and returns the device token once.

  4. Step 4

    Relay safely

    The phone uses its UUID/token for heartbeat, one-job claims, and status updates.

Queue, do not promise delivery

A safe single-message request

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
}

Contract essentials

  • One leading plus and 7–15 normalized digits; letters and extensions fail validation.
  • One SMS segment: 160 GSM-7 units or 70 UTF-16 units, after any plan footer.
  • Marketing and every bulk batch require explicit consent confirmation; suppression is checked before creation.
  • The phone claims one job at a time and reports with its current lease token.

Endpoint catalogue

Account and billing

9 endpoints
POST
/api/v1/register

Create a free or pending paid account.

Public
POST
/api/v1/login

Create a user session and account JWT.

Public
POST
/api/v1/verify_payment

Verify an owned Stripe Checkout Session.

Account
POST
/api/v1/billing/add-payment

Start or resume Stripe-hosted Checkout.

Account
POST
/api/v1/billing/portal

Open the owned Stripe Billing Portal.

Account
POST
/api/v1/billing/cancel

Confirm cancellation before removing paid access.

Account
POST
/api/v1/user/settings

Update username and/or password.

Account
POST
/api/v1/user/delete

Confirm billing cleanup, then delete the account.

Account
POST
/api/v1/stripe/webhook

Apply verified, deduplicated billing events.

Stripe signature

Endpoint catalogue

Pairing and devices

5 endpoints
POST
/api/v1/pairing/grants

Create a short-lived, one-time phone pairing grant.

Account
POST
/api/v1/pairing/validate

Validate a grant without consuming it.

Pairing grant
POST
/api/v1/device/register

Pair a new phone or refresh its own registration.

Pairing grant or device
POST
/api/v1/device/heartbeat

Refresh online and SIM inventory state.

Device
POST
/api/v1/device/delete

Revoke a paired phone.

Account

Endpoint catalogue

SMS and history

6 endpoints
POST
/api/v1/sms/send

Queue one policy-compliant, one-segment SMS.

Account or device
POST
/api/v1/sms/send-bulk

Validate and queue a consent-confirmed batch.

Account or device
GET
/api/v1/sms/pending?limit=1

Claim one leased job for carrier handoff.

Device
POST
/api/v1/sms/update

Acknowledge one claimed job outcome.

Device
POST
/api/v1/sms/update-batch

Acknowledge several outcomes independently.

Device
GET
/api/v1/info

Read safe account, device, job, and batch state.

Account or device

Endpoint catalogue

Suppression and administration

6 endpoints
GET
/api/v1/suppression

List canonical suppressed recipients.

Account
POST
/api/v1/suppression/add

Add up to 100 suppression entries.

Account
POST
/api/v1/suppression/remove

Remove up to 100 suppression entries.

Account
POST
/api/v1/admin/login

Create an administrator session.

Public, rate-limited
GET
/api/v1/admin/users

List safe account summaries.

Administrator
POST
/api/v1/admin/user/update

Audit suspension or entitlement changes.

Administrator

Failures are part of the contract

Common status codes

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.

Need the detailed request shapes?

Download the maintained Markdown reference for examples, lifecycle rules, suppression, billing safeguards, pagination, and operational limits.

Download reference