curl --request POST \
--url https://app.hookie.ai/admin/api/invites/accept \
--header 'Content-Type: application/json' \
--cookie hookie_session= \
--data '
{
"token": "<string>"
}
'const options = {
method: 'POST',
headers: {cookie: 'hookie_session=', 'Content-Type': 'application/json'},
body: JSON.stringify({token: '<string>'})
};
fetch('https://app.hookie.ai/admin/api/invites/accept', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.hookie.ai/admin/api/invites/accept"
payload = { "token": "<string>" }
headers = {
"cookie": "hookie_session=",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"joined": true,
"tenant_id": "<string>",
"workspace": {
"id": "<string>",
"name": "<string>",
"slug": "<string>"
},
"role": "<string>"
}{
"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
}{
"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
}{
"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
}{
"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
}{
"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
}Join a workspace with an invite link's token
Any signed-in person, in the console (#308); never an agent or an API key. The workspace joined is the one the invite belongs to, never one named in the request. This route is resolved WITHOUT the automatic workspace every other admin route creates for someone who has none, so an invitee joins this workspace without first getting an empty one of their own. The link is used once: accepting creates the membership with the invite’s role, marks the invite accepted in the same transaction (two accepts racing for one link make one member), makes the workspace the caller’s active one, and is audited as member_invite_accepted. A person who is already a member gets 200 with joined: false and is switched to the workspace; a pending link they open is not spent. A token that is wrong, expired, revoked or already used answers the same 404 with the same words, and so does an invite whose creator could no longer create it (removed, demoted below admin, or, for an admin invite, no longer the owner): an invite is only as good as its creator’s authority when it is accepted. The console calls POST /admin/api/invites/preview first and accepts only when the person clicks Join; opening a link never joins by itself. The deployment’s email-domain pin applies. On Team, the subscription’s seat count follows (best-effort). Members per plan, the owner included: Free 1 (the owner only), Pro 3, Team unlimited (billed per seat).
curl --request POST \
--url https://app.hookie.ai/admin/api/invites/accept \
--header 'Content-Type: application/json' \
--cookie hookie_session= \
--data '
{
"token": "<string>"
}
'const options = {
method: 'POST',
headers: {cookie: 'hookie_session=', 'Content-Type': 'application/json'},
body: JSON.stringify({token: '<string>'})
};
fetch('https://app.hookie.ai/admin/api/invites/accept', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.hookie.ai/admin/api/invites/accept"
payload = { "token": "<string>" }
headers = {
"cookie": "hookie_session=",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"joined": true,
"tenant_id": "<string>",
"workspace": {
"id": "<string>",
"name": "<string>",
"slug": "<string>"
},
"role": "<string>"
}{
"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
}{
"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
}{
"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
}{
"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
}{
"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
}Authorizations
The console's sealed session cookie, set by WorkOS AuthKit. Mutating requests also require the X-Requested-With CSRF header.
Body
The token from the link (#/invite/{token}).
Response
Joined, or already a member. Either way the workspace is now the caller's active one.