message.comDevelopers

Authentication

Every authenticated request carries a bearer token in the Authorization header. The API supports two token types today (workspace JWTs for the dashboard) and a third on the roadmap (API keys for headless integrations). A small public surface is anonymous.

Two-and-a-half modes

The auth model is intentionally narrow:

  • Workspace JWT. Issued at POST /api/v1/auth/login. Used by the dashboard at app.message.com and by any client acting as a logged-in agent. Live
  • API key. Workspace-scoped bearer string formatted msg_live_* or msg_test_*. Used by backend services that need to act without an agent session. Planned
  • Public widget config. Anonymous GET keyed by a public embedId. Used by the in-browser widget bundle to fetch its appearance and feature flags. No auth required. Live

Workspace JWT

The dashboard authenticates against POST /api/v1/auth/login with an email and password. The response includes a signed JSON Web Token (RFC 7519) that you pass on subsequent requests in the Authorization header.

Authorization header
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Issuing a token

cURL · login
curl -X POST 'https://app.message.com/api/v1/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "[email protected]",
    "password": "your-password"
  }'
200 OK
{
  "token": "eyJhbGci...",
  "expiresAt": "2026-05-20T15:30:00Z",
  "agent": {
    "id": "uuid",
    "email": "[email protected]",
    "role": "admin",
    "workspaceId": "uuid"
  }
}

Token properties

  • Lifetime. Seven days. Long enough to keep the dashboard logged in across a working week, short enough to limit blast radius if a token leaks.
  • Stateless verification. Tokens are verified with the server-side signing secret on every request. No database lookup per request.
  • Revocable. POST /api/v1/auth/logout bumps the agent's tokenVersion counter. Every live token signed with the old counter is rejected on next use.
  • Workspace-scoped. The token carries the workspace ID it was issued for. Cross-workspace API calls return 404.

Never embed a workspace JWT in client-side code that ships to users. Tokens issued via /auth/login are agent credentials. For browser code, use the widget bundle and the anonymous embedId instead.

API key (planned)

Planned API keys are committed for Q2 2026. They will be issued from Settings → Integrations → API keys, scoped to a workspace, and rotatable from the same screen. Format: msg_live_<base64> for production, msg_test_<base64> for sandbox traffic.

Authorization header (planned)
Authorization: Bearer msg_live_abc123def456...

The API-key endpoint is on the roadmap and the shape may change before launch. For now, mint a workspace JWT via /auth/login and refresh it as needed.

Planned scopes

Each key will carry a scope set. Today the planned scopes mirror the existing role surface:

  • read:conversations, write:conversations
  • read:visitors, write:visitors
  • read:reports
  • write:tickets (used by inbound CRM sync flows)

Public widget config

The widget bundle that ships to the browser is anonymous. On load it issues a single unauthenticated GET to fetch its config (appearance, welcome message, business hours, feature flags). The only identifier on this request is the public embedId embedded in the install snippet.

cURL · widget config
curl 'https://app.message.com/api/v1/widget-config?embedId=YOUR_EMBED_ID'

The response contains zero personal data and zero workspace internals. Treat the embedId as public; treat the workspace JWT and the (planned) API key as secret.

Required request headers

For every authenticated REST call:

HTTP headers
Authorization: Bearer <token>
Content-Type: application/json
Accept: application/json

Optional but recommended on mutations: Idempotency-Key (any unique string per intent). See REST API conventions.

Auth-related errors

CodeWhen
401 unauthorizedMissing, malformed, or expired token.
401 token_revokedToken signed with a stale tokenVersion (you logged out elsewhere).
403 forbiddenAuthenticated but the role or channel scope does not allow this action.
404 not_foundResource belongs to a different workspace. We do not leak existence.
429 rate_limitedAuth endpoints have strict per-IP and per-email caps (see Rate limits).

Security checklist

  • Never log full bearer tokens. If you must log for debugging, prefix-and-suffix only.
  • Rotate workspace JWTs by calling /auth/logout on every device after a password change.
  • Pin TLS to TLS 1.3 (RFC 8446) or higher; we negotiate it by default.
  • For server-to-server traffic, prefer (planned) API keys over agent JWTs. Agent JWTs are revocable per agent, which is the wrong granularity for a long-running daemon.
  • If you suspect a token leak: POST /auth/logout on the affected agent, then issue a fresh one with /auth/login.