Account lifecycle
An account carries three independent states: status (the business switch you set), the authentication state returned by GET /v1/accounts/{id}/auth, and runtime_status (the live connection). Webhook payloads expose the last two as auth_status and runtime_status — note the REST account object itself has no field named auth_status.
Authentication state machine
pending_authInitial state after account creation; no flow started yet.
awaiting_qr_scanA QR flow is active; auth_payload carries the QR content to render.
awaiting_codeA code flow is active; for WhatsApp the verify_code in auth_payload is entered on the phone.
awaiting_passwordThe provider requires a two-factor password after the code step.
authorizedAuthentication complete. The runtime is started automatically.
failedThe flow failed; last_error carries the reason. Start a new flow to retry.
pending_auth→awaiting_qr_scanPOST /auth/qr/start begins a QR flow.
pending_auth→awaiting_codePOST /auth/start begins a verification-code flow.
awaiting_code→awaiting_passwordThe provider demands a two-factor password.
awaiting_qr_scan→authorizedThe QR scan is confirmed by the provider.
awaiting_code→authorizedThe code (or WhatsApp pairing) is accepted.
awaiting_password→authorizedThe password is accepted.
authorized→pending_authThe provider invalidates the session — an account.auth.required event fires and a new flow is needed.
awaiting_*→failedThe provider reports failure at any waiting step (account.auth.failed event).
awaiting_*→pending_authPOST /auth/cancel abandons the active flow.
Runtime state machine
unknownThe initial state after account creation, and whenever the platform has no fresh report from the provider — call /runtime/refresh to resync.
startingA start is in progress; the provider is bringing the session online.
runningConnected and able to send and receive.
reconnectingThe connection dropped and an automatic or manual reconnect is in progress.
disconnectedThe provider reported the session offline; reconnect or start to recover.
stoppingA stop is in progress.
stoppedNot connected. The state after a stop.
errorThe runtime hit an unrecoverable error; last_error carries the reason.
unknown→startingAutomatic start after authorization succeeds.
stopped→startingAn explicit POST /runtime/start.
starting→runningThe provider session comes online (account.started event).
running→reconnectingThe connection drops, or POST /runtime/reconnect is called.
reconnecting→runningThe connection is re-established.
running→disconnectedThe provider reports the session offline (account.status.updated event).
disconnected→runningPOST /runtime/reconnect or /runtime/start brings it back.
running→stoppingPOST /runtime/stop begins a graceful stop.
stopping→stoppedThe stop completes.
*→errorAn unrecoverable provider error at any point.
*→unknownNo fresh provider report; POST /runtime/refresh resyncs the value.
Notes
- Account.status is yours (a business on/off switch set at creation or via PATCH). The other two are platform-owned and read-only: the auth state via GET /v1/accounts/{id}/auth (its status field), runtime_status on the account object.
- Successful authorization starts the runtime automatically — calling POST /runtime/start afterwards is a harmless no-op.
- While authorized, POST /auth/start, /auth/qr/start, and /auth/session are rejected with 409 account_already_authorized. Call POST /auth/cancel first if you really need a fresh flow.
- An account.auth.required event means the provider invalidated the session: auth falls out of authorized and auth_payload carries the material (such as a new QR) for re-authentication.
- Every runtime change is pushed as an account.status.updated event carrying both auth_status and runtime_status — keep your local copy in sync from the webhook rather than polling.