curl --request PUT \
--url https://app.hookie.ai/admin/api/workspace/google-domain \
--header 'Content-Type: application/json' \
--cookie hookie_session= \
--data '
{
"default_role": "viewer",
"domain": "<string>"
}
'const options = {
method: 'PUT',
headers: {cookie: 'hookie_session=', 'Content-Type': 'application/json'},
body: JSON.stringify({default_role: 'viewer', domain: '<string>'})
};
fetch('https://app.hookie.ai/admin/api/workspace/google-domain', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.hookie.ai/admin/api/workspace/google-domain"
payload = {
"default_role": "viewer",
"domain": "<string>"
}
headers = {
"cookie": "hookie_session=",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"link": {
"domain": "<string>",
"default_role": "viewer",
"created_by": "<string>",
"created_by_email": "<string>",
"created_at": "2023-11-07T05:31:56Z"
}
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}Link the owner's Google Workspace domain
Owner only, in the console, from a Google sign-in whose Google Workspace domain Google verified; never through an OAuth-connected agent or an API key. The domain linked is ALWAYS the session’s, never one chosen by the request: domain in the body is only a check, refused with 409 google_workspace_domain_mismatch when it differs. Linking another domain replaces this workspace’s link (members who joined stay); linking the same one again changes only default_role (PATCH changes the role without a Google sign-in). Audited as google_workspace_linked (or google_workspace_updated). Refused while the workspace is suspended. Google Workspace teams (#326). A workspace can be linked to one Google Workspace domain, and a domain to one workspace. Anyone who then signs in to the console with Google using an account in that domain joins the workspace automatically with the link’s default_role, before Hookie would create an empty workspace for them, and, when it is their first workspace, it becomes their active one (someone already in other workspaces joins this one as well but is not moved: it appears in their workspace switcher). No WorkOS organization is created: the grouping is Hookie’s. Linking is first come, first served among the domain’s own Google accounts; a platform operator can unlink a domain or reassign it to another workspace, audited in both workspaces’ logs. The domain is Google’s hd claim, read once at sign-in from Google’s OpenID Connect userinfo endpoint with the Google access token WorkOS returns, and sealed into an HttpOnly cookie bound to that session. It is never taken from the email address: a personal Google account on a company address, an email-code sign-in and a GitHub sign-in never join, and gmail.com / googlemail.com can never be linked. A join respects the plan’s member limit (at the limit the person is not added, and GET /admin/api/me carries googleWorkspaceNotice, which names only their own domain, never the workspace or its headcount), never happens for a suspended or closing workspace, and never re-adds someone who left or was removed, including before this feature shipped (an invite still can). Joins are audited as member_joined_google_workspace, and on Team the subscription’s seat count follows. Requires the WorkOS environment’s Google provider to return OAuth tokens; without that no domain is ever verified, so nothing links and nobody joins.
curl --request PUT \
--url https://app.hookie.ai/admin/api/workspace/google-domain \
--header 'Content-Type: application/json' \
--cookie hookie_session= \
--data '
{
"default_role": "viewer",
"domain": "<string>"
}
'const options = {
method: 'PUT',
headers: {cookie: 'hookie_session=', 'Content-Type': 'application/json'},
body: JSON.stringify({default_role: 'viewer', domain: '<string>'})
};
fetch('https://app.hookie.ai/admin/api/workspace/google-domain', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.hookie.ai/admin/api/workspace/google-domain"
payload = {
"default_role": "viewer",
"domain": "<string>"
}
headers = {
"cookie": "hookie_session=",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"link": {
"domain": "<string>",
"default_role": "viewer",
"created_by": "<string>",
"created_by_email": "<string>",
"created_at": "2023-11-07T05:31:56Z"
}
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>",
"reason": "<string>",
"code": "agent_scope_insufficient",
"required_scope": "hookie:read",
"granted_scopes": [
"<string>"
],
"manage_url": "<string>",
"scheme": "<string>",
"max_members": 123,
"members": 123,
"customer_id": "<string>",
"customer_name": "<string>",
"account_id": "<string>",
"terms_version": "<string>",
"claim_required": true
}Authorizations
The console's sealed session cookie, set by WorkOS AuthKit. Mutating requests also require the X-Requested-With CSRF header.