# phonesms.trucopilot.com — SMS Gateway API Base URL: https://phonesms.trucopilot.com A multi-tenant SMS gateway. Android phones running the SMSTruCopilot app push received SMS here and stay connected over a WebSocket. External apps/agents read those messages and send SMS back out through the phones' SIMs. Everything is keyed by an OrgId + SecretKey. ## Auth - Identify with an `OrgId` (3-64 chars: letters, digits, `-`, `_`) and a `SecretKey` (12-50 chars). - The pair is claimed on first use (first /webhook or /websocket call creates it). Reuse the same pair. - Pass the secret in the URL path where shown, OR as the header `X-Secret-Key` (preferred — keeps it out of logs). - 10 failed auth attempts locks an OrgId for 5 minutes. ## REST endpoints ### Health GET /health -> {"status":"ok"} ### Store inbound SMS (used by the phone) POST /webhook body: {"org_id":"ORG","secret_key":"SECRET","messages":[ {"address":"+15551234567","body":"hello","date":1700000000000,"sim_slot":0,"sim_number":"+1555...","id":"123"} ]} (headers X-Org-Id / X-Secret-Key also accepted instead of body fields) -> {"ok":true,"org_id":"ORG","stored":1} ### Get messages GET /messages/{OrgId}/{SecretKey} or GET /messages/{OrgId} with header X-Secret-Key: SECRET query params: ?limit=100 (max 1000) &since_id=0 &direction=in|out &sim=+1555... -> {"org_id":"ORG","count":N,"messages":[{id,direction,address,body,sim_slot,sim_number,status,device_ts,created_at}, ...]} ### Send SMS (always accepted as a queued ticket, then delivered) POST /send/{OrgId} body: {"secret_key":"SECRET","sim":"+1555...","to":"+1999...","body":"hi"} multiple: {"secret_key":"SECRET","sim":"+1555...","messages":[{"to":"+1...","body":"a"},{"to":"+1...","body":"b"}]} `sim` is optional (slot index or SIM number); omit to use the first connected phone. -> {"ok":true,"device_online":true,"queued":1,"results":[{"id":5,"to":"+1999...","status":"sending"}]} Each result `id` is your ticket. Status lifecycle (poll GET /messages?direction=out): queued = accepted, no phone online yet (delivered automatically when a phone reconnects) sending = pushed to the phone, awaiting confirmation sent = phone confirmed; "sent_at" holds the real send time failed = phone reported a failure ### List SIMs GET /sims/{OrgId}/{SecretKey} -> {"online_devices":1,"live_sims":[{slot,number,label,carrier}],"known_sims":[...]} ## WebSocket (the phone's control channel) Connect: wss://phonesms.trucopilot.com/websocket?org_id=ORG&secret_key=SECRET (or connect then send {"type":"auth","org_id":"ORG","secret_key":"SECRET"} as the first message) Phone -> server: {"type":"sims","sims":[{"slot":0,"number":"+1555...","label":"SIM1","carrier":"AT&T"}]} {"type":"inbound","message":{"address":"+1...","body":"...","date":1700000000000,"sim_slot":0}} {"type":"send_result","id":5,"success":true} {"type":"ping"} Server -> phone: {"type":"connected","org_id":"ORG"} {"type":"send_sms","id":5,"to":"+1999...","body":"hi","sim":"+1555..."} {"type":"sims_ack","count":1} / {"type":"inbound_ack","stored":1} / {"type":"pong"} ## Interactive / machine-readable - Swagger UI: https://phonesms.trucopilot.com/docs - OpenAPI JSON: https://phonesms.trucopilot.com/openapi.json - This file: https://phonesms.trucopilot.com/llms.txt ## curl quickstart # store a message (claims the org on first call) curl -X POST https://phonesms.trucopilot.com/webhook -H 'Content-Type: application/json' \ -d '{"org_id":"myorg","secret_key":"my-secret-key-123","messages":[{"address":"+15551112222","body":"hi","date":1700000000000}]}' # read messages curl -H 'X-Secret-Key: my-secret-key-123' https://phonesms.trucopilot.com/messages/myorg # send a message (needs a phone connected via the app) curl -X POST https://phonesms.trucopilot.com/send/myorg -H 'Content-Type: application/json' \ -d '{"secret_key":"my-secret-key-123","to":"+15553334444","body":"sent from API"}'