AGNTDocs

Users, organizations and teams

Provision and deprovision users, group them into organizations and teams, set up verified domains, SAML SSO, SCIM and audit export, and set policy from your account down to each team.

Your account holds every end user of your app. Group users into organizations (your customer companies) and teams to give each customer its own admins, sign-in, directory sync, audit trail and policy. Data isolation does not follow this hierarchy: it is per user at every level.

How it works

Account          your app; holds every user, organization and setting.
 |                Console settings are the policy ceiling for everything below.
 +- Organization  a customer company (optional): admins, verified domains,
 |   |            SAML SSO, SCIM, audit export, skill library, model tiers
 |   +- Team      a group of users; team admins set policy the org left open
 |       +- User  one end user; owns tasks, chats, memories, contacts,
 |                connections and a workspace
 +- Team          a team outside any organization
     +- User
ConceptRule
IsolationA user's data is visible to that user and to your account-wide credentials, never to other users. Sharing an account, organization or team grants nothing by itself. Sharing is explicit, for example a team-scoped memory or a task collaborator.
One active teamA user has exactly one active team membership. Adding a user to a team archives their other memberships.
Organization membershipA user belongs to at most one organization, with organizationRole admin, member or guest.
Team rolesowner (exactly one per team), admin, member.
PolicyA tier can change a setting only where no tier above it has locked it. See Policy.

Organization and team admins act through the hosted app (the end-user app served for your account) or through the API with their own credentials. The examples in this guide use an account-wide API key, which can administer every organization and team in your account. See Authentication for key levels.

Your app's hosted domain is the domain the hosted app is served on: its AGNT subdomain or your custom domain. SAML sign-in and SCIM are served there.

Create an organization

Create an organization for each customer company.

curl https://api.agnt.ai/organizations \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Harborview Property Management" }'

The response returns the organization with "id": "6702a9c3e1b4f5d6a7b8c901".

PUT /organizations/:orgId sets name, defaultTeam (where organization-scoped provisioning places new users) and defaultAssistant. DELETE /organizations/:orgId deletes the organization and its domains. Its users and teams stay in your account, and teams left with no members are deleted.

Verify a domain

A verified domain proves the customer controls it. It lets the organization claim its users: auto-join, SSO sign-in, and the rule that users at that domain can join only that organization's teams.

curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/domains \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "domain": "harborview.co", "autoJoin": true }'
{
  "ok": true,
  "domain": {
    "id": "6702aa14b7c8d9e0f1a2b3c4",
    "domain": "harborview.co",
    "source": "manual",
    "verified": false,
    "autoJoin": true,
    "txtRecordName": "_agnt-verification.harborview.co",
    "txtRecordValue": "agnt-06815aa2c88aa0194d3af3d4476fe650ae6cd63017d0e66d6a4ae065",
    "verifiedAt": null,
    "lastCheckedAt": null,
    "createdAt": "2026-11-02T16:24:11.000Z",
    "updatedAt": "2026-11-02T16:24:11.000Z"
  }
}

Publish a DNS TXT record named txtRecordName with the value txtRecordValue, then verify:

curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/domains/6702aa14b7c8d9e0f1a2b3c4/verify \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY"

The response returns the domain with verified: true and verifiedAt set. Until the record is visible in DNS, verify returns 400 and records lastCheckedAt. Call it again after propagation.

NameTypeRequiredDescription
domainstringYesThe domain, such as harborview.co. Stored lower-cased.
autoJoinbooleanNoDefault false. Once the domain is verified, users with an email at this domain join the organization as member when they are provisioned or sign up.

PUT /organizations/:orgId/domains/:domainId with { autoJoin } changes auto-join. Domains added by an SSO configuration have source: "sso" and cannot be edited or removed directly.

Provision users

POST /users/provision finds or creates a user by email and places them on a team. It is idempotent, so call it on every sign-in. It returns 201 when it creates the user and 200 when the user exists.

Provision Maria Chen onto the Leasing team:

curl https://api.agnt.ai/users/provision \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "firstName": "Maria",
    "lastName": "Chen",
    "teamId": "6702ab52c3d4e5f6a7b8c9d0"
  }'
{
  "ok": true,
  "user": {
    "id": "6702b23a0b1c2d3e4f5a6b7c",
    "account": "66f1a2b3c4d5e6f708192a3b",
    "email": "[email protected]",
    "assistant": null,
    "name": "Maria Chen",
    "firstName": "Maria",
    "lastName": "Chen",
    "avatarUrl": null,
    "timezone": "UTC",
    "locale": "en-US",
    "organization": "6702a9c3e1b4f5d6a7b8c901",
    "organizationRole": "member",
    "team": {
      "id": "6702ab52c3d4e5f6a7b8c9d0",
      "name": "Leasing",
      "organization": "6702a9c3e1b4f5d6a7b8c901",
      "status": "active"
    },
    "teamRole": "member",
    "status": "active",
    "createdAt": "2026-11-02T16:24:11.000Z",
    "updatedAt": "2026-11-02T16:24:11.000Z"
  },
  "teamId": "6702ab52c3d4e5f6a7b8c9d0",
  "created": true,
  "addedToTeam": true,
  "alreadyMember": false,
  "joinSkipped": false
}

Maria joined Harborview Property Management because harborview.co is a verified auto-join domain.

NameTypeRequiredDescription
emailstringYesLower-cased and trimmed. Becomes the user's first identifier, so X-User-Email resolves to them.
firstName, lastNamestringNoUsed in the assistant's introductions and signatures.
teamIdstringNoAn existing team in your account.
idstringNoYour own id for the user, used only if it is a 24-character hex string.

Where the user lands:

RequestTeamOrganization
teamId givenThat team, as member. If the email's domain is verified by an organization, the team must belong to that organization, or the call returns 403.As below, by key type
No teamId, organization-scoped keyThe organization's defaultTeam, or a new team in the organization owned by the userThe key's organization
No teamId, account-wide keyA new team owned by the userThe organization that verified the email's domain with autoJoin, if any
Response fieldDescription
createdA new user was created.
addedToTeamA new team membership was created.
alreadyMemberThe user and the membership already existed. Nothing changed.
joinSkippedThe user owns another team that still has active members, so they were not moved. Transfer that team's ownership, then call again.

A new user needs a timezone and working hours before a key can act as them. See the Quickstart.

Update a user

PUT /users/:userId changes a user's profile, organization, role and status. Make Jane Rivera an admin of Harborview:

curl https://api.agnt.ai/users/6702b1e8f9a0b1c2d3e4f5a6 \
  -X PUT \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "organization": "6702a9c3e1b4f5d6a7b8c901", "organizationRole": "admin" }'
NameTypeDescription
organizationstring or nullAn organization id, or null to remove the user from their organization.
organizationRolestringadmin, member or guest.
statusstringactive, inactive or suspended. While inactive or suspended, every request acting as the user fails with 403 account_blocked.
firstName, lastName, name, timezone, locale, metadataProfile fields.
externalIdstringYour id for the user. Unique in the account.

Set status to suspended to cut off a user's access without deleting anything. An organization admin can change these fields only for users in their own organization.

Add people to an organization

MethodUse when
Verified domain with autoJoin: trueEveryone at the customer's domain belongs to the customer.
PUT /users/:userId with organizationYour backend decides membership.
SAML just-in-time sign-in, or SCIMThe customer's identity provider decides.
POST /organizations/:orgId/members with { email }An admin adds one person. The person is notified by email and in the app. Provision the user first.

DELETE /organizations/:orgId/members/:userId removes a user from the organization and its teams.

Teams

Create the Leasing team inside Harborview by calling as Jane, an organization admin. Jane becomes the owner and moves from her current team.

curl https://api.agnt.ai/teams \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "X-User-Email: [email protected]" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Leasing" }'

The response returns the team with "id": "6702ab52c3d4e5f6a7b8c9d0" and "organization": "6702a9c3e1b4f5d6a7b8c901".

A team belongs to the caller's organization: an organization admin's, or an organization-scoped key's. Called with an account-wide key and no X-User-Email, the team belongs to no organization, and ownerId (a user in your account) is required.

Add a user with POST /teams/:teamId/members. The user moves from their current team. Move Maria to the Maintenance team:

curl https://api.agnt.ai/teams/6702ab9fd4e5f6a7b8c9d0e1/members \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "userId": "6702b23a0b1c2d3e4f5a6b7c", "role": "member" }'
NameTypeRequiredDescription
userIdstringYesThe user to add.
rolestringNomember (default) or admin.
newOwnerIdstringNoIf the user owns their current team and it has other active members, an active member of that team to hand it to. Without it the call returns 400 with requiresOwnershipTransfer: true and that teamId.
  • Adding a user to an organization's team makes them a member of that organization if they had none. A user in a different organization is refused with 403.
  • If the user was the last member of their old team, that team is archived.
  • The response returns member.id, the membership id. Use it as memberId below. GET /teams/:teamId/members lists memberships.
EndpointRule
PUT /teams/:teamId/members/:memberIdrole: member or admin. status: active, invited or archived. A team admin cannot change the owner, grant owner, or change another admin except to member.
POST /teams/:teamId/transfer-ownership{ newOwnerId }, called as the current owner with X-User-Email. The new owner must be an active member. The old owner becomes member.
DELETE /teams/:teamId/members/:memberIdThe owner cannot be removed, and admins cannot remove admins. The removed user moves to another active team, else a team they previously owned, else a new team of their own.

Deprovision users

POST /users/deprovision removes a user from one team. If the user then has no team membership at all, active or archived, the user record and their identifiers, integrations and chats are deleted. For the full cascade use DELETE /users/:userId.

curl https://api.agnt.ai/users/deprovision \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "teamId": "6702ab9fd4e5f6a7b8c9d0e1" }'
{ "ok": true, "deleted": true, "userDeleted": true, "userId": "6702b23a0b1c2d3e4f5a6b7c" }
  • email and teamId are required. The team must be in your account, and in the key's organization for an organization-scoped key, or the call returns 404.
  • An email that matches no user returns 200 with deleted: false.
  • userDeleted: false means the user still has another membership, so the user record and its data remain.

Deprovisioning is refused, with nothing changed, when it would leave something without an administrator:

StatusFlagWhenResolve by
409requiresOrgAdminTransfer: true, organizationIdThe user is the organization's only adminPromote another user with PUT /users/:userId
400requiresOwnershipTransfer: true, teamIdThe user owns a team with other active membersPOST /teams/:teamId/transfer-ownership

DELETE /users/:userId deletes a user outright, whatever their memberships, with the same two refusals. Deletion runs asynchronously: the response confirms it is scheduled. DELETE /organizations/:orgId/members/:userId also returns 409 requiresOrgAdminTransfer for the only admin.

SAML SSO

Each organization can sign its users in through its own SAML 2.0 identity provider (IdP), such as Okta, Microsoft Entra ID or Google Workspace. A user enters their email on your app's hosted domain. If the domain is verified by an organization with SSO enabled, the user is sent to that organization's IdP.

  1. Register the service provider in the IdP:

    IdP settingValue
    ACS (reply) URLhttps://<your app's hosted domain>/api/sso/saml/acs
    SP entity ID and metadatahttps://<your app's hosted domain>/api/sso/saml/metadata
    Single logout URLhttps://<your app's hosted domain>/api/sso/saml/slo
    AttributesEmail, first name, last name and, optionally, groups
  2. Configure the organization with the IdP's details:

    curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/sso \
      -X PUT \
      -H "Authorization: Bearer $AGNT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "enabled": true,
        "enforced": true,
        "provider": "saml_generic",
        "saml": {
          "entryPoint": "https://harborview.okta.com/app/harborview_agnt/exk7q2m9/sso/saml",
          "certificate": "MIIDqDCCApCgAwIBAgIGAYk3HarborviewSigningCert",
          "attributeMapping": { "email": "email", "firstName": "givenName", "lastName": "sn", "groups": "groups" },
          "groupFilter": { "enabled": true, "allowedGroups": ["harborview-staff"] },
          "groupRoleMapping": [ { "group": "harborview-it", "role": "admin" } ]
        },
        "memberSync": { "autoProvision": true }
      }'
    
NameTypeDescription
enabledbooleanTurns SSO sign-in on for the organization's verified domains.
enforcedbooleanUsers at those domains, and members of the organization, can sign in only through SSO. Other sign-in methods return 403 sso_required.
providerstringsaml_generic. Every SAML 2.0 IdP connects through it.
saml.entryPointstringThe IdP's SSO URL. Required, with certificate, before sign-in works.
saml.certificatestringThe IdP's signing certificate. Every response is verified against it. Never returned.
saml.issuerstringThe IdP's entity ID, stored for your reference.
saml.signatureAlgorithmstringDefault sha256.
saml.attributeMappingobjectAttribute names for email, firstName, lastName and groups. Defaults to those names. The email falls back to the NameID.
saml.groupFilterobject{ enabled, allowedGroups, requireAll }. Only users in any of these groups (all of them, with requireAll) may sign in. Case-insensitive.
saml.groupRoleMappingarray[{ group, role }] with role admin or member. Sets the user's organization role at each sign-in. The first matching group wins.
saml.allowIdpInitiatedbooleanDefault false. When true, sign-ins started from the IdP's dashboard are accepted.
memberSync.autoProvisionbooleantrue creates a user on first sign-in. false admits only users you have already provisioned.

SSO guarantees:

  • Assertions must be signed. An unsigned assertion, or one that fails verification against certificate, is rejected.
  • An assertion must be addressed to your ACS URL, be within its validity window, and is accepted once for IdP-initiated sign-in. SP-initiated sign-in must complete within 10 minutes of starting.
  • The signed-in email must belong to one of the organization's verified domains.

PUT merges each object you send into the stored configuration, so you can rotate saml.certificate alone. DELETE /organizations/:orgId/sso clears the SSO configuration, including the SCIM token.

SCIM 2.0

SCIM lets the customer's IdP create, update and deactivate users and manage teams. It works with or without SAML SSO. Mint the organization's token:

curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/sso/scim-token \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY"
{ "ok": true, "scim": { "token": "9b1e0c4f7a2d8e3b6c5a1f0d9e8b7c6a" } }

The token is shown once, and only a hash is stored. Each organization has one token: minting a new one invalidates the previous one immediately. Give the IdP the token as a bearer token and this base URL on your app's hosted domain:

https://<your app's hosted domain>/api/scim/v2
MethodPathBehavior
GET/UsersUsers in the organization. Supports startIndex, count (max 200) and filter=userName eq "[email protected]".
POST/UsersCreates a user in the organization from userName (or the first of emails) and name. Returns 409 if the email exists in the account.
GET/Users/:idOne user.
PUT, PATCH/Users/:idUpdates name.givenName, name.familyName and active. active: false blocks the user.
DELETE/Users/:idDeactivates the user and keeps their data. Deprovision to delete it.
GET, POST/GroupsTeams in the organization. POST creates a team from displayName.
GET, PUT, PATCH, DELETE/Groups/:idRenames a team, or adds, removes and replaces members. DELETE deletes the team and archives its memberships.
GET/ServiceProviderConfigPatch and filter are supported. Bulk and password change are not.

Responses use application/scim+json. User ids are AGNT user ids and userName is the email. Adding a user to a group moves them from their current team. A user in a different organization is skipped, as is a user who owns another team that still has active members.

Audit events

Administrative actions are recorded as audit events: organization, domain and SSO changes, membership and role changes, team policy changes, audit-export changes and SSO sign-ins. Actions by a signed-in user, or an API key acting as one with X-User-Email, who belongs to a team in an organization with audit logging enabled are recorded. Account-wide key calls without X-User-Email and SCIM changes are not. Events are archived nightly. The API serves the most recent 30 days.

curl "https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/audit-events?action=sso.updated&after=2026-11-01T00:00:00Z" \
  -H "Authorization: Bearer $AGNT_API_KEY"
{
  "ok": true,
  "events": [
    {
      "id": "6702d1a8e9f0a1b2c3d4e5f6",
      "account": "66f1a2b3c4d5e6f708192a3b",
      "organization": "6702a9c3e1b4f5d6a7b8c901",
      "actor": "[email protected]",
      "action": "sso.updated",
      "entityType": "organization",
      "entityId": "6702a9c3e1b4f5d6a7b8c901",
      "metadata": { "provider": "saml_generic", "enabled": true, "enforced": true },
      "createdAt": "2026-11-02T16:24:11.000Z"
    }
  ],
  "page": 1,
  "perPage": 20,
  "total": 1
}
NameTypeDescription
actorstringThe actor's email. Exact match.
actionstringSuch as sso.updated or domain.verified.
entityTypestringSuch as organization or domain.
after, beforedate-timeTime range.
page, perPageintegerNewest first. perPage max 100.

GET /audit-events returns events across your account and also accepts entityId. GET /audit-events/:eventId returns one event.

Export audit events to S3

Deliver audit events to the customer's own S3 bucket to keep them beyond 30 days.

  1. In the customer's AWS account, create an IAM role with this permissions policy:

    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::harborview-agnt-audit/agnt/*"
      }]
    }
    

    The role's trust policy must allow only the AGNT account that delivers audit exports. Contact [email protected] for the account ID and the exact role to trust. Do not trust the account root. Use a dedicated bucket with versioning enabled.

  2. Configure the organization:

    curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/audit-logging \
      -X PUT \
      -H "Authorization: Bearer $AGNT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "enabled": true,
        "s3BucketArn": "arn:aws:s3:::harborview-agnt-audit",
        "s3Prefix": "agnt",
        "roleArn": "arn:aws:iam::210987654321:role/agnt-audit-writer",
        "region": "us-west-2"
      }'
    

    The response returns the stored configuration with "deliveryConfigured": true.

  3. Deliver a time range. The call returns 202 with a delivery job:

    curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/audit-logging/deliver \
      -X POST \
      -H "Authorization: Bearer $AGNT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "from": "2026-11-01T00:00:00Z", "to": "2026-11-02T00:00:00Z" }'
    
  4. Read the job's status with GET /organizations/:orgId/audit-logging/deliver/:jobId:

    {
      "ok": true,
      "deliveryJob": {
        "id": "6702d2b9f0a1b2c3d4e5f6a7",
        "organization": "6702a9c3e1b4f5d6a7b8c901",
        "requestedBy": "[email protected]",
        "status": "completed",
        "from": "2026-11-01T00:00:00.000Z",
        "to": "2026-11-02T00:00:00.000Z",
        "filesCopied": 1,
        "deliveryErrors": [],
        "completedAt": "2026-11-02T16:25:03.000Z",
        "createdAt": "2026-11-02T16:24:11.000Z"
      }
    }
    
NameTypeDescription
enabledbooleanTurns audit logging on for the organization. Delivery returns 403 while it is false.
s3BucketArnstringThe destination bucket. Delivery returns 400 until both s3BucketArn and roleArn are set.
s3PrefixstringKey prefix. Default agnt-audit-logs.
roleArnstringThe IAM role assumed to write.
regionstringThe bucket's region. Default us-east-1.
  • Each delivery copies one range. Without from and to, it covers the 30 days up to 00:00 UTC today. To keep a continuous copy, call deliver on a schedule, for example daily.
  • Files are JSON Lines, written to <s3Prefix>/year=YYYY/month=MM/day=DD/.
  • Delivery is idempotent: delivering a range again overwrites the same objects with the same content.
  • Job status is pending, running, completed or failed.

Policy

You set the ceiling for your app in the AGNT console. Below it, each control is inherited, tightened or locked. A tier can change a control only where no tier above it has locked it.

ControlAccount (console)OrganizationTeam
SkillsStore tiers offered; skills blocked or allowed app-wide; whether users can browse, install, create and shareSkill library: allowed tiers and enabled skillsStore on or off, allowlist, blocklist; create and share rules
MCPmcpAccessLevel cap and lock; whether custom MCP servers can be addedIts own cap and lock; custom MCP servers Inherit, On or Off
ConnectionsAllowed account types; access per resource with locks; connection catalogThe same fields; each connection Inherit, On or Off
Computer useWorkspace switches with locks; restricted presetThe same switches and preset
AutonomyApproval mode per action type, and locksThe same, except cells the organization locked
Model tiersDefault chat and task tiersDefault chat and task tiers
Kill switchFreezes every outbound action for the account

How tiers combine:

  • Computer use and the restricted preset. An "off" at the account or the user's team wins. With no setting anywhere, each switch is on. See Computer use.
  • MCP and connection access. The most restrictive level across account, team and user applies. A lock forces the admin's level.
  • Skill store. A team with the store off wins. Blocklists add up across tiers. Allowlists narrow.
  • Skill library. When an organization configures its library, a skill is available to its users only if its tier is in allowedTiers and its id is in enabledSkills. Skills the platform installs as locked are always available. An organization with no library configuration inherits everything.
  • Autonomy. An organization lock pins the cell for every team and user in it. Modes, defaults and the order in which a mode is decided are in Autonomy.
  • Connection catalog. A team's Inherit, On or Off decides whether a connection is offered to the team's users in the hosted app. A team value takes precedence over the account's.

Account-tier settings are changed only by account admins signed in to the console. Organization and team settings accept an account-wide key or an admin of that organization or team.

Set team policy

Cap MCP at read-only, pin calendar access to read-only, block one skill, and stop the Leasing team from adding its own MCP servers:

curl https://api.agnt.ai/teams/6702ab52c3d4e5f6a7b8c9d0/settings/resource-permissions \
  -X PATCH \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mcpAccessLevel": "read",
    "mcpLocked": true,
    "connections": {
      "allowedTypes": ["google", "azure"],
      "connectionPermissions": { "google": { "calendar": "read" }, "azure": { "calendar": "read" } },
      "connectionLocks": { "google": { "calendar": true }, "azure": { "calendar": true } }
    },
    "store": { "blocklist": ["6702c915c6d7e8f9a0b1c2d3"] }
  }'

curl https://api.agnt.ai/teams/6702ab52c3d4e5f6a7b8c9d0/settings/custom-mcp \
  -X PATCH \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "allowCustomMcp": "off" }'

On team settings, null (or "inherit") inherits and a value is an explicit setting. A lock pins a value so the user's own preference is ignored. A lock with no value is rejected.

NameTypeDescription
mcpAccessLevelstring or nulloff, read or read_write.
mcpLockedboolean or nullLocks mcpAccessLevel. Requires a team value.
connections.allowedTypesarray or nullnull inherits, [] allows all, or a list of account types.
connections.connectionPermissionsobject{ <type>: { <resource>: "off" | "read" | "read_write" | null } }
connections.connectionLocksobject{ <type>: { <resource>: true | false | null } }. A value is required before a lock. A locked value cannot be cleared without clearing its lock in the same request.
capabilitiesobjectComputer-use switches. See Computer use.
storeobject{ enabled, allowlist, blocklist } of skill ids. null inherits.
skillsobjectcanBrowseStore, canInstallFromStore, canCreate, requireApproval, canShareWithTeam, requirePermissionToShare: true, false or null.
usersobjectcreateSkills, shareSkills: true, false or null.
approvalSettings.matrixobjectAutonomy cells and locked. Cells the organization locked are ignored.

Account types are google, azure (Microsoft), apple, slack, zoom, asana, hubspot, imap, or mcp:<name> for an MCP connection. Resources are calendar, contacts, email, drive, messaging, video, teams, projects and crm.

GET /teams/:teamId/settings/resource-permissions returns the team's stored values plus the organization's locked autonomy cells (orgLockedCells, orgLockedValues), so an admin UI can show what it cannot change.

To set a connection's catalog state for a team, send { "enabled": "inherit" | "on" | "off" } to PATCH /teams/:teamId/settings/connections/:connectionId. GET /teams/:teamId/settings/connections lists each connection with orgEnabled, teamEnabled and effectiveState.

Apply the restricted security preset

The restricted preset turns off and locks MCP servers (including custom ones), the workspace shell, browser automation and workspace handoff in one call. Apply it to the Maintenance team:

curl https://api.agnt.ai/teams/6702ab9fd4e5f6a7b8c9d0e1/settings/security-preset \
  -X POST \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "preset": "restricted" }'

Apply it to the whole account in the AGNT console. See Computer use for what each switch covers.

Set organization policy

Offer Harborview's users only first-party and official skills, and only the ones listed:

curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/library \
  -X PATCH \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "allowedTiers": ["agnt", "official"], "enabledSkills": ["6702c915c6d7e8f9a0b1c2d3"] }'

allowedTiers takes agnt, official and community. bulkEnableTier (one tier name) adds every published skill in that tier to enabledSkills.

To set and lock autonomy for the organization, use PATCH /organizations/:orgId/settings/resource-permissions. See Autonomy.

Default model tiers

Set the organization's default tiers for new chats and tasks. They apply between a task's own tier and your account's default.

curl https://api.agnt.ai/organizations/6702a9c3e1b4f5d6a7b8c901/settings/model-tiers \
  -X PATCH \
  -H "Authorization: Bearer $AGNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "chat": "medium", "task": "high" }'
{ "ok": true, "defaultModelTiers": { "chat": "medium", "task": "high" } }

Values are low, medium, high, ultra, or null to inherit your account's default. See Model tiers.

Endpoint reference

Every endpoint accepts an account-wide API key. Organization endpoints also accept an admin of that organization, and team endpoints an admin of that team.

MethodPathDescription
POST/users/provisionFind or create a user and place them on a team
POST/users/deprovisionRemove a user from a team; delete the user if no membership remains
GET/usersList users
PUT/users/:userIdUpdate profile, organization, organizationRole, status
DELETE/users/:userIdDelete a user and their data (asynchronous)
GET POST/teamsList; create
GET PUT DELETE/teams/:teamIdRead; update; delete
GET POST/teams/:teamId/membersList; add
PUT DELETE/teams/:teamId/members/:memberIdChange role or status; remove
POST/teams/:teamId/transfer-ownershipTransfer ownership, as the current owner
GET PATCH/teams/:teamId/settings/resource-permissionsTeam policy
POST/teams/:teamId/settings/security-presetApply the restricted preset
GET/teams/:teamId/settings/connectionsConnection catalog with account and team state
PATCH/teams/:teamId/settings/connections/:connectionIdSet a connection's catalog state
PATCH/teams/:teamId/settings/custom-mcpAllow or block custom MCP servers
GET POST/organizationsList; create
GET PUT DELETE/organizations/:orgIdRead; update; delete
GET POST/organizations/:orgId/membersList; add and notify
DELETE/organizations/:orgId/members/:userIdRemove from the organization and its teams
GET POST/organizations/:orgId/domainsList; add
PUT DELETE/organizations/:orgId/domains/:domainIdUpdate auto-join; remove
POST/organizations/:orgId/domains/:domainId/verifyCheck the TXT record
PUT DELETE/organizations/:orgId/ssoConfigure (merge); clear
POST/organizations/:orgId/sso/scim-tokenMint the SCIM token
GET PATCH/organizations/:orgId/settings/resource-permissionsAutonomy matrix and locks
GET PATCH/organizations/:orgId/librarySkill library
GET PATCH/organizations/:orgId/settings/model-tiersDefault model tiers
GET/organizations/:orgId/audit-eventsThe organization's audit events
GET PUT/organizations/:orgId/audit-loggingS3 export configuration
POST/organizations/:orgId/audit-logging/deliverStart a delivery
GET/organizations/:orgId/audit-logging/deliver/:jobIdDelivery status
GET/audit-eventsAccount-wide audit events
GET/audit-events/:eventIdOne audit event

SAML (/api/sso/saml/acs, /api/sso/saml/metadata, /api/sso/saml/slo) and SCIM (/api/scim/v2) are served on your app's hosted domain, not api.agnt.ai.

Limits

  • Audit events are served for 30 days. Export them to keep them longer.
  • List endpoints page with page and perPage (default 20, max 100). SCIM pages with startIndex and count (default 100, max 200), filters only on userName eq, and has no bulk operations.
  • Up to 10 organizations can be created per account per minute.
  • SAML sign-in and SCIM serve users of the hosted app. If you build your own sign-in, provision and deprovision from your backend.
  • Organization-scoped API keys act only within their organization, and with X-User-Email they are limited to organization admin operations. See Authentication.

See also