Skip to content

HTTP endpoints

Besides gRPC and gRPC-Web, the backend answers a short, fixed list of plain HTTP routes on the same port. None of them is a data API. Campaigns, content, leads, and everything else are gRPC only.

RouteAuthPurpose
GET /healthNoneAlways 200. Body: {"status":"ok","model_ready":<bool>,"port":<int>}
GET /auth/configNone{"google_client_id":"…","password_auth":<bool>} for the login screen
POST /auth/googleNone (it is the sign-in)Exchanges a Google ID token for a PULSE session. Same JSON shape as Login.
POST /auth/refreshRefresh tokenExchanges a refresh token for a new pair in the same session. Refused once the session is signed out.
/creatives/<name>, /media/<name>The owner’s session, or a server-signed URLGenerated media, decrypted from the sealed store
GET /podcast/feed.xmlNone, on purposeThe podcast RSS feed that podcast platforms poll. Needs PULSE_PUBLIC_BASE_URL.
POST /voice/webrtc/offerSessionForwards a WebRTC offer to the calling agent (CALLING_AGENT_URL). 503 when that is not set.
POST /voice/transcribeSessionRaw PCM in, {"text":"…"} out, via Voxtral
GET /.well-known/agent-card.jsonNoneThe A2A agent card
/a2aSession (bearer header only)A2A JSON-RPC. See Calling the API.
POST /twilio/messageTwilio signatureInbound WhatsApp and SMS
anything elseNoneThe Flutter web app, when PULSE_WEB_DIR is set

Requests with gRPC-Web content types go to the gRPC server before any of these routes are checked.