See an organisation as one of its members
const url = 'https://api.sloose.com/staff/orgs/org_9f3c/impersonate';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"userId":"example","reason":"example","write":true,"confirm":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.sloose.com/staff/orgs/org_9f3c/impersonate \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "userId": "example", "reason": "example", "write": true, "confirm": "example" }'Backoffice route, staff session only — the shared ADMIN_TOKEN is refused with 403 SESSION_REQUIRED. Mints a session for a member of the organisation that lasts an hour and does not slide. Read-only by default: every request that is not a GET is refused with 403 IMPERSONATION_READ_ONLY (STAFF_VIEW on the routes that act on the person rather than the organisation), except POST /auth/session/refresh and POST /auth/impersonation/end.
Pass write: true for a view that acts as the member for real within this organisation — every row it writes in the organisation is theirs, and the organisation cannot tell from the data that it was not. It still makes none of the person’s own writes outside the organisation — making an organisation, accepting an invitation, asking another organisation for access, ending one of their sessions, moving the session, changing their second factor — each refused with 403 STAFF_VIEW. Nor, within the organisation, does it grant a credential or access that would outlast it — an API token, an invitation, an approved access request, a raised role, an app’s grant — or close the organisation: each refused with 403 IMPERSONATION_REFUSED (an app’s grant as OAuth’s access_denied). That variant needs a reason and confirm set to the organisation’s own name, and is refused rather than downgraded if either is missing.
The widget shows who is looking, and says so more loudly when the view can write. Staff session only — the admin token cannot look as somebody, since nobody would be on the record. Written down as impersonate.start against the member, with write in the detail.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The organisation
Example
org_9f3cThe organisation
Request Body
Section titled “Request Body”object
The member to see the organisation as. Defaults to its most senior member.
Why, for the record.
Ask for a view that may write. reason and confirm are then required, and the request is refused — never quietly downgraded to read-only — if either is missing. Omit for a read-only view.
The organisation’s own name, typed out. Required when write is true.
Examplegenerated
{ "userId": "example", "reason": "example", "write": true, "confirm": "example"}Responses
Section titled “Responses”The session, read-only unless write was asked for, and where to open it.
object
object
A session token for the member. Read-only unless write on this response is true.
Expiry, seconds since the epoch. Does not slide.
Whether this view may write, or only read.
object
The widget, outside the CRM, with the session in the fragment — open it in a new tab.
Example
{ "session": { "role": "owner" }}The request — its body or its query — did not match the schema. issues carries the Zod issue list.
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}A bearer that is neither the token nor a live session (code: AUTH_REQUIRED).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}A customer’s session, an API token, or no bearer at all — not staff, and not the ADMIN_TOKEN (code: ADMIN_REQUIRED).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}No such member of this organisation, or it is not visible to this session.
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}The restore switch is on (code: MAINTENANCE): every route but /health and /robots.txt is refused before anything is read, except the operator’s own POST /staff/people/{id}/delete with the ADMIN_TOKEN. Sloose is down for maintenance. Please try again in a few minutes.
object
Example
{ "code": "MAINTENANCE"}Headers
Section titled “Headers”Seconds until asking again is worth it (300 while the switch is on).