User State
User state is versioned JSON state scoped by account, project, environment, and the signed-in end user. Each end-user bearer token can read and write only its own state.
Use it for per-user preferences, saved settings, progress, and other data that belongs to one signed-in user. Do not use it for secrets or for data that must be shared across users.
Most developers should use the SDK instead of calling these endpoints directly.
End-User Routes
text
GET /v1/{accountId}/projects/{slug}/user-state/{env}
PATCH /v1/{accountId}/projects/{slug}/user-state/{env}These routes accept Authorization: Bearer <end-user-token>.
A GET returns 200 with { version, state } and an ETag header when state exists, and 204 with no body when the user has no state yet.
Write Semantics
- User state must be a JSON object.
PATCHis the only write route for user state; there is noPUT. Writes take the sameIf-Match/If-None-Matchpreconditions as public state, with the same412and400outcomes, including the rule that sending both headers always returns412. The rules are stated once under Public State - Write Semantics.- Successful writes return
200withversionandstateonly; unlike public state, the response carries nocommentorstateSizeBytes. PATCHexpects anopsarray of JSON Patch operations and uses the same operation set as public-statePATCH. See Patch rejection codes for the failure semantics.- The state size limit and the oversize
PATCHresponse are the same as for public state; see Public State - Write Semantics.
Developer Routes
Developers can inspect and remove end-user state through an admin surface at /v1/{accountId}/projects/{slug}/user-states:
text
GET /v1/{accountId}/projects/{slug}/user-states/{env}
GET /v1/{accountId}/projects/{slug}/user-states/{env}/{endUserId}
DELETE /v1/{accountId}/projects/{slug}/user-states/{endUserId}All three routes require Authorization: Bearer <developer-token>; API keys and end-user tokens are rejected.
The list route is paginated, newest first. It accepts limit (defaults to 50; values outside 1-50 are silently clamped into that range) and an opaque cursor taken from the previous response's cursor field. It returns 200 with { items, cursor, hasMore }, where each item carries endUserId, version, state, and updatedAt.
The show route returns 200 with { version, state } and an ETag header, or 204 when the end-user has no state yet; an unknown end-user id also returns 204.
The delete route removes the end-user's state across every environment in the project (note its path has no {env} segment) and returns 204.
See Authentication for the bearer token these routes require.