Stackure API Reference
Stackure's HTTP endpoints, with their parameters and responses.
Two APIs. The Sign-in API under /api/public signs people in to your apps. The Management API under /api/internal runs your organization without the web app.
Each region is its own deployment with its own base URL. Use the region where your organization was created.
Bodies are JSON unless an operation says otherwise. Send them with Content-Type: application/json. Parameters such as charset are fine. Each deployment sets the largest JSON body it takes, 1 MB by default. A larger body returns 400 request too large. An empty list is []. User, team, app, organization, signup, support request and AI client connection IDs are UUIDs. An ID that isn't one returns 400. Errors look like {"error": "<message>"}. A method an endpoint doesn't support returns 405 method not allowed.
Paged lists take cursor and limit. The X-Next-Cursor response header holds the cursor for the next page and is absent on the last one.
This page is for https://stackure.com, which takes JSON bodies up to 1 MB. Its OpenAPI 3.1.0 spec is at https://stackure.com/openapi.json.
Sign-in API
Paths start with /api/public.
Authentication
Sign people in to your app, check their sessions and connect AI clients. Each operation lists the credentials it takes:
X-App-Secret: your app's secret, on calls your server makes for your app.- A session token as
Authorization: Bearer <token>or asessioncookie. Session checks and the directory take the app session token your app got when the person signed in. Sign-out takes that or a platform session token. - An AI client's access token as
Authorization: Bearer <token>, on session checks that carry themcpparameter. X-Org-Secret: the parent organization's secret, on signups.
Exchanging a sign-in token and the MCP endpoints take none. The MCP endpoints follow OAuth 2.1 for public clients: no client secret, PKCE with S256.
The endpoints below refer to credentials by these names:
orgSecret:X-Org-Secretheader. The parent organization's secret, 64 characters, fromPOST /api/internal/account/secret.appSecret:X-App-Secretheader. Your app's secret, 64 characters. You see it when you register the app and each time you rotate it.appSession:Authorization: Bearerheader. A session token issued for one app when a person signs in to it. It works only with that app'sapp_idand never on the Management API. SendAuthorization: Bearer <token>withBearerwritten exactly like that.appSessionCookie:sessioncookie. The same app session token in a cookie namedsession. When you send a cookie and a header, the cookie is used.mcpCredential:Authorization: Bearerheader. An access token an AI client got fromPOST /api/public/auth/mcp/tokenfor your app. Accepted only with themcpquery parameter. SendAuthorization: Bearer <token>withBearerwritten exactly like that.platformSession:Authorization: Bearerheader. A platform session token, fromPOST /api/public/auth/magic-link/verifywith a link requested withoutapp_id. SendAuthorization: Bearer <token>withBearerwritten exactly like that.platformSessionCookie:sessioncookie. The same platform session token in a cookie namedsession. When you send a cookie and a header, the cookie is used.
Endpoints
POST /api/public/signup· Apply for an organizationPOST /api/public/auth/magic-link/send· Send a sign-in linkPOST /api/public/auth/magic-link/verify· Exchange a sign-in tokenGET /api/public/auth/session/validate· Check a sessionGET /api/public/directory/users· List who can open your appGET /api/public/directory/teams· List teams that have your appPOST /api/public/auth/sign-out· Sign outPOST /api/public/auth/mcp/token· Get an AI client tokenPOST /api/public/auth/mcp/register· Register an AI clientPOST /api/public/auth/mcp/revoke· Revoke an AI client token
Apply for an organization
POST /api/public/signup
Applies for a new organization under a parent organization. The parent's approvers and the applicant each get an email.
You get the same 200 when a signup with this email or organization name is already waiting or the email already belongs to a user. The applicant then gets an email saying why it can't go ahead.
Rate limited per email and IP address.
Authentication
orgSecret(X-Org-Secretheader)
Request body
application/json, object.
| Field | Description |
|---|---|
parent_idstring (uuid) | The organization to apply under. Leave it out for the top organization of this region. |
account_namestring, required | Name of the new organization. Up to 255 characters. |
account_countrystring, required | Country name, such as Germany. Up to 50 characters. |
account_timezonestring, required | IANA time zone, such as Europe/Berlin. |
account_typestring, required | What kind of organization it is. Up to 100 characters. |
account_planstring, required | Plan. Any case works. One of free, pilot or premium. |
user_first_namestring, required | Up to 100 characters. |
user_last_namestring, required | Up to 100 characters. |
user_emailstring (email), required | The applicant's email. They become the owner when the signup is approved. Up to 255 characters. |
user_positionstring, required | The applicant's job title. Up to 100 characters. |
signup_messagestring | A note for the approvers. Up to 1000 characters. |
Responses
| Status | Description |
|---|---|
200 | Signup received. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | invalid org secret: X-Org-Secret is missing or doesn't match the parent organization. An unknown parent_id gets the same 401, so the response doesn't reveal which organizations exist. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
429 | too many requests, please try again later. Some limits also send Retry-After. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required | Always We got your signup. We read every one and reply by email. |
signup_idstring (uuid) | Only in local development. |
429 headers:
| Header | Description |
|---|---|
Retry-Afterinteger | Seconds to wait before trying again. |
Send a sign-in link
POST /api/public/auth/magic-link/send
Emails a sign-in link if the email belongs to a user. The response is the same either way.
With app_id, also send your app's secret in X-App-Secret. The link then signs the person in to your app.
Without app_id, every request gets 200 unless its JSON is invalid, its Content-Type is wrong or it's rate limited.
Authentication
One of these:
- No credentials
appSecret(X-App-Secretheader)
Request body
application/json, object.
| Field | Description |
|---|---|
user_emailstring (email) | |
app_idstring (uuid) | Your app's ID. Requires X-App-Secret. |
Responses
| Status | Description |
|---|---|
200 | Request handled. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | invalid app secret: you sent app_id and X-App-Secret is missing or wrong. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
429 | too many requests, please try again later. Some limits also send Retry-After. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required | |
tokenstring | The sign-in link's token. Only in local development. |
429 headers:
| Header | Description |
|---|---|
Retry-Afterinteger | Seconds to wait before trying again. |
Exchange a sign-in token
POST /api/public/auth/magic-link/verify
Exchanges the token from a sign-in link for a session token. A link requested without app_id gives a platform session token for the Management API. A link requested with app_id gives a session token for that app.
If the organization's access has expired, a link requested without app_id gives token_scope support_only: the session can only contact support, and redirect_url points to the support page. A link requested with app_id returns 403 forbidden instead.
Links that connect an AI client don't work here.
Authentication
- No credentials
Request body
application/json, object.
| Field | Description |
|---|---|
tokenstring, required | The token query parameter of the sign-in link. Exactly 64 characters. |
Responses
| Status | Description |
|---|---|
200 | Signed in. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | token invalid when the token isn't 64 characters. authentication failed when the link is unknown, used, expired or connects an AI client. |
403 | forbidden: the link was for an app the person can't open, or their organization's access has expired. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
429 | too many verification attempts from this IP address. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
200 body: application/json, object.
| Field | Description |
|---|---|
session_tokenstring (uuid), required | The platform session token. When the link was for an app, the app session token. |
token_scopestring, required | One of full or support_only. |
app_idstring (uuid) | The app the token is for. Only for app links. |
redirect_urlstring (uri) | The support page. Only when token_scope is support_only. |
account_statusstring | Only when token_scope is support_only. Always expired. |
Check a session
GET /api/public/auth/session/validate
Tells your server who is signed in to your app. Call it from your server on every protected request.
Send your app's secret in X-App-Secret and the person's app session token as Authorization: Bearer <token> or a session cookie. A missing, expired or signed-out token returns authenticated: false with a sign_in_url.
For an MCP endpoint, add mcp and forward the AI client's Authorization: Bearer credential. When the client isn't signed in, the response adds www_authenticate: answer the client with 401 and that value, unchanged, as the WWW-Authenticate header.
Rate limited per app. Failed calls are also limited per app and IP address, 10 a minute by default. Past that, a failed call returns 429 with Retry-After: 60 instead of its error.
Authentication
One of these:
appSecret(X-App-Secretheader) andappSession(Authorization: Bearerheader)appSecret(X-App-Secretheader) andappSessionCookie(sessioncookie)appSecret(X-App-Secretheader) andmcpCredential(Authorization: Bearerheader)appSecret(X-App-Secretheader)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | Your app's ID. |
mcpstring (uri) in query | The public URL of your MCP endpoint the request arrived at, with no query string. When present, the token is checked as an AI client credential for your app. |
Responses
| Status | Description |
|---|---|
200 | The session's state. |
400 | app_id required or invalid app_id format. |
401 | invalid app secret: X-App-Secret is missing or wrong. |
429 | too many requests, please try again later. Some limits also send Retry-After. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | no-store when authenticated is true. Not sent otherwise. |
200 body: application/json, object.
| Field | Description |
|---|---|
authenticatedboolean, required | |
userobject | Only when authenticated is true. |
user.user_idstring (uuid), required | |
user.account_idstring (uuid), required | The person's organization. |
user.user_emailstring (email), required | |
user.user_first_namestring, required | |
user.user_last_namestring, required | |
user.user_is_app_adminboolean, required | The person is an app admin or the owner in their organization. Your app decides what that means. |
user.user_teamsarray of objects, required | Teams the person is on in their organization, sorted by name. Empty when none. |
user.user_teams[].team_idstring (uuid), required | |
user.user_teams[].team_namestring, required | |
sign_in_urlstring (uri) | Where to send the person to sign in. Only when authenticated is false. |
www_authenticatestring | The WWW-Authenticate value for your 401 to the AI client. Only with mcp and when authenticated is false. |
429 headers:
| Header | Description |
|---|---|
Retry-Afterinteger | Seconds to wait before trying again. |
List who can open your app
GET /api/public/directory/users
Lists the users in the signed-in person's organization who can open your app, for pickers and sharing. Sorted by first name, then last name. q matches name, email and job title.
We define no permissions inside your app. You decide what these users and teams may do.
Send X-App-Secret and the person's app session token as Authorization: Bearer <token> or a session cookie. AI client credentials aren't accepted. Rate limited per app. Failed calls are also limited per app and IP address, 10 a minute by default. Past that, a failed call returns 429 with Retry-After: 60 instead of its error.
Authentication
One of these:
appSecret(X-App-Secretheader) andappSession(Authorization: Bearerheader)appSecret(X-App-Secretheader) andappSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | Your app's ID. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
idarray of strings (uuid) in query | Only these IDs, for checking or naming people or teams you already have. Repeat it for up to 200. Up to 200 items. |
Responses
| Status | Description |
|---|---|
200 | One page of users. |
400 | invalid app_id format when app_id is missing or isn't a UUID, invalid input: q, invalid input: limit, invalid input: cursor or invalid input: id. |
401 | invalid app secret when X-App-Secret is missing or wrong. invalid session when there's no live session for this app. |
429 | too many requests, please try again later. Some limits also send Retry-After. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
user_idstring (uuid), required | |
user_emailstring (email), required | |
user_first_namestring, required | |
user_last_namestring, required |
429 headers:
| Header | Description |
|---|---|
Retry-Afterinteger | Seconds to wait before trying again. |
List teams that have your app
GET /api/public/directory/teams
Lists the teams in the signed-in person's organization that have your app, for pickers and sharing: every team when the app is available to everyone, otherwise the teams it's shared with. Sorted by name. q matches the team name.
We define no permissions inside your app. You decide what these users and teams may do.
Send X-App-Secret and the person's app session token as Authorization: Bearer <token> or a session cookie. AI client credentials aren't accepted. Rate limited per app. Failed calls are also limited per app and IP address, 10 a minute by default. Past that, a failed call returns 429 with Retry-After: 60 instead of its error.
Authentication
One of these:
appSecret(X-App-Secretheader) andappSession(Authorization: Bearerheader)appSecret(X-App-Secretheader) andappSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | Your app's ID. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
idarray of strings (uuid) in query | Only these IDs, for checking or naming people or teams you already have. Repeat it for up to 200. Up to 200 items. |
Responses
| Status | Description |
|---|---|
200 | One page of teams. |
400 | invalid app_id format when app_id is missing or isn't a UUID, invalid input: q, invalid input: limit, invalid input: cursor or invalid input: id. |
401 | invalid app secret when X-App-Secret is missing or wrong. invalid session when there's no live session for this app. |
429 | too many requests, please try again later. Some limits also send Retry-After. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
team_idstring (uuid), required | |
team_namestring, required |
429 headers:
| Header | Description |
|---|---|
Retry-Afterinteger | Seconds to wait before trying again. |
Sign out
POST /api/public/auth/sign-out
Signs the person out everywhere. Every session on every app and device ends. Their AI clients are disconnected.
Send a platform or app session token as Authorization: Bearer <token> or a session cookie. You get 200 even when the token is missing or no longer valid.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)appSession(Authorization: Bearerheader)appSessionCookie(sessioncookie)- No credentials
Responses
| Status | Description |
|---|---|
200 | message is signed out successfully. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Get an AI client token
POST /api/public/auth/mcp/token
The OAuth token endpoint for AI clients connecting over MCP, to us or to your app.
The authorize step is GET /mcp/authorize for our MCP server or GET /mcp/{app_id}/authorize for your app. Clients find every OAuth URL at /.well-known/oauth-authorization-server/mcp or /.well-known/oauth-authorization-server/mcp/{app_id}.
authorization_coderedeems the code from the authorize step with its PKCEcode_verifier.refresh_tokenreturns a new access token and refresh token. Always use the newest refresh token. Reusing an old one can end the connection.
Access ends when the person signs out, disconnects the client or loses access. It also ends after a period without use.
Authentication
- No credentials
Request body
application/x-www-form-urlencoded, object.
| Field | Description |
|---|---|
grant_typestring, required | One of authorization_code or refresh_token. |
codestring | For authorization_code. Exactly 64 characters. |
code_verifierstring | For authorization_code. The PKCE verifier. 43 to 128 characters. |
redirect_uristring | For authorization_code. The one used at the authorize step. |
resourcestring (uri) | For authorization_code. The MCP endpoint URL. Must match the one from the authorize step. |
refresh_tokenstring | For refresh_token. Exactly 64 characters. |
client_idstring | Your client_id from registration or the HTTPS URL of your client metadata document. |
Responses
| Status | Description |
|---|---|
200 | Tokens issued. |
400 | error is unsupported_grant_type, invalid_grant, invalid_client or invalid_target. |
429 | too many requests, please try again later: the connection holds too many live access tokens. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
200 body: application/json, object.
| Field | Description |
|---|---|
access_tokenstring (uuid), required | |
token_typestring, required | Always Bearer. |
expires_ininteger, required | Seconds until the access token expires. |
refresh_tokenstring, required | |
scopestring | Left out for connections to an app. One of stackure.read or stackure.read stackure.write. |
Register an AI client
POST /api/public/auth/mcp/register
OAuth dynamic client registration for AI clients. Returns the client_id to use at the authorize and token steps. Rate limited per IP address. This endpoint sets its own body limit, 16 KB by default. A larger body returns 400 invalid_client_metadata.
Each redirect URI must be one of these:
- HTTPS with a lowercase host
httponlocalhostor127.0.0.1- A custom URL scheme for a native app
Authentication
- No credentials
Request body
application/json, object.
| Field | Description |
|---|---|
redirect_urisarray of strings, required | 1 to 10 items. |
client_namestring | Shown to people when they connect. Only letters, digits, spaces and hyphens are kept. Defaults to MCP client. |
Responses
| Status | Description |
|---|---|
201 | Client registered. |
400 | error is invalid_client_metadata or invalid_redirect_uri. |
429 | too many requests, please try again later. Some limits also send Retry-After. |
500 | internal server error: something failed on our side. Try again. |
201 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
201 body: application/json, object.
| Field | Description |
|---|---|
client_idstring (uuid), required | |
client_id_issued_atinteger, required | Unix time in seconds. |
client_namestring, required | |
redirect_urisarray of strings, required | |
token_endpoint_auth_methodstring, required | Always none. |
grant_typesarray of strings, required | |
response_typesarray of strings, required |
429 headers:
| Header | Description |
|---|---|
Retry-Afterinteger | Seconds to wait before trying again. |
Revoke an AI client token
POST /api/public/auth/mcp/revoke
OAuth token revocation. A live access token or refresh token ends its whole connection. You get 200 and {} whether or not the token was valid.
Authentication
- No credentials
Request body
application/x-www-form-urlencoded, object.
| Field | Description |
|---|---|
tokenstring, required | An access token or refresh token. |
client_idstring | When sent, the token must belong to this client. |
Responses
| Status | Description |
|---|---|
200 | Done. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, empty object.
Management API
Paths start with /api/internal.
Authentication
Run your organization without the web app: users, teams, roles, permissions, apps and their secrets, partners, partner signups, AI access, AI clients, support requests and activity. You can also transfer ownership, rotate your organization's secret and see its limits. The signup list shows each organization's name, status and date. GET /api/internal/signup shows one signup in full.
Every call needs a platform session token as Authorization: Bearer <token> or a session cookie. When you send both, the cookie is used. To get a token, request a sign-in link with POST /api/public/auth/magic-link/send without app_id, take the token from the link in the email and exchange it at POST /api/public/auth/magic-link/verify. The token ends when it expires, when you sign out or when you sign in again, since each person has one session at a time. Request a new link when calls return 401 invalid session.
App session tokens and AI client tokens don't work here.
- No token: 401
missing authorization header. - A token that isn't a live platform session: 401
invalid session. - Your organization's access has expired: 403
forbiddenon every call except your own support requests. You can still send them to the organization above yours, list them and read them with/api/internal/support-requestsand/api/internal/support-request.
What you can see and change depends on your roles.
The endpoints below refer to credentials by these names:
platformSession:Authorization: Bearerheader. A platform session token, fromPOST /api/public/auth/magic-link/verifywith a link requested withoutapp_id. SendAuthorization: Bearer <token>withBearerwritten exactly like that.platformSessionCookie:sessioncookie. The same platform session token in a cookie namedsession. When you send a cookie and a header, the cookie is used.
Endpoints
GET /api/internal/users· List usersPOST /api/internal/users· Invite usersGET /api/internal/user· Get a userPUT /api/internal/user· Update a userDELETE /api/internal/user· Delete a userGET /api/internal/user/apps· List a user's appsGET /api/internal/user/teams· List a user's teamsGET /api/internal/user/access· Get a user's roles and permissionsPOST /api/internal/user/roles· Give roles to a userDELETE /api/internal/user/roles· Remove a role from a userGET /api/internal/user/ai-clients· List a user's AI clientsPOST /api/internal/user/ai-clients· Disconnect an AI clientGET /api/internal/roles· List rolesGET /api/internal/role· Get a rolePOST /api/internal/role· Create a rolePUT /api/internal/role· Update a roleDELETE /api/internal/role· Delete a roleGET /api/internal/permissions· List permissionsGET /api/internal/permission· Get a permissionGET /api/internal/role/permissions· List a role's permissionsPOST /api/internal/role/permissions· Add permissions to a roleDELETE /api/internal/role/permissions· Remove permissions from a roleGET /api/internal/role/users· List users with a roleGET /api/internal/permission/roles· List roles with a permissionGET /api/internal/permission/users· List users with a permissionGET /api/internal/teams· List teamsGET /api/internal/team· Get a teamPOST /api/internal/team· Create a teamPUT /api/internal/team· Update a teamDELETE /api/internal/team· Delete a teamGET /api/internal/team/members· List team membersPOST /api/internal/team/members· Add team membersPUT /api/internal/team/member· Make or remove a team adminDELETE /api/internal/team/member· Remove a team memberGET /api/internal/team/apps· List a team's appsGET /api/internal/team/partners· List a team's partnersPOST /api/internal/team/partner· Assign a partner to a teamDELETE /api/internal/team/partner· Unassign a partner from a teamGET /api/internal/apps· List appsGET /api/internal/app· Get an appPOST /api/internal/app· Register an appPUT /api/internal/app· Update an appDELETE /api/internal/app· Delete an appPOST /api/internal/app/secret· Rotate an app secretGET /api/internal/app/teams· List an app's teamsGET /api/internal/app/users· List who can open an appGET /api/internal/app/partners· List an app's partnersPOST /api/internal/app/account· Make an app available to everyoneDELETE /api/internal/app/account· Stop sharing an app with everyonePOST /api/internal/app/team· Share an app with a teamDELETE /api/internal/app/team· Stop sharing an app with a teamPOST /api/internal/app/partner· Share an app with a partnerDELETE /api/internal/app/partner· Stop sharing an app with a partnerGET /api/internal/partners· List partnersGET /api/internal/partner· Get a partnerPOST /api/internal/partner/close· Close a partnerPOST /api/internal/partner/expiry· Extend a partner's expiryGET /api/internal/partner/apps· List apps shared with a partnerGET /api/internal/partner/limits· Get a partner's limitsGET /api/internal/partner/teams· List teams managing a partnerGET /api/internal/signups· List signupsGET /api/internal/signup· Get a signupPOST /api/internal/signup/approve· Approve a signupGET /api/internal/support-requests· List support requestsPOST /api/internal/support-requests· Send a support requestGET /api/internal/support-request· Get a support requestPOST /api/internal/support-request/status· Update a support requestPOST /api/internal/signup/reject· Reject a signupGET /api/internal/account· Get your organizationPUT /api/internal/account/owner· Transfer ownershipPOST /api/internal/account/secret· Rotate the organization secretGET /api/internal/account/ai-access· Get AI accessPUT /api/internal/account/ai-access· Change AI accessGET /api/internal/limits· Get your organization's limitsGET /api/internal/activity· List activity
List users
GET /api/internal/users
Users in your organization you can see, sorted by first name, then last name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | One page of users. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
user_idstring (uuid) | |
account_idstring (uuid) | The user's organization. |
user_first_namestring, required | |
user_last_namestring, required | |
user_positionstring, required | Job title. |
user_emailstring (email), required | |
user_settingsobject | Stored settings, such as timezone. |
user_timezonestring | IANA time zone, such as Europe/Berlin. |
user_createdstring (date-time), required | |
user_updatedstring (date-time), required | |
user_created_bystring (uuid) | The user who invited this one. |
HasAccessboolean, required | Always true. |
Invite users
POST /api/internal/users
Adds people to your organization. Each new user gets an email with a link to sign in.
201 when at least 1 user was created and none failed. 207 when any failed. 409 when every user already exists. details has one entry per person.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, array of objects. At least 1 item.
| Field | Description |
|---|---|
user_first_namestring, required | Up to 100 characters. |
user_last_namestring, required | Up to 100 characters. |
user_emailstring (email), required | Up to 255 characters. |
user_positionstring, required | Job title. Up to 100 characters. |
user_settingsobject |
Responses
| Status | Description |
|---|---|
201 | Users created. |
207 | Some or all failed. |
400 | invalid json when the body isn't a JSON array of users, no users to invite or bulk operation failed, all users must have valid data when no entry is valid. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
409 | Every user already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
201, 207 and 409 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required | One of all users invited successfully, some users invited successfully, some users invited successfully, some failed, all users failed to be invited or all users already exist. |
detailsarray of objects | |
details[].user_idstring, required | Empty when no user was created. |
details[].user_emailstring, required | |
details[].statusstring, required | created, duplicate_skipped when the email already exists, or why it failed, such as user_email required or invalid email. |
Get a user
GET /api/internal/user
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query, required | User ID. |
Responses
| Status | Description |
|---|---|
200 | The user. |
400 | invalid input: user_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
user_idstring (uuid) | |
account_idstring (uuid) | The user's organization. |
user_first_namestring, required | |
user_last_namestring, required | |
user_positionstring, required | Job title. |
user_emailstring (email), required | |
user_settingsobject | Stored settings, such as timezone. |
user_timezonestring | IANA time zone, such as Europe/Berlin. |
user_createdstring (date-time), required | |
user_updatedstring (date-time), required | |
user_created_bystring (uuid) | The user who invited this one. |
creatorobject, required | The user who invited this one. Email and job title are empty when you can't see them. |
creator.user_idstring (uuid) | |
creator.account_idstring (uuid) | The user's organization. |
creator.user_first_namestring, required | |
creator.user_last_namestring, required | |
creator.user_positionstring, required | Job title. |
creator.user_emailstring (email), required | |
creator.user_settingsobject | Stored settings, such as timezone. |
creator.user_timezonestring | IANA time zone, such as Europe/Berlin. |
creator.user_createdstring (date-time), required | |
creator.user_updatedstring (date-time), required | |
creator.user_created_bystring (uuid) | The user who invited this one. |
user_is_account_ownerboolean | Present and true when this user owns the organization. |
user_app_countinteger | Apps this user can open that you can see. Left out when 0. |
user_team_countinteger | Teams this user is on that you can see. Left out when 0. |
user_role_countinteger | Roles this user holds. Left out when 0. |
Update a user
PUT /api/internal/user
Changes only the fields you send. An empty value leaves that field as it is. You can change user_timezone only for yourself.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query, required | User ID. |
Request body
application/json, object.
| Field | Description |
|---|---|
user_first_namestring | Up to 100 characters. |
user_last_namestring | Up to 100 characters. |
user_emailstring (email) | Up to 255 characters. |
user_positionstring | Job title. Up to 100 characters. |
user_timezonestring | IANA time zone, such as Europe/Berlin. Only for yourself. |
Responses
| Status | Description |
|---|---|
200 | message is user updated successfully. |
400 | invalid input: user_id when it's missing or isn't a UUID, invalid json, input too long when user_first_name, user_last_name or user_position is over 100 characters, invalid input: user_first_name, invalid input: user_last_name or invalid input: user_position when that field has a control character such as a line break, invalid email when user_email isn't a valid address of 255 characters or fewer or invalid timezone when user_timezone isn't an IANA time zone. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this, you sent user_timezone for someone else or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
409 | email already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Delete a user
DELETE /api/internal/user
You can't delete yourself, the owner or a team's last admin.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query, required | User ID. |
Responses
| Status | Description |
|---|---|
200 | message is user deleted successfully. |
400 | invalid input: user_id when it's missing or isn't a UUID, cannot delete self, cannot delete account owner or cannot delete the last admin of a team. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List a user's apps
GET /api/internal/user/apps
Apps the user can open that you can see, sorted by name. 403 when you can't see apps.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query, required | User ID. |
Responses
| Status | Description |
|---|---|
200 | The user and their apps. user has only user_id, user_first_name and user_last_name filled in. |
400 | invalid input: user_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
userobject, required | A user. Fields an endpoint doesn't load are empty or left out. Dates it doesn't load are 0001-01-01T00:00:00Z. |
user.user_idstring (uuid) | |
user.account_idstring (uuid) | The user's organization. |
user.user_first_namestring, required | |
user.user_last_namestring, required | |
user.user_positionstring, required | Job title. |
user.user_emailstring (email), required | |
user.user_settingsobject | Stored settings, such as timezone. |
user.user_timezonestring | IANA time zone, such as Europe/Berlin. |
user.user_createdstring (date-time), required | |
user.user_updatedstring (date-time), required | |
user.user_created_bystring (uuid) | The user who invited this one. |
appsarray of objects, required | |
apps[].app_idstring (uuid) | |
apps[].account_idstring (uuid) | The organization that registered the app. |
apps[].app_namestring | |
apps[].app_urlstring (uri) | |
apps[].app_logostring | |
apps[].app_logo_typestring | |
apps[].app_createdstring (date-time), required | |
apps[].app_updatedstring (date-time), required | |
apps[].app_created_bystring (uuid) | |
apps[].share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
apps[].app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
List a user's teams
GET /api/internal/user/teams
Teams the user is on that you can see, sorted by name. 403 when you can't see teams.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query, required | User ID. |
Responses
| Status | Description |
|---|---|
200 | The user and their teams. user has only user_id, user_first_name and user_last_name filled in. teams is [] when there are none. |
400 | invalid input: user_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
userobject, required | A user. Fields an endpoint doesn't load are empty or left out. Dates it doesn't load are 0001-01-01T00:00:00Z. |
user.user_idstring (uuid) | |
user.account_idstring (uuid) | The user's organization. |
user.user_first_namestring, required | |
user.user_last_namestring, required | |
user.user_positionstring, required | Job title. |
user.user_emailstring (email), required | |
user.user_settingsobject | Stored settings, such as timezone. |
user.user_timezonestring | IANA time zone, such as Europe/Berlin. |
user.user_createdstring (date-time), required | |
user.user_updatedstring (date-time), required | |
user.user_created_bystring (uuid) | The user who invited this one. |
teamsarray of objects, required | |
teams[].team_idstring (uuid) | |
teams[].account_idstring (uuid) | The team's organization. |
teams[].team_namestring, required | |
teams[].team_settingsobject | |
teams[].team_createdstring (date-time) | |
teams[].team_updatedstring (date-time) | |
teams[].team_created_bystring (uuid) |
Get a user's roles and permissions
GET /api/internal/user/access
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query | User ID. Leave it out for yourself. |
Responses
| Status | Description |
|---|---|
200 | The user's roles and what each one allows. |
400 | invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
user_idstring (uuid), required | |
user_first_namestring, required | |
user_last_namestring, required | |
role_actionsobject, required | Permission keys by role key. Roles without permissions are left out. |
role_actions.{key}array of strings | |
rolesarray of objects, required | |
roles[].role_keystring, required | |
roles[].role_namestring, required | |
roles[].role_descriptionstring | |
roles[].role_typestring | One of default or custom. |
roles[].account_idstring (uuid) | The organization a custom role belongs to. |
roles[].user_countinteger | Users in your organization with this role. Left out when 0. |
roles[].can_removeboolean, required | You can remove this role from the user. |
roles[].permissionsarray of objects, required | |
roles[].permissions[].permission_idstring (uuid) | |
roles[].permissions[].permission_keystring, required | |
roles[].permissions[].permission_namestring, required | |
roles[].permissions[].permission_descriptionstring | |
roles[].permissions[].permission_role_countinteger | Roles with this permission. Left out when 0. |
roles[].permissions[].permission_user_countinteger | Users you can see who hold it. Left out when 0. |
Give roles to a user
POST /api/internal/user/roles
Gives the user every role in roles. You can't give account_owner: transfer ownership instead.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
user_idstring (uuid) | |
user_emailstring (email) | Up to 255 characters. |
rolesarray of strings, required | At least 1 item. |
Responses
| Status | Description |
|---|---|
200 | message is roles assigned to followed by the user_email you sent, trimmed and lowercased, or else the user_id you sent. |
400 | invalid json, invalid input: user_id when you send neither user_id nor user_email or user_id isn't a UUID, invalid email when user_email isn't a valid address of 255 characters or fewer, role required when roles is empty, or invalid input: roles when a role key isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | user not found for role or role not found: followed by the unknown role keys. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Remove a role from a user
DELETE /api/internal/user/roles
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query, required | User ID. |
role_keystring in query, required | Role key, such as user_admin. Up to 100 characters. |
Responses
| Status | Description |
|---|---|
200 | message is role revoked from user. |
400 | invalid input: user_id when it's missing or isn't a UUID. invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | role not found or user does not hold this role. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List a user's AI clients
GET /api/internal/user/ai-clients
Live AI client connections, newest first. To see another user's connections, you need permission to edit that user.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
user_idstring (uuid) in query | User ID. Leave it out for yourself. |
Responses
| Status | Description |
|---|---|
200 | The connections. |
400 | invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
itemsarray of objects, required | |
items[].idstring (uuid), required | Connection ID. |
items[].hoststring, required | Host of the client's HTTPS client ID. unverified when it has none. |
items[].targetstring, required | The app the client connects to. For platform connections, our platform's name. |
items[].grantstring or null, required | read or write for platform connections. null for app connections. One of read, write or null. |
items[].createdstring (date-time), required | |
items[].usedstring (date-time), required | |
items[].expiresstring (date-time), required | |
items[].is_currentboolean, required | Always false here. |
items[].untrustedobject, required | |
items[].untrusted.clientstring, required | The name the client gave itself. Not verified. |
Disconnect an AI client
POST /api/internal/user/ai-clients
Ends one AI client connection. To end another user's connection, you need permission to edit that user.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
user_idstring (uuid) | Whose connection. Leave it out for yourself. |
connection_idstring (uuid), required |
Responses
| Status | Description |
|---|---|
200 | Disconnected. |
400 | invalid json, invalid input: user_id or invalid input: connection_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | connection not found, also when you aren't allowed to end it. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
disconnectedboolean, required | Always true. |
List roles
GET /api/internal/roles
Default roles and your organization's custom roles, sorted by name. Needs permission to edit users.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Responses
| Status | Description |
|---|---|
200 | The roles. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
role_keystring, required | |
role_namestring, required | |
role_descriptionstring | |
role_typestring | One of default or custom. |
account_idstring (uuid) | The organization a custom role belongs to. |
user_countinteger | Users in your organization with this role. Left out when 0. |
Get a role
GET /api/internal/role
Needs permission to edit users.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
role_keystring in query, required | Role key, such as user_admin. Up to 100 characters. |
Responses
| Status | Description |
|---|---|
200 | The role, with user_count when anyone holds it. |
400 | invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
role_keystring, required | |
role_namestring, required | |
role_descriptionstring | |
role_typestring | One of default or custom. |
account_idstring (uuid) | The organization a custom role belongs to. |
user_countinteger | Users in your organization with this role. Left out when 0. |
Create a role
POST /api/internal/role
Creates a custom role for your organization. Add permissions to it with POST /api/internal/role/permissions.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
role_keystring, required | Matches ^[a-z0-9_]{1,100}$. |
role_namestring, required | Up to 100 characters. |
role_descriptionstring | Up to 500 characters. |
Responses
| Status | Description |
|---|---|
200 | message is custom role created: followed by the role name. |
400 | invalid json, invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores, role_name required when role_name is missing or blank or input too long when role_name is over 100 characters or role_description is over 500. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
409 | role already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Update a role
PUT /api/internal/role
Renames a custom role or changes its description. Fields you leave out stay as they are.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
role_keystring, required | Up to 100 characters. |
role_namestring | Up to 100 characters. |
role_descriptionstring | Up to 500 characters. |
Responses
| Status | Description |
|---|---|
200 | message is custom role updated successfully. |
400 | invalid json, invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores, invalid input: nothing to change when neither role_name nor role_description is sent, role_name required when role_name is blank or input too long when role_name is over 100 characters or role_description is over 500. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Delete a role
DELETE /api/internal/role
Deletes a custom role. Default roles can't be deleted.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
role_keystring in query, required | Role key, such as user_admin. Up to 100 characters. |
Responses
| Status | Description |
|---|---|
200 | message is custom role deleted successfully. |
400 | invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List permissions
GET /api/internal/permissions
Every permission you can put in a role, sorted by name. Needs permission to edit users.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Responses
| Status | Description |
|---|---|
200 | The permissions. Each has only permission_key and permission_name. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
permission_idstring (uuid) | |
permission_keystring, required | |
permission_namestring, required | |
permission_descriptionstring | |
permission_role_countinteger | Roles with this permission. Left out when 0. |
permission_user_countinteger | Users you can see who hold it. Left out when 0. |
Get a permission
GET /api/internal/permission
Needs permission to edit users. Without it you get 404.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
permission_keystring in query, required | Permission key, such as view_any_user. |
Responses
| Status | Description |
|---|---|
200 | The permission, with how many roles have it and how many users you can see hold it. |
400 | invalid input: permission_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
permission_idstring (uuid) | |
permission_keystring, required | |
permission_namestring, required | |
permission_descriptionstring | |
permission_role_countinteger | Roles with this permission. Left out when 0. |
permission_user_countinteger | Users you can see who hold it. Left out when 0. |
List a role's permissions
GET /api/internal/role/permissions
Needs permission to edit users.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
role_keystring in query, required | Role key, such as user_admin. Up to 100 characters. |
Responses
| Status | Description |
|---|---|
200 | The role's permissions, sorted by name, each with only permission_key and permission_name. [] when the role has none. |
400 | invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
permission_idstring (uuid) | |
permission_keystring, required | |
permission_namestring, required | |
permission_descriptionstring | |
permission_role_countinteger | Roles with this permission. Left out when 0. |
permission_user_countinteger | Users you can see who hold it. Left out when 0. |
Add permissions to a role
POST /api/internal/role/permissions
Adds permissions to a custom role, along with any view permissions they need.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
role_keystring, required | Up to 100 characters. |
permission_keysarray of strings, required | At least 1 item. |
Responses
| Status | Description |
|---|---|
200 | message is permissions added successfully. When view permissions were added too, it goes on with ; also added the view permissions they need: and their keys. |
400 | invalid json, invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores, permission required when permission_keys is empty or invalid input: permission_keys when one of them isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | role not found or permission not found: followed by the unknown keys. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Remove permissions from a role
DELETE /api/internal/role/permissions
Removes permissions from a custom role. This one takes a JSON body.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
role_keystring, required | Up to 100 characters. |
permission_keysarray of strings, required | At least 1 item. |
Responses
| Status | Description |
|---|---|
200 | message is permissions removed successfully. |
400 | invalid json, invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores, permission required when permission_keys is empty or invalid input: permission_keys when one of them isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | role not found, permission not found or permission not found: followed by the unknown keys. |
409 | another permission in this role requires it. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List users with a role
GET /api/internal/role/users
Users with the role that you can see. Needs permission to edit users.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
role_keystring in query, required | Role key, such as user_admin. Up to 100 characters. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | The role and one page of its users. users is [] when there are none. |
400 | invalid input: role_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores, invalid input: q, invalid input: limit or invalid input: cursor. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, object.
| Field | Description |
|---|---|
roleobject, required | |
role.role_keystring, required | |
role.role_namestring, required | |
role.role_descriptionstring | |
role.role_typestring | One of default or custom. |
role.account_idstring (uuid) | The organization a custom role belongs to. |
role.user_countinteger | Users in your organization with this role. Left out when 0. |
usersarray of objects, required | |
users[].user_idstring (uuid) | |
users[].account_idstring (uuid) | The user's organization. |
users[].user_first_namestring, required | |
users[].user_last_namestring, required | |
users[].user_positionstring, required | Job title. |
users[].user_emailstring (email), required | |
users[].user_settingsobject | Stored settings, such as timezone. |
users[].user_timezonestring | IANA time zone, such as Europe/Berlin. |
users[].user_createdstring (date-time), required | |
users[].user_updatedstring (date-time), required | |
users[].user_created_bystring (uuid) | The user who invited this one. |
List roles with a permission
GET /api/internal/permission/roles
Default roles first, then your custom roles. Needs permission to edit users. You get 404 without it or when no role has the permission.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
permission_keystring in query, required | Permission key, such as view_any_user. |
Responses
| Status | Description |
|---|---|
200 | The permission and its roles. |
400 | invalid input: permission_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
permissionobject, required | |
permission.permission_idstring (uuid) | |
permission.permission_keystring, required | |
permission.permission_namestring, required | |
permission.permission_descriptionstring | |
permission.permission_role_countinteger | Roles with this permission. Left out when 0. |
permission.permission_user_countinteger | Users you can see who hold it. Left out when 0. |
rolesarray of objects, required | |
roles[].role_keystring, required | |
roles[].role_namestring, required | |
roles[].role_descriptionstring | |
roles[].role_typestring | One of default or custom. |
roles[].account_idstring (uuid) | The organization a custom role belongs to. |
roles[].user_countinteger | Users in your organization with this role. Left out when 0. |
List users with a permission
GET /api/internal/permission/users
Users you can see who hold the permission through any role. Needs permission to edit users. Without it you get 404.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
permission_keystring in query, required | Permission key, such as view_any_user. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | The permission and one page of users. users is [] when there are none. |
400 | invalid input: permission_key when it's missing or isn't 1 to 100 lowercase letters, digits or underscores, invalid input: q, invalid input: limit or invalid input: cursor. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, object.
| Field | Description |
|---|---|
permissionobject, required | |
permission.permission_idstring (uuid) | |
permission.permission_keystring, required | |
permission.permission_namestring, required | |
permission.permission_descriptionstring | |
permission.permission_role_countinteger | Roles with this permission. Left out when 0. |
permission.permission_user_countinteger | Users you can see who hold it. Left out when 0. |
usersarray of objects, required | |
users[].user_idstring (uuid) | |
users[].account_idstring (uuid) | The user's organization. |
users[].user_first_namestring, required | |
users[].user_last_namestring, required | |
users[].user_positionstring, required | Job title. |
users[].user_emailstring (email), required | |
users[].user_settingsobject | Stored settings, such as timezone. |
users[].user_timezonestring | IANA time zone, such as Europe/Berlin. |
users[].user_createdstring (date-time), required | |
users[].user_updatedstring (date-time), required | |
users[].user_created_bystring (uuid) | The user who invited this one. |
List teams
GET /api/internal/teams
Teams you can see, sorted by name. If you can assign partners to teams, you also get every other team by name only.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
statestring in query | empty lists only teams with at most 1 member that you can add people to. One of empty. |
Responses
| Status | Description |
|---|---|
200 | One page of teams. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
team_idstring (uuid) | |
account_idstring (uuid) | The team's organization. |
team_namestring, required | |
team_settingsobject | |
team_createdstring (date-time) | |
team_updatedstring (date-time) | |
team_created_bystring (uuid) | |
team_you_are_adminboolean, required |
Get a team
GET /api/internal/team
Returns the team and its counts. For members and what you can do with them, use GET /api/internal/team/members.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
Responses
| Status | Description |
|---|---|
200 | The team. team_members is left out. |
400 | invalid input: team_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
team_idstring (uuid) | |
account_idstring (uuid) | The team's organization. |
team_namestring, required | |
team_settingsobject | |
team_createdstring (date-time) | |
team_updatedstring (date-time) | |
team_created_bystring (uuid) | |
team_member_countinteger | Left out when 0. |
team_app_countinteger | Apps shared with the team that you can see. Left out when 0. |
team_managed_partner_countinteger | Partners the team manages that you can see. Left out when 0. |
team_admin_countinteger, required | |
team_you_are_adminboolean, required | |
user_can_add_users_to_this_teamboolean, required | Whether you can add people to this team. |
user_can_manage_adminsboolean, required | Whether you can make and remove this team's admins. |
team_membersarray of objects | |
team_members[].user_idstring (uuid) | |
team_members[].account_idstring (uuid) | The user's organization. |
team_members[].user_first_namestring, required | |
team_members[].user_last_namestring, required | |
team_members[].user_positionstring, required | Job title. |
team_members[].user_emailstring (email), required | |
team_members[].user_settingsobject | Stored settings, such as timezone. |
team_members[].user_timezonestring | IANA time zone, such as Europe/Berlin. |
team_members[].user_createdstring (date-time), required | |
team_members[].user_updatedstring (date-time), required | |
team_members[].user_created_bystring (uuid) | The user who invited this one. |
team_members[].user_is_team_adminboolean, required | |
team_members[].assigned_atstring (date-time), required | When they joined the team. |
team_members[].user_can_remove_this_user_from_this_teamboolean, required | |
team_members[].user_can_make_adminboolean, required | |
team_members[].user_can_remove_adminboolean, required | |
team_members[].user_can_viewboolean, required | You can open this user's page. |
Create a team
POST /api/internal/team
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
team_namestring, required | Up to 255 characters. |
team_admin_idstring (uuid), required | The team's first admin. |
team_settingsobject |
Responses
| Status | Description |
|---|---|
200 | message is team created successfully. |
400 | invalid json, team_name required, input too long when team_name is over 255 characters, team_admin_id required or team admin invalid when team_admin_id isn't a person in your organization. |
401 | missing authorization header or invalid session. |
403 | forbidden, team quota exceeded or team membership quota exceeded. |
409 | team already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required | |
team_idstring (uuid), required |
Update a team
PUT /api/internal/team
Changes the name or settings. Change admins with PUT /api/internal/team/member.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
team_idstring (uuid), required | |
team_namestring | Up to 255 characters. |
team_settingsobject |
Responses
| Status | Description |
|---|---|
200 | message is team updated successfully. |
400 | invalid json, invalid input: team_id or input too long when team_name is over 255 characters. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | team not found. |
409 | team already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Delete a team
DELETE /api/internal/team
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
Responses
| Status | Description |
|---|---|
200 | message is team deleted successfully. |
400 | invalid input: team_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List team members
GET /api/internal/team/members
The team and one page of its members, sorted by first name, then last name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | The team with team_members. team_app_count and team_managed_partner_count are left out here. team_members is [] when no member matches. |
400 | invalid input: team_id when it's missing or isn't a UUID, invalid input: q, invalid input: limit or invalid input: cursor. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, object.
| Field | Description |
|---|---|
team_idstring (uuid) | |
account_idstring (uuid) | The team's organization. |
team_namestring, required | |
team_settingsobject | |
team_createdstring (date-time) | |
team_updatedstring (date-time) | |
team_created_bystring (uuid) | |
team_member_countinteger | Left out when 0. |
team_app_countinteger | Apps shared with the team that you can see. Left out when 0. |
team_managed_partner_countinteger | Partners the team manages that you can see. Left out when 0. |
team_admin_countinteger, required | |
team_you_are_adminboolean, required | |
user_can_add_users_to_this_teamboolean, required | Whether you can add people to this team. |
user_can_manage_adminsboolean, required | Whether you can make and remove this team's admins. |
team_membersarray of objects | |
team_members[].user_idstring (uuid) | |
team_members[].account_idstring (uuid) | The user's organization. |
team_members[].user_first_namestring, required | |
team_members[].user_last_namestring, required | |
team_members[].user_positionstring, required | Job title. |
team_members[].user_emailstring (email), required | |
team_members[].user_settingsobject | Stored settings, such as timezone. |
team_members[].user_timezonestring | IANA time zone, such as Europe/Berlin. |
team_members[].user_createdstring (date-time), required | |
team_members[].user_updatedstring (date-time), required | |
team_members[].user_created_bystring (uuid) | The user who invited this one. |
team_members[].user_is_team_adminboolean, required | |
team_members[].assigned_atstring (date-time), required | When they joined the team. |
team_members[].user_can_remove_this_user_from_this_teamboolean, required | |
team_members[].user_can_make_adminboolean, required | |
team_members[].user_can_remove_adminboolean, required | |
team_members[].user_can_viewboolean, required | You can open this user's page. |
Add team members
POST /api/internal/team/members
Adds people from your organization to the team. 200 when none failed, 207 when any did. details has one entry per ID.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
team_idstring (uuid), required | |
member_idsarray of strings (uuid), required | User IDs. At least 1 item. |
Responses
| Status | Description |
|---|---|
200 | message is team members added successfully. |
207 | Some or all failed. |
400 | invalid json, invalid input: team_id, required parameters missing when member_ids is empty or invalid input: member_ids when one of them isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | team not found. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 and 207 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required | One of team members added successfully, some team members added successfully, some failed or all team members failed to be added. |
detailsarray of objects | |
details[].user_idstring (uuid), required | |
details[].statusstring, required | assigned, already_member, duplicate_input_skipped, user_not_found or why it failed. |
Make or remove a team admin
PUT /api/internal/team/member
Makes a member a team admin or removes their admin role. A team always keeps at least 1 admin.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
user_idstring (uuid) in query, required | User ID. |
Request body
application/json, object.
| Field | Description |
|---|---|
is_adminboolean, required | true makes the member an admin. false removes their admin role. |
Responses
| Status | Description |
|---|---|
200 | message is team admin added or team admin removed. |
400 | invalid input: team_id or invalid input: user_id when that parameter is missing or isn't a UUID. invalid json or cannot remove the last admin of a team. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | user not found: the user isn't on this team. |
409 | team admin unchanged. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Remove a team member
DELETE /api/internal/team/member
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
user_idstring (uuid) in query, required | User ID. |
Responses
| Status | Description |
|---|---|
200 | message is team member removed successfully. |
400 | invalid input: team_id or invalid input: user_id when that parameter is missing or isn't a UUID. cannot remove the last admin of a team. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | not found or user is not a member of this team. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List a team's apps
GET /api/internal/team/apps
Apps shared with the team that you can see, sorted by name. 403 when you can't see apps.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
Responses
| Status | Description |
|---|---|
200 | The team and its apps. team has only team_id and team_name. apps is [] when there are none. |
400 | invalid input: team_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
teamobject, required | A team. Fields an endpoint doesn't load are left out. |
team.team_idstring (uuid) | |
team.account_idstring (uuid) | The team's organization. |
team.team_namestring, required | |
team.team_settingsobject | |
team.team_createdstring (date-time) | |
team.team_updatedstring (date-time) | |
team.team_created_bystring (uuid) | |
appsarray of objects, required | |
apps[].app_idstring (uuid) | |
apps[].account_idstring (uuid) | The organization that registered the app. |
apps[].app_namestring | |
apps[].app_urlstring (uri) | |
apps[].app_logostring | |
apps[].app_logo_typestring | |
apps[].app_createdstring (date-time), required | |
apps[].app_updatedstring (date-time), required | |
apps[].app_created_bystring (uuid) | |
apps[].share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
apps[].app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
List a team's partners
GET /api/internal/team/partners
Partner organizations the team manages, sorted by name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | One page of partners. |
400 | invalid input: team_id when it's missing or isn't a UUID, invalid input: q, invalid input: limit or invalid input: cursor. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
account_idstring (uuid) | |
parent_idstring (uuid) | The organization directly above. |
account_namestring, required | |
account_countrystring, required | |
account_levelstring, required | One of root, partner or subpartner. |
account_typestring, required | |
account_planstring, required | One of free, pilot, premium or root. |
account_settingsobject | |
account_createdstring (date-time), required | |
account_updatedstring (date-time), required | |
account_expirystring (date-time), required | When the organization's access ends. |
Assign a partner to a team
POST /api/internal/team/partner
The team then manages that partner organization.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
team_idstring (uuid), required | |
partner_account_idstring (uuid), required |
Responses
| Status | Description |
|---|---|
200 | message is partner assigned to team successfully. |
400 | invalid json, invalid input: team_id or invalid input: partner_account_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | team not found or account not found. |
409 | already exists: the team already manages this partner. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Unassign a partner from a team
DELETE /api/internal/team/partner
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
team_idstring (uuid) in query, required | Team ID. |
partner_account_idstring (uuid) in query, required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | message is partner unassigned from team successfully. |
400 | invalid input: team_id or invalid input: partner_account_id when that parameter is missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | partner not found or team not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List apps
GET /api/internal/apps
Apps your organization registered or received that you can see, sorted by name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
statestring in query | organization: available to everyone. unassigned or undistributed: not yet available to everyone or any team. received: shared with your organization by another one. One of organization, unassigned, undistributed or received. |
Responses
| Status | Description |
|---|---|
200 | One page of apps. Each has app_id, account_id, app_name, app_url, app_logo, app_logo_type and share_state filled in. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | not found: state=unassigned with no q or cursor found nothing. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
app_idstring (uuid) | |
account_idstring (uuid) | The organization that registered the app. |
app_namestring | |
app_urlstring (uri) | |
app_logostring | |
app_logo_typestring | |
app_createdstring (date-time), required | |
app_updatedstring (date-time), required | |
app_created_bystring (uuid) | |
share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
Get an app
GET /api/internal/app
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
Responses
| Status | Description |
|---|---|
200 | The app and what you can do with it. |
400 | invalid input: app_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
appobject, required | |
app.app_idstring (uuid) | |
app.account_idstring (uuid) | The organization that registered the app. |
app.app_namestring | |
app.app_urlstring (uri) | |
app.app_logostring | |
app.app_logo_typestring | |
app.app_createdstring (date-time), required | |
app.app_updatedstring (date-time), required | |
app.app_created_bystring (uuid) | |
app.share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
app.app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
app.creator_idstring (uuid) | |
app.creator_first_namestring | |
app.creator_last_namestring | |
app.creator_is_youboolean, required | |
app.app_users_countinteger | People in your organization who can open it. Left out when 0. |
app.app_teams_countinteger | Teams in your organization it's shared with. Left out when 0. |
app.app_partners_countinteger | Partners it's shared with. Left out when 0. |
app.user_can_view_this_appboolean, required | Always true. |
app.user_can_edit_this_appboolean, required | |
app.user_can_delete_this_appboolean, required | |
app.user_can_share_this_appboolean, required | You can share it with everyone, teams or partners. |
app.user_can_share_to_accountboolean, required | You can make it available to everyone. |
app.user_can_share_to_teamsboolean, required | |
app.user_can_share_to_partnersboolean, required | |
app.user_can_unshare_this_appboolean, required | |
app.user_can_view_this_app_usersboolean, required | |
app.user_can_view_this_app_teamsboolean, required | |
app.user_can_view_this_app_partnersboolean, required | |
app.user_can_view_creatorboolean, required | |
app.is_shared_with_user_accountboolean, required | The app is available to everyone in your organization. |
app.is_receivedboolean, required | Another organization registered the app and shared it with yours. |
app.owner_namestring | Name of the organization that registered the app. |
Register an app
POST /api/internal/app
Registers an app for your organization. The response is the only time you see app_secret.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
app_namestring, required | Up to 255 characters. |
app_urlstring (uri), required | HTTPS URL of the app. Saved in lowercase. |
app_logostring, required | |
app_logo_typestring, required | |
app_mcp_urlstring (uri) | HTTPS URL of the app's MCP endpoint, if it has one. |
Responses
| Status | Description |
|---|---|
200 | message is app registered successfully. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden or app quota exceeded. |
409 | app already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required | |
app_idstring (uuid), required | |
app_secretstring, required | Shown only here. Store it now. Exactly 64 characters. |
Update an app
PUT /api/internal/app
Changes only the fields you send. Send at least 1.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
Request body
application/json, object.
| Field | Description |
|---|---|
app_namestring | Up to 255 characters. |
app_urlstring (uri) | HTTPS URL of the app. |
app_logostring | |
app_logo_typestring | |
app_mcp_urlstring | HTTPS URL of the app's MCP endpoint. An empty string removes it. |
Responses
| Status | Description |
|---|---|
200 | message is app updated successfully. |
400 | invalid input: app_id when it's missing or isn't a UUID, invalid json, input too long when app_name is over 255 characters, invalid app url, invalid app mcp url or required parameters missing when nothing changes. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
409 | app already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Delete an app
DELETE /api/internal/app
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
Responses
| Status | Description |
|---|---|
200 | message is app deleted successfully. |
400 | invalid input: app_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Rotate an app secret
POST /api/internal/app/secret
Creates a new secret for an app your organization registered. The old one stops working at once, so every SDK still using it fails until you update it. The response is the only time you see the new one. Needs permission to edit the app.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
Responses
| Status | Description |
|---|---|
200 | The new secret. |
400 | invalid input: app_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
200 body: application/json, object.
| Field | Description |
|---|---|
app_secretstring, required | Exactly 64 characters. |
List an app's teams
GET /api/internal/app/teams
Teams in your organization the app is shared with, sorted by name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | The app and one page of teams. app has only app_id and app_name. |
400 | invalid input: app_id when it's missing or isn't a UUID, invalid input: q, invalid input: limit or invalid input: cursor. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, object.
| Field | Description |
|---|---|
appobject, required | An app. Fields an endpoint doesn't load are left out. Dates it doesn't load are 0001-01-01T00:00:00Z. |
app.app_idstring (uuid) | |
app.account_idstring (uuid) | The organization that registered the app. |
app.app_namestring | |
app.app_urlstring (uri) | |
app.app_logostring | |
app.app_logo_typestring | |
app.app_createdstring (date-time), required | |
app.app_updatedstring (date-time), required | |
app.app_created_bystring (uuid) | |
app.share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
app.app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
teamsarray of objects, required | |
teams[].team_idstring (uuid), required | |
teams[].team_namestring, required | |
teams[].access_view_this_teamboolean, required | |
teams[].access_stop_sharing_app_with_this_teamboolean, required |
List who can open an app
GET /api/internal/app/users
People you can see who can open an app your organization registered. App admins can open every app. Others get it through a team. users is empty when the app is available to everyone.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | The app and one page of users. app has only app_id and app_name. |
400 | invalid input: app_id when it's missing or isn't a UUID, invalid input: q, invalid input: limit or invalid input: cursor. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found, also for apps your organization received from another one. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, object.
| Field | Description |
|---|---|
appobject, required | An app. Fields an endpoint doesn't load are left out. Dates it doesn't load are 0001-01-01T00:00:00Z. |
app.app_idstring (uuid) | |
app.account_idstring (uuid) | The organization that registered the app. |
app.app_namestring | |
app.app_urlstring (uri) | |
app.app_logostring | |
app.app_logo_typestring | |
app.app_createdstring (date-time), required | |
app.app_updatedstring (date-time), required | |
app.app_created_bystring (uuid) | |
app.share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
app.app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
usersarray of objects, required | |
users[].user_idstring (uuid), required | |
users[].user_first_namestring, required | |
users[].user_last_namestring, required | |
users[].user_emailstring (email), required | |
users[].user_positionstring, required | |
users[].access_view_this_userboolean, required | Always true. |
List an app's partners
GET /api/internal/app/partners
Partner organizations you can see that an app your organization registered is shared with, sorted by name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | The app and one page of partners. app has only app_id and app_name. |
400 | invalid input: app_id when it's missing or isn't a UUID, invalid input: q, invalid input: limit or invalid input: cursor. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found, also for apps your organization received from another one. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, object.
| Field | Description |
|---|---|
appobject, required | An app. Fields an endpoint doesn't load are left out. Dates it doesn't load are 0001-01-01T00:00:00Z. |
app.app_idstring (uuid) | |
app.account_idstring (uuid) | The organization that registered the app. |
app.app_namestring | |
app.app_urlstring (uri) | |
app.app_logostring | |
app.app_logo_typestring | |
app.app_createdstring (date-time), required | |
app.app_updatedstring (date-time), required | |
app.app_created_bystring (uuid) | |
app.share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
app.app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
partnersarray of objects, required | |
partners[].account_idstring (uuid), required | |
partners[].account_namestring, required | |
partners[].access_stop_sharing_app_with_this_partnerboolean, required |
Make an app available to everyone
POST /api/internal/app/account
Everyone in your organization can then open the app.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
app_idstring (uuid), required | |
account_idstring (uuid) | Your organization's ID. Any other value returns 400. |
Responses
| Status | Description |
|---|---|
200 | message is app shared with account successfully. |
400 | invalid json, invalid input: app_id or invalid input when account_id isn't your organization's ID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found. |
409 | app already shared with the organization. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Stop sharing an app with everyone
DELETE /api/internal/app/account
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
account_idstring (uuid) in query | Your organization's ID. Any other value returns 400. |
Responses
| Status | Description |
|---|---|
200 | message is app unshared from account successfully. |
400 | invalid input: app_id when it's missing or isn't a UUID. invalid input when account_id isn't your organization's ID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found or app is not shared there. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Share an app with a team
POST /api/internal/app/team
Members of the team can then open the app.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
app_idstring (uuid), required | |
team_idstring (uuid), required |
Responses
| Status | Description |
|---|---|
200 | message is app shared with team successfully. |
400 | invalid json, invalid input: app_id or invalid input: team_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found or team not found. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Stop sharing an app with a team
DELETE /api/internal/app/team
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
team_idstring (uuid) in query, required | Team ID. |
Responses
| Status | Description |
|---|---|
200 | message is app unshared from team successfully. |
400 | invalid input: app_id or invalid input: team_id when that parameter is missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found or app is not shared there. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Share an app with a partner
POST /api/internal/app/partner
Shares an app your organization registered with a partner organization. Its members see the app only after its app admins distribute it.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
Request body
application/json, object.
| Field | Description |
|---|---|
partner_idstring (uuid), required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | message is app shared with account successfully. |
400 | invalid json. invalid input: app_id when it's missing or isn't a UUID. invalid input: partner_id when partner_id is missing, your own organization or not a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found or partner not found. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Stop sharing an app with a partner
DELETE /api/internal/app/partner
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
app_idstring (uuid) in query, required | App ID. |
partner_account_idstring (uuid) in query, required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | message is app unshared from account successfully. |
400 | invalid input: app_id when it's missing or isn't a UUID. invalid input: partner_account_id when it's missing, your own organization or not a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | app not found, partner not found or app is not shared there. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List partners
GET /api/internal/partners
Partner organizations directly below yours that you can see.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
statestring in query | active (the default) sorts by name. expiring lists partners close to expiry, soonest first. closed lists closed partners, most recently closed first. It needs permission to see every partner. One of active, expiring or closed. |
Responses
| Status | Description |
|---|---|
200 | One page of partners. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
account_idstring (uuid), required | |
account_namestring, required | |
account_expirystring (date-time), required |
Get a partner
GET /api/internal/partner
A partner organization directly below yours, open or closed.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
partner_idstring (uuid) in query, required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | The partner. total_available_apps counts the apps your organization shared with it that you can see. A closed partner has no owner or totals. Its account_updated is when it closed. |
400 | invalid input: partner_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
account_idstring (uuid) | |
parent_idstring (uuid) | The organization directly above. |
account_namestring, required | |
account_countrystring, required | |
account_levelstring, required | One of root, partner or subpartner. |
account_typestring, required | |
account_planstring, required | One of free, pilot, premium or root. |
account_settingsobject | |
account_createdstring (date-time), required | |
account_updatedstring (date-time), required | |
account_expirystring (date-time), required | When the organization's access ends. |
owner_idstring (uuid) | |
owner_first_namestring | |
owner_last_namestring | |
owner_positionstring | |
owner_emailstring (email) | |
total_teamsinteger | |
total_usersinteger | |
total_owned_appsinteger | Apps the organization registered. |
total_available_appsinteger | |
managed_byarray of objects, required | Teams in your organization that manage this partner. |
managed_by[].team_idstring (uuid), required | |
managed_by[].team_namestring, required |
Close a partner
POST /api/internal/partner/close
Closes a partner organization and removes everything under it. This is final.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
partner_idstring (uuid) in query, required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | message is partner closed successfully. |
400 | invalid input: partner_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Extend a partner's expiry
POST /api/internal/partner/expiry
Moves a partner organization's expiry to a later date.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
partner_idstring (uuid) in query, required | Partner organization ID. |
Request body
application/json, object.
| Field | Description |
|---|---|
target_expiry_datestring (date), required | The new expiry date, such as 2026-12-31. |
Responses
| Status | Description |
|---|---|
200 | message is partner expiry extended successfully. |
400 | invalid json or invalid input: partner_id when it's missing or isn't a UUID. extension must be between 1 and 3 months when target_expiry_date is missing, isn't YYYY-MM-DD or isn't later than both today and the current expiry. extension would exceed maximum allowed expiry date when it's more than 90 days from now. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
409 | The expiry can't be extended yet. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
List apps shared with a partner
GET /api/internal/partner/apps
Apps your organization shared with the partner that you can see, sorted by name. share_state shows how far the partner has distributed each one.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
partner_idstring (uuid) in query, required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | The partner's name and its apps. |
400 | invalid input: partner_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
partner_namestring, required | |
appsarray of objects, required | |
apps[].app_idstring (uuid) | |
apps[].account_idstring (uuid) | The organization that registered the app. |
apps[].app_namestring | |
apps[].app_urlstring (uri) | |
apps[].app_logostring | |
apps[].app_logo_typestring | |
apps[].app_createdstring (date-time), required | |
apps[].app_updatedstring (date-time), required | |
apps[].app_created_bystring (uuid) | |
apps[].share_statestring | How far your organization has distributed the app: pending (not yet), teams (chosen teams) or organization (everyone). One of pending, teams or organization. |
apps[].app_mcp_urlstring (uri) | The app's MCP endpoint, when set. |
Get a partner's limits
GET /api/internal/partner/limits
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
partner_idstring (uuid) in query, required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | The partner's plan, limits and use. |
400 | invalid input: partner_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
account_idstring (uuid), required | |
account_namestring, required | |
account_planstring, required | |
limitsobject, required | |
limits.usersobject, required | |
limits.users.currentinteger, required | |
limits.users.maxinteger, required | |
limits.users.remaininginteger, required | -1 when max is 0 or current is over max. |
limits.teamsobject, required | |
limits.teams.currentinteger, required | |
limits.teams.maxinteger, required | |
limits.teams.remaininginteger, required | -1 when max is 0 or current is over max. |
limits.appsobject, required | |
limits.apps.currentinteger, required | |
limits.apps.maxinteger, required | |
limits.apps.remaininginteger, required | -1 when max is 0 or current is over max. |
limits.partnersobject, required | |
limits.partners.currentinteger, required | |
limits.partners.maxinteger, required | |
limits.partners.remaininginteger, required | -1 when max is 0 or current is over max. |
List teams managing a partner
GET /api/internal/partner/teams
Teams in your organization that manage the partner, sorted by name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
partner_idstring (uuid) in query, required | Partner organization ID. |
Responses
| Status | Description |
|---|---|
200 | The teams. |
400 | invalid input: partner_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
team_idstring (uuid), required | |
team_namestring, required |
List signups
GET /api/internal/signups
Signups for new organizations under yours, newest first. Needs permission to see signups.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
statusstring in query | Leave it out or send all for every signup. One of all, pending or rejected. |
qstring in query | Search text. Every word must match. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | One page of signups. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
signup_idstring (uuid), required | |
account_namestring, required | |
signup_statusstring, required | One of pending or rejected. |
signup_createdstring (date-time), required | |
signup_updatedstring (date-time) | |
account_countrystring | |
account_levelstring | |
account_typestring | |
account_planstring | |
account_timezonestring | |
user_first_namestring | |
user_last_namestring | |
user_emailstring | |
user_positionstring |
Get a signup
GET /api/internal/signup
One signup for a new organization under yours, with who sent it and what stops its approval. Needs permission to see signups.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
signup_idstring (uuid) in query, required | Signup ID. |
Responses
| Status | Description |
|---|---|
200 | The signup. |
400 | invalid input: signup_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | signup not found, also when you can't see it. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
signup_idstring (uuid), required | |
account_namestring, required | Name of the new organization. |
account_countrystring, required | |
account_typestring, required | What kind of organization it is. |
account_planstring, required | One of free, pilot or premium. |
user_first_namestring, required | |
user_last_namestring, required | |
user_emailstring (email), required | They become the owner when the signup is approved. |
user_positionstring, required | Job title. |
signup_statusstring, required | An approved signup becomes the organization and is no longer listed. One of pending or rejected. |
signup_messagestring, required | The note for the approvers. Empty when there is none. |
signup_reviewer_notesstring, required | The reason given when it was rejected. Empty until then. |
signup_createdstring (date-time), required | |
signup_updatedstring (date-time), required | |
can_approveboolean, required | Whether you can approve it now with POST /api/internal/signup/approve. false while approve_blocked is set. |
can_rejectboolean, required | Whether you can reject it now with POST /api/internal/signup/reject. |
approve_blockedstring or null, required | What stops approval: email_taken when the email already belongs to a user, name_taken when an organization with this name and country exists, partner_limit when you have as many partners as your plan allows. null when nothing does or you can't approve it. One of email_taken, name_taken, partner_limit or null. |
Approve a signup
POST /api/internal/signup/approve
Creates the organization and its owner.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
signup_idstring (uuid), required |
Responses
| Status | Description |
|---|---|
200 | The new organization and its owner. |
400 | invalid json or invalid input: signup_id when it's missing or isn't a UUID. |
401 | missing authorization header or invalid session. |
403 | forbidden or subaccount quota exceeded. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
409 | email already exists. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
account_idstring (uuid), required | The new organization. |
user_idstring (uuid), required | Its owner. |
List support requests
GET /api/internal/support-requests
Support requests you sent, newest first. With box set to inbox, the requests that organizations directly below yours sent to your organization. The inbox needs permission to see every partner, in an organization that isn't a subpartner. While your organization's access has expired you can list only your own requests. inbox gets 403.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
boxstring in query | mine for requests you sent. inbox for requests sent to your organization. One of mine or inbox. Default mine. |
statusstring in query | Leave it out for every status. One of pending, responded or closed. |
typestring in query | Leave it out for every type. One of Account & Billing, Access, Integration, Quota, Bug Report, Feature Request or Other. |
qstring in query | Search text. Every word must match the subject, type or organization name. Up to 256 characters. |
cursorstring in query | The X-Next-Cursor value from the previous page. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | One page of support requests. |
400 | The request isn't valid. error says why, for example invalid json or invalid input: user_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
X-Total-Countinteger | Total matches. Sent on the first page when the total is 10,000 or less. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
support_request_idstring (uuid), required | |
account_idstring (uuid), required | The organization that sent it. Yours in mine. |
account_namestring, required | |
request_typestring, required | One of Account & Billing, Access, Integration, Quota, Bug Report, Feature Request or Other. |
subjectstring, required | |
statusstring, required | One of pending, responded or closed. |
support_request_createdstring (date-time), required | |
support_request_updatedstring (date-time), required |
Send a support request
POST /api/internal/support-requests
Sends a support request from you to the organization directly above yours. It replies by email. You can send up to 5 in 1 hour. This works while your organization's access has expired.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
request_typestring, required | One of Account & Billing, Access, Integration, Quota, Bug Report, Feature Request or Other. |
subjectstring, required | 3 to 150 characters. |
messagestring, required | 10 to 5000 characters. |
Responses
| Status | Description |
|---|---|
200 | The new request. |
400 | invalid json. invalid input when request_type isn't one of the types, subject is under 3 characters or message is under 10. input too long when subject is over 150 characters or message is over 5000. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
429 | too many requests, please try again later: you sent 5 in the last hour. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
support_request_idstring (uuid), required | |
statusstring, required | Always pending. |
Get a support request
GET /api/internal/support-request
One support request with its message: one you sent, or one in your organization's inbox. The inbox needs permission to see every partner. Replies go by email. To mark a request responded or closed, use POST /api/internal/support-request/status. While your organization's access has expired you can read only requests you sent.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
support_request_idstring (uuid) in query, required | Support request ID. |
Responses
| Status | Description |
|---|---|
200 | The request. |
400 | invalid input: support_request_id. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | support request not found, also when you can't see it. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
support_request_idstring (uuid), required | |
account_idstring (uuid), required | The organization that sent it. |
account_namestring, required | |
user_idstring (uuid), required | The person who sent it. |
user_first_namestring, required | |
user_last_namestring, required | |
user_emailstring (email), required | |
request_typestring, required | One of Account & Billing, Access, Integration, Quota, Bug Report, Feature Request or Other. |
subjectstring, required | |
messagestring, required | |
statusstring, required | pending can change to responded or closed, and responded to closed. No change can be undone. One of pending, responded or closed. |
resolved_atstring (date-time) or null, required | When it was closed. null until then. |
support_request_createdstring (date-time), required | |
support_request_updatedstring (date-time), required | |
mineboolean, required | Whether you sent it. |
can_resolveboolean, required | Whether you can change its status now with POST /api/internal/support-request/status. |
Update a support request
POST /api/internal/support-request/status
Marks a support request from an organization below yours as responded or closed.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
support_request_idstring (uuid), required | |
statusstring, required | One of responded or closed. |
Responses
| Status | Description |
|---|---|
200 | message is support request marked responded or support request marked closed. |
400 | invalid json, invalid input: support_request_id or status must be responded or closed. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
409 | support request already closed or support request already responded. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Reject a signup
POST /api/internal/signup/reject
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
signup_idstring (uuid), required | |
reasonstring, required | 3 to 500 characters. |
Responses
| Status | Description |
|---|---|
204 | Rejected. No body. |
400 | invalid json. invalid input: signup_id when it's missing or isn't a UUID. invalid input when reason is under 3 or over 500 characters. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | It doesn't exist or you can't see it. error says what, for example user not found. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
Get your organization
GET /api/internal/account
Needs permission to see the organization.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Responses
| Status | Description |
|---|---|
200 | Your organization. total_available_apps counts apps available to everyone. The owner's ID, email and job title are left out when you can't see the owner. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
account_idstring (uuid) | |
parent_idstring (uuid) | The organization directly above. |
account_namestring, required | |
account_countrystring, required | |
account_levelstring, required | One of root, partner or subpartner. |
account_typestring, required | |
account_planstring, required | One of free, pilot, premium or root. |
account_settingsobject | |
account_createdstring (date-time), required | |
account_updatedstring (date-time), required | |
account_expirystring (date-time), required | When the organization's access ends. |
owner_idstring (uuid) | |
owner_first_namestring | |
owner_last_namestring | |
owner_positionstring | |
owner_emailstring (email) | |
total_teamsinteger | |
total_usersinteger | |
total_owned_appsinteger | Apps the organization registered. |
total_available_appsinteger |
Transfer ownership
PUT /api/internal/account/owner
Makes another user in your organization the owner. Only the owner can do this. You keep the role you name.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
new_owner_user_idstring (uuid), required | |
previous_owner_role_keystring, required | The role you keep, such as user_admin. Not account_owner. Up to 100 characters. |
Responses
| Status | Description |
|---|---|
200 | message is ownership transferred successfully. |
400 | invalid json, invalid input: new_owner_user_id when it's missing or isn't a UUID, new owner must be account member when new_owner_user_id isn't another person in your organization, invalid input: previous_owner_role_key when it's missing, account_owner or isn't 1 to 100 lowercase letters, digits or underscores. |
401 | missing authorization header or invalid session. |
403 | only owner can transfer ownership or account expired. |
404 | role not found: previous_owner_role_key isn't a role you can take. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
messagestring, required |
Rotate the organization secret
POST /api/internal/account/secret
Creates a new organization secret for X-Org-Secret on POST /api/public/signup. The previous one stops working. The response is the only time you see it.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Responses
| Status | Description |
|---|---|
200 | The new secret. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
Cache-Controlstring | Don't cache this response. Always no-store. |
200 body: application/json, object.
| Field | Description |
|---|---|
org_secretstring, required | Exactly 64 characters. |
Get AI access
GET /api/internal/account/ai-access
What AI clients can do in your organization through the platform's MCP server, and which AI client hosts can connect. Only the owner can see this.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Responses
| Status | Description |
|---|---|
200 | The current settings. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | not found: this region doesn't offer AI clients. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
ai_accessstring, required | off: AI clients can't connect. read: view only. write: view and change. One of off, read or write. |
ai_clientsarray of strings, required | AI client hosts allowed to connect, such as claude.ai, sorted. Empty allows any AI client. Up to 20 items. |
Change AI access
PUT /api/internal/account/ai-access
Changes 1 setting per call: send ai_access or ai_clients, not both. Only the owner can do this.
ai_accessset tooffdisconnects every AI client connected to the platform in your organization.- A list of hosts in
ai_clientsdisconnects AI clients from other hosts and unverified ones. An empty list allows any AI client.
AI clients connected to individual apps stay connected.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Request body
application/json, object.
| Field | Description |
|---|---|
ai_accessstring | off: AI clients can't connect. read: view only. write: view and change. One of off, read or write. |
ai_clientsarray of strings | Host names such as claude.ai, up to 253 characters each. A URL counts as its host. Duplicates are dropped. Empty allows any AI client. Up to 20 items. |
Responses
| Status | Description |
|---|---|
200 | The setting you changed and its value before. |
400 | invalid json, invalid input: send ai_access or ai_clients, invalid input: ai_access or invalid input: hosts. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | not found: this region doesn't offer AI clients. |
415 | unsupported media type: send Content-Type: application/json. Parameters such as charset are fine. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
ai_accessstring | When you sent ai_access. One of off, read or write. |
ai_clientsarray of strings | When you sent ai_clients. Sorted, without duplicates. |
previousstring or array of strings, required | The value before, in the same form. |
Get your organization's limits
GET /api/internal/limits
Needs permission to see limits.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Responses
| Status | Description |
|---|---|
200 | Your plan, limits and use. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
500 | internal server error: something failed on our side. Try again. |
200 body: application/json, object.
| Field | Description |
|---|---|
account_idstring (uuid), required | |
account_namestring, required | |
account_planstring, required | |
limitsobject, required | |
limits.usersobject, required | |
limits.users.currentinteger, required | |
limits.users.maxinteger, required | |
limits.users.remaininginteger, required | -1 when max is 0 or current is over max. |
limits.teamsobject, required | |
limits.teams.currentinteger, required | |
limits.teams.maxinteger, required | |
limits.teams.remaininginteger, required | -1 when max is 0 or current is over max. |
limits.appsobject, required | |
limits.apps.currentinteger, required | |
limits.apps.maxinteger, required | |
limits.apps.remaininginteger, required | -1 when max is 0 or current is over max. |
limits.partnersobject, required | |
limits.partners.currentinteger, required | |
limits.partners.maxinteger, required | |
limits.partners.remaininginteger, required | -1 when max is 0 or current is over max. |
List activity
GET /api/internal/activity
Your organization's audit log, newest first. You see your own actions and those on things you can see. Emails, changes, IP addresses and user agents appear only for people who can see the whole audit log.
Authentication
One of these:
platformSession(Authorization: Bearerheader)platformSessionCookie(sessioncookie)
Parameters
| Name | Description |
|---|---|
qstring in query | Search text. Every word must match. search works too. Up to 256 characters. |
orgstring (uuid) in query | A closed organization whose audit log you can still read. |
actorstring (uuid) in query | Only events by this user. |
thingstring (uuid) in query | Only events about this user, team, app or other thing. |
actionstring in query | Only this action, such as auth.sign_out. Matches ^[a-z_]+\.[a-z_]+$. Up to 40 characters. |
fromstring (date) in query | First day to include, in your time zone. |
tostring (date) in query | Last day to include, in your time zone. |
cursorinteger (int64) in query | The X-Next-Cursor value from the previous page. before works too. At least 1. |
limitinteger in query | Page size. Values above 200 count as 200. Default 100. At least 1. |
Responses
| Status | Description |
|---|---|
200 | One page of events. |
400 | invalid input or invalid search query. |
401 | missing authorization header or invalid session. |
403 | forbidden: your roles don't allow this or your organization's access has expired. |
404 | partner not found: you can't read the audit log of the organization in org. |
500 | internal server error: something failed on our side. Try again. |
200 headers:
| Header | Description |
|---|---|
X-Next-Cursorstring | Send it as cursor to get the next page. Absent on the last page. |
200 body: application/json, array of objects.
| Field | Description |
|---|---|
event_idinteger (int64), required | |
occurred_atstring (date-time), required | |
actionstring, required | Such as auth.sign_out. |
sentencestring, required | What happened, with {target} and {related} standing for those things. |
actor_typestring, required | |
actor_idstring (uuid) | |
actor_namestring | |
actor_emailstring (email) | Only for people who can see the whole audit log. |
actor_linkstring | Path in the web app. |
target_typestring, required | |
target_idstring (uuid) | |
target_namestring | |
target_linkstring | Path in the web app. |
related_typestring | |
related_idstring (uuid) | |
related_namestring | |
related_linkstring | Path in the web app. |
changesobject | Old and new value by field. Only for people who can see the whole audit log. |
changes.{key}array | Exactly 2 items. |
viastring | The AI client that made the change, when one did. |
ipstring | Only for people who can see the whole audit log. |
user_agentstring | Only for people who can see the whole audit log. |