Which org the CRM around this tab belongs to
const url = 'https://api.sloose.com/auth/session/frame';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"zohoOrgId":"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/auth/session/frame \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "zohoOrgId": "example" }'A widget framed by a CRM sends that CRM’s org id. Connector found and you are a member → the tab gets a session of its own in that org (tabToken), and connectorId names the connection of it that IS this CRM: the page pre-selects it for an import started in this tab, and the import records it. A session holds no connection of its own (every request that uses one names it).
The session that asks is not moved (#237). Inside a CRM the widget keeps one session per browser, shared by every tab of the CRM’s site, and two tabs of two orgs’ CRMs used to take it from each other. Asked with that browser session, a member answer mints the tab’s own: the same person, with the second factor and the CRM proof the browser session holds, ended whenever it is ended (a sign-out, a revoke, a ban), and sliding it as it is used. The tab keeps it in its own storage and sends it from then on. Asked with a tab’s own session — the tab reloaded — that session is placed in the org and handed back, and nothing new is made. One browser session holds at most twenty tab sessions at once; past that, the one least recently minted, placed or slid ends — a session slides at most once a quarter hour of use, so among tabs opened within one quarter hour that is the oldest — and its tab, if still open, is refused once and asks again.
Not a member of any org that holds it → what the session is told depends on what its Zoho sign-in proved (design §13.6, §13.7). One that proved THIS CRM within the last day gets none: the Sloose orgs holding it through a listed connection they have not disconnected (holders, org names only — any of them may be asked for access), the orgs you administer (orgs, any of which could connect this CRM too — an org and a CRM are different things), and the CRM’s own name (crm). Any other session gets verify and nothing about the holders — not their names, their number, nor whether any exist — so a CRM id cannot be probed for whether it is a customer: reason: unproved (sign in with Zoho, choosing this CRM’s organisation) or reason: other-crm (the sign-in proved another CRM, named in signedInTo). Nobody joins an org by being in its CRM.
Asked on every load of a framed widget, so a stored session is checked against the tab it is in.
Session only, and never a staff member’s view of an org, which stays in the org it was opened on.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
The CRM’s own org id (zgid), as the widget SDK’s CRM.CONFIG.getOrgInfo() reports it.
Examplegenerated
{ "zohoOrgId": "example"}Responses
Section titled “Responses”What the CRM around this tab is to you.
object
True when the org holds more than one connection for this CRM id: connectorId is then a deterministic pick (an active connection, then the oldest), and the page says which connection it pre-selects.
The session THIS TAB uses from now on, in that org: send it as Authorization: Bearer. Minted when the bearer that asked was the browser’s session; that same bearer when it was already a tab’s own.
When tabToken ends if it is not used, in seconds since the epoch. Its window slides with use, as any session’s does.
object
The CRM your Zoho sign-in proved, as it names itself.
object
The Sloose orgs holding this CRM through a listed connection they have not disconnected: org names only, as somebody outside an org is shown one — “a team” when the name could be read as Sloose. Any may be asked for access.
object
The orgs you administer, any of which could connect this CRM.
object
object
unproved: this session proved no CRM, or not within the last day — sign in with Zoho. other-crm: its sign-in proved another CRM than this tab’s — sign in again and choose this one on Zoho’s screen.
With other-crm: the CRM the sign-in proved, as it names itself.
Example
{ "outcome": "member", "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"}No bearer, or one that is expired, revoked or no longer resolves to a member.
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"}An API token was used (code: SESSION_REQUIRED), or the session is a staff member’s view of an org (code: STAFF_VIEW).
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"}Asked more often than a tab ever does — sixty times in ten minutes for one session (code: RATE_LIMITED, with retryAfterSeconds).
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"}