Skip to content

Which org the CRM around this tab belongs to

POST
/auth/session/frame
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.

Media typeapplication/json
object
zohoOrgId
required

The CRM’s own org id (zgid), as the widget SDK’s CRM.CONFIG.getOrgInfo() reports it.

string
>= 1 characters <= 64 characters
Examplegenerated
{
"zohoOrgId": "example"
}

What the CRM around this tab is to you.

Media typeapplication/json
One of:
object
outcome
required
string
Allowed values: member
orgId
required
string
orgName
required
string
connectorId
required
string
role
required
string
Allowed values: owner admin builder operator
ambiguous
required

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.

boolean
tabToken
required

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.

string
tabExp
required

When tabToken ends if it is not used, in seconds since the epoch. Its window slides with use, as any session’s does.

integer
Example
{
"outcome": "member",
"role": "owner"
}

The request — its body or its query — did not match the schema. issues carries the Zod issue list.

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

No bearer, or one that is expired, revoked or no longer resolves to a member.

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
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).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
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).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

Report a problem with this page