> For the complete documentation index, see [llms.txt](https://docs.otari.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.otari.ai/otari/for-integrators/api-reference/admin.md).

# Admin

## Get Administration Access

> Report whether the caller may use the deployment administration surface.\
> \
> The one endpoint here that answers 200 for everybody. The rest refuse a\
> non-operator with 404 so they do not confirm they exist, which leaves a\
> dashboard nothing to gate its navigation on but a failed request; this says\
> the same thing without one. It publishes only the caller's own standing,\
> which they could establish by trying an endpoint anyway.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"DeploymentAdminAccessPublic":{"description":"Whether the caller may reach the deployment administration surface.\n\nThe one endpoint in that surface that answers 200 for everybody, and\ndeliberately: the rest refuse with 404 so they do not confirm they exist,\nwhich leaves the dashboard nothing to gate its navigation on but a failed\nrequest. This says the same thing a caller could learn by trying, without\nthe try.","properties":{"granted":{"title":"Granted","type":"boolean"}},"required":["granted"],"title":"DeploymentAdminAccessPublic","type":"object"}}},"paths":{"/api/v1/admin/access":{"get":{"description":"Report whether the caller may use the deployment administration surface.\n\nThe one endpoint here that answers 200 for everybody. The rest refuse a\nnon-operator with 404 so they do not confirm they exist, which leaves a\ndashboard nothing to gate its navigation on but a failed request; this says\nthe same thing without one. It publishes only the caller's own standing,\nwhich they could establish by trying an endpoint anyway.","operationId":"admin-get_administration_access","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentAdminAccessPublic"}}},"description":"Successful Response"}},"summary":"Get Administration Access","tags":["admin"]}}}}
```

## List Deployment Users

> List every account on this deployment, with the organizations each belongs to.\
> \
> Deployment-wide, so it is not the same list as \`\`GET /api/v1/organizations/me/members\`\`:\
> that one is the caller's organization roster and drops a suspended\
> membership, while this one carries every identity at whatever standing,\
> including one whose memberships are all suspended. Each row also reports when\
> the account last signed in to the dashboard, and null there means never.\
> \`\`search\`\` narrows the page and the count together.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"DeploymentUsersPublic":{"properties":{"count":{"title":"Count","type":"integer"},"data":{"items":{"$ref":"#/components/schemas/DeploymentUserPublic"},"title":"Data","type":"array"}},"required":["data","count"],"title":"DeploymentUsersPublic","type":"object"},"DeploymentUserPublic":{"description":"An identity on this deployment, whatever organization it belongs to.\n\nNot ``ActiveOrganizationMemberPublic``: that shape is a *membership* joined\nto an identity, scoped to one organization and hiding the suspended rows.\nThis one is the identity itself, and its ``organizations`` list carries every\nmembership at whatever status, because an account whose only membership is\nsuspended is precisely what an operator comes here to find.\n\n``is_bootstrap_operator`` and ``is_self`` are the two rows an operator may\nnot deactivate or demote, and they travel on the row so the page can disable\nthose controls rather than offering ones the server refuses. Neither is an\nauthorization: the server refuses either way. ``is_self`` is answered here\nbecause nothing else the dashboard fetches names the caller's identity, so\nwithout it the page could not tell which row is the reader's own.","properties":{"created_at":{"format":"date-time","title":"Created At","type":"string"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"id":{"format":"uuid","title":"Id","type":"string"},"is_active":{"title":"Is Active","type":"boolean"},"is_bootstrap_operator":{"title":"Is Bootstrap Operator","type":"boolean"},"is_self":{"title":"Is Self","type":"boolean"},"is_superuser":{"title":"Is Superuser","type":"boolean"},"last_sign_in_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"title":"Last Sign In At"},"organizations":{"items":{"$ref":"#/components/schemas/DeploymentUserOrganizationPublic"},"title":"Organizations","type":"array"}},"required":["id","email","full_name","is_active","is_superuser","is_bootstrap_operator","is_self","last_sign_in_at","created_at","organizations"],"title":"DeploymentUserPublic","type":"object"},"DeploymentUserOrganizationPublic":{"description":"One organization an identity belongs to, as the operator surface lists it.","properties":{"name":{"title":"Name","type":"string"},"organization_id":{"format":"uuid","title":"Organization Id","type":"string"},"role":{"title":"Role","type":"string"},"slug":{"title":"Slug","type":"string"},"status":{"title":"Status","type":"string"}},"required":["organization_id","name","slug","role","status"],"title":"DeploymentUserOrganizationPublic","type":"object"},"HTTPValidationError":{"properties":{"code":{"const":"invalid_request","description":"Stable error code, also sent as the Otari-Error-Code header.","title":"Code","type":"string"},"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"ValidationError":{"properties":{"ctx":{"title":"Context","type":"object"},"input":{"title":"Input"},"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"}}},"paths":{"/api/v1/admin/users":{"get":{"description":"List every account on this deployment, with the organizations each belongs to.\n\nDeployment-wide, so it is not the same list as ``GET /api/v1/organizations/me/members``:\nthat one is the caller's organization roster and drops a suspended\nmembership, while this one carries every identity at whatever standing,\nincluding one whose memberships are all suspended. Each row also reports when\nthe account last signed in to the dashboard, and null there means never.\n``search`` narrows the page and the count together.","operationId":"admin-list_deployment_users","parameters":[{"description":"Number of records to skip","in":"query","name":"skip","required":false,"schema":{"default":0,"description":"Number of records to skip","minimum":0,"title":"Skip","type":"integer"}},{"description":"Maximum number of records to return","in":"query","name":"limit","required":false,"schema":{"default":100,"description":"Maximum number of records to return","maximum":1000,"minimum":1,"title":"Limit","type":"integer"}},{"description":"Narrow to accounts whose name or email contains this text, case-insensitively.","in":"query","name":"search","required":false,"schema":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"description":"Narrow to accounts whose name or email contains this text, case-insensitively.","title":"Search"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentUsersPublic"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"List Deployment Users","tags":["admin"]}}}}
```

## Update Deployment User

> Deactivate or reactivate an account, or change whether it may administer this deployment.\
> \
> Both fields are optional and omitting one leaves it alone; a body naming\
> neither is refused rather than treated as a no-op. Deactivating also ends\
> that account's dashboard sessions immediately, so a lost laptop stops\
> working now rather than when its cookie is next presented.\
> \
> Two changes are refused to keep a deployment reachable: an operator may not\
> deactivate their own account or drop their own operator access, and neither\
> may be taken from the deployment's bootstrap operator, which is the identity\
> master-key sign-in resolves to. Granting either is unguarded.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"DeploymentUserUpdateRequest":{"description":"The two flags the operator surface may flip, each optional.\n\nOmitting a field leaves it alone, so deactivating an account and changing\nwhat it may administer stay separate decisions even though one endpoint\ncarries both. A body that sets neither is refused rather than treated as a\nno-op: it is a request that meant something and lost it.","properties":{"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"is_superuser":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Superuser"}},"title":"DeploymentUserUpdateRequest","type":"object"},"DeploymentUserPublic":{"description":"An identity on this deployment, whatever organization it belongs to.\n\nNot ``ActiveOrganizationMemberPublic``: that shape is a *membership* joined\nto an identity, scoped to one organization and hiding the suspended rows.\nThis one is the identity itself, and its ``organizations`` list carries every\nmembership at whatever status, because an account whose only membership is\nsuspended is precisely what an operator comes here to find.\n\n``is_bootstrap_operator`` and ``is_self`` are the two rows an operator may\nnot deactivate or demote, and they travel on the row so the page can disable\nthose controls rather than offering ones the server refuses. Neither is an\nauthorization: the server refuses either way. ``is_self`` is answered here\nbecause nothing else the dashboard fetches names the caller's identity, so\nwithout it the page could not tell which row is the reader's own.","properties":{"created_at":{"format":"date-time","title":"Created At","type":"string"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"id":{"format":"uuid","title":"Id","type":"string"},"is_active":{"title":"Is Active","type":"boolean"},"is_bootstrap_operator":{"title":"Is Bootstrap Operator","type":"boolean"},"is_self":{"title":"Is Self","type":"boolean"},"is_superuser":{"title":"Is Superuser","type":"boolean"},"last_sign_in_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"title":"Last Sign In At"},"organizations":{"items":{"$ref":"#/components/schemas/DeploymentUserOrganizationPublic"},"title":"Organizations","type":"array"}},"required":["id","email","full_name","is_active","is_superuser","is_bootstrap_operator","is_self","last_sign_in_at","created_at","organizations"],"title":"DeploymentUserPublic","type":"object"},"DeploymentUserOrganizationPublic":{"description":"One organization an identity belongs to, as the operator surface lists it.","properties":{"name":{"title":"Name","type":"string"},"organization_id":{"format":"uuid","title":"Organization Id","type":"string"},"role":{"title":"Role","type":"string"},"slug":{"title":"Slug","type":"string"},"status":{"title":"Status","type":"string"}},"required":["organization_id","name","slug","role","status"],"title":"DeploymentUserOrganizationPublic","type":"object"},"HTTPValidationError":{"properties":{"code":{"const":"invalid_request","description":"Stable error code, also sent as the Otari-Error-Code header.","title":"Code","type":"string"},"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"ValidationError":{"properties":{"ctx":{"title":"Context","type":"object"},"input":{"title":"Input"},"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"}}},"paths":{"/api/v1/admin/users/{user_id}":{"patch":{"description":"Deactivate or reactivate an account, or change whether it may administer this deployment.\n\nBoth fields are optional and omitting one leaves it alone; a body naming\nneither is refused rather than treated as a no-op. Deactivating also ends\nthat account's dashboard sessions immediately, so a lost laptop stops\nworking now rather than when its cookie is next presented.\n\nTwo changes are refused to keep a deployment reachable: an operator may not\ndeactivate their own account or drop their own operator access, and neither\nmay be taken from the deployment's bootstrap operator, which is the identity\nmaster-key sign-in resolves to. Granting either is unguarded.","operationId":"admin-update_deployment_user","parameters":[{"in":"path","name":"user_id","required":true,"schema":{"format":"uuid","title":"User Id","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentUserUpdateRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentUserPublic"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Update Deployment User","tags":["admin"]}}}}
```

## Issue Password Link

> Give an account a single-use link that sets its password, for someone who cannot sign in.\
> \
> Where this deployment can mail links, the link goes to the account's address and is not returned, the\
> same as "Forgot your password?". Where it cannot, or the send fails, the response carries the link for\
> you to pass on, which is how a member who forgot their password gets back in on a deployment without\
> mail. A password chosen through a link that was not mailed records the address as vouched for rather\
> than proven. A new link replaces any earlier reset link for the account.\
> \
> Refused with 409 for a deactivated account, one with no address, one that has no password and signs in\
> with a provider or a passkey (its owner adds a password once signed in), and, where open\_signup is\
> disabled, an unverified address no organization still has as a member or invitee.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"PasswordLinkPublic":{"description":"A single-use link that sets an account's password, and whether it was mailed.","properties":{"expires_at":{"description":"When the link stops working.","format":"date-time","title":"Expires At","type":"string"},"link":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The link to pass on to the account's owner yourself, set only when mail_sent is false. Choosing a password through it records the address as vouched for rather than proven, since the mailbox never saw the link.","title":"Link"},"mail_sent":{"description":"Whether the link was mailed to the account's address. False when this deployment cannot mail links, or the send failed.","title":"Mail Sent","type":"boolean"}},"required":["mail_sent","expires_at"],"title":"PasswordLinkPublic","type":"object"},"HTTPValidationError":{"properties":{"code":{"const":"invalid_request","description":"Stable error code, also sent as the Otari-Error-Code header.","title":"Code","type":"string"},"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"ValidationError":{"properties":{"ctx":{"title":"Context","type":"object"},"input":{"title":"Input"},"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"}}},"paths":{"/api/v1/admin/users/{user_id}/password-link":{"post":{"description":"Give an account a single-use link that sets its password, for someone who cannot sign in.\n\nWhere this deployment can mail links, the link goes to the account's address and is not returned, the\nsame as \"Forgot your password?\". Where it cannot, or the send fails, the response carries the link for\nyou to pass on, which is how a member who forgot their password gets back in on a deployment without\nmail. A password chosen through a link that was not mailed records the address as vouched for rather\nthan proven. A new link replaces any earlier reset link for the account.\n\nRefused with 409 for a deactivated account, one with no address, one that has no password and signs in\nwith a provider or a passkey (its owner adds a password once signed in), and, where open_signup is\ndisabled, an unverified address no organization still has as a member or invitee.","operationId":"admin-issue_password_link","parameters":[{"in":"path","name":"user_id","required":true,"schema":{"format":"uuid","title":"User Id","type":"string"}}],"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordLinkPublic"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Issue Password Link","tags":["admin"]}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.otari.ai/otari/for-integrators/api-reference/admin.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
