Admin API
Administrators
Administrator accounts and sign-in. The control plane
For concepts and a walkthrough, read Operators.
- POST
/admin/auth/loginSign in as an administrator - POST
/admin/auth/logoutEnd the current admin session - GET
/admin/auth/meDescribe the current admin credential - POST
/admin/auth/passwordChange your admin password - GET
/admin/usersList administrators - POST
/admin/usersCreate an administrator - POST
/admin/users/{id}/disabledDisable or re-enable an administrator
Sign in as an administrator
/admin/auth/loginReturns a token for the /admin endpoints. expiresAt is authoritative — the lifetime is ADMIN_SESSION_TTL_HOURS (12 by default), because how long a control-plane token may sit in a terminal is a deployment decision, not ours.
Expiry is a backstop, not the control: these are opaque handles resolved on every request, so revoking a session or disabling an operator takes effect on the next call.
Failures are indistinguishable: unknown account, wrong password and disabled account all return the same 401.
- Auth
- None
- Body
- application/json
Request body
emailstring (email)requiredMax 320 characters
passwordstringrequiredMax 512 characters
Response fields 200
accessTokenstringrequiredSend as
Authorization: Bearer <token>on every /admin endpoint.expiresAtstring (date-time)requiredFour hours out — shorter than a tenant session.
mustChangePasswordbooleanrequiredadminobjectrequiredadmin.idstring (uuid)requiredadmin.emailstring (email)requiredadmin.namestring | nullrequired
AdminLoginResult
accessTokenstringrequiredSend as
Authorization: Bearer <token>on every /admin endpoint.expiresAtstring (date-time)requiredFour hours out — shorter than a tenant session.
mustChangePasswordbooleanrequiredadminobjectrequiredadmin.idstring (uuid)requiredadmin.emailstring (email)requiredadmin.namestring | nullrequired
Responses
- 200Signed in.
- 401Invalid email or password.
curl -X POST "https://api.getengageai.app/admin/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@ops.example",
"password": "h7TN5737-LD9FH2hW-mJ9uu6oj"
}'{
"accessToken": "eng_sess_76bc0bae.2DrK9vYw…",
"expiresAt": "2026-10-16T09:30:00.000Z",
"mustChangePassword": true,
"admin": {
"id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
"email": "owner@acme.example",
"name": "Trailhead Mid GTX Boot"
}
}End the current admin session
/admin/auth/logoutResponse fields 200
loggedOuttruerequired
Responses
- 200Signed out.
- 401Missing or invalid admin credential.
- 409The bootstrap key has no session to end.
curl -X POST "https://api.getengageai.app/admin/auth/logout" \
-H "Authorization: Bearer $ADMIN_TOKEN"{
"loggedOut": true
}Describe the current admin credential
/admin/auth/meTells you whether you are acting as a named operator or as the shared key.
Response fields 200
kindenumrequiredbootstrap_keyis anonymous — actions taken with it have no named actor.One of
admin_session,bootstrap_keyadminUserIdstring (uuid) | nullrequiredemailstring (email) | nullrequiredmustChangePasswordbooleanrequired
AdminPrincipal
kindenumrequiredbootstrap_keyis anonymous — actions taken with it have no named actor.One of
admin_session,bootstrap_keyadminUserIdstring (uuid) | nullrequiredemailstring (email) | nullrequiredmustChangePasswordbooleanrequired
Responses
- 200The authenticated administrator.
- 401Missing or invalid admin credential.
curl "https://api.getengageai.app/admin/auth/me" \
-H "Authorization: Bearer $ADMIN_TOKEN"{
"kind": "admin_session",
"adminUserId": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
"email": "owner@acme.example",
"mustChangePassword": true
}Change your admin password
/admin/auth/passwordRevokes every admin session you hold, including this one.
- Body
- application/json
Request body
currentPasswordstringrequiredMax 512 characters
newPasswordstringrequiredMin 12 characters · Max 512 characters
Response fields 200
changedtruerequiredsessionsRevokedintegerrequiredMin -9007199254740991
Responses
- 200Changed. Sign in again.
- 401The current password did not match.
- 409The bootstrap key has no password.
curl -X POST "https://api.getengageai.app/admin/auth/password" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "h7TN5737-LD9FH2hW-mJ9uu6oj",
"newPassword": "a-long-passphrase-you-chose"
}'{
"changed": true,
"sessionsRevoked": 0
}List administrators
/admin/usersResponses
- 200Every administrator, disabled ones included.
- 401Missing or invalid admin credential.
curl "https://api.getengageai.app/admin/users" \
-H "Authorization: Bearer $ADMIN_TOKEN"[
{
"id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
"email": "alice@ops.example",
"name": "Alice",
"mustChangePassword": true,
"lastLoginAt": "2026-10-16T09:30:00.000Z",
"disabledAt": "2026-10-16T09:30:00.000Z",
"createdAt": "2026-10-16T09:30:00.000Z"
}
]Create an administrator
/admin/usersReturns a temporary password, shown once.
The bootstrap key can only do this while no administrator exists. Once the first account is in place, creating operators requires signing in as one — otherwise the shared key would remain a permanent way to mint access, and disabling someone would not actually remove their route in.
- Body
- application/json
Request body
emailstring (email)requiredMax 320 characters
namestringMax 255 characters
Response fields 201
idstring (uuid)requiredemailstring (email)requirednamestring | nullrequiredmustChangePasswordbooleanrequiredlastLoginAtstring (date-time) | nullrequireddisabledAtstring (date-time) | nullrequiredNon-null means they cannot sign in.
createdAtstring (date-time)requiredtemporaryPasswordstringrequiredShown once. Hand it to them; they must replace it.
Responses
- 201Created. Hand the password over once.
- 401Missing or invalid admin credential.
- 409Email taken, or the bootstrap key used too late.
curl -X POST "https://api.getengageai.app/admin/users" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "bob@ops.example",
"name": "Bob"
}'{
"id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
"email": "owner@acme.example",
"name": "Trailhead Mid GTX Boot",
"mustChangePassword": true,
"lastLoginAt": "2026-10-16T09:30:00.000Z",
"disabledAt": "2026-10-16T09:30:00.000Z",
"createdAt": "2026-10-16T09:30:00.000Z",
"temporaryPassword": "h7TN5737-LD9FH2hW-mJ9uu6oj"
}Disable or re-enable an administrator
/admin/users/{id}/disabledDisabling revokes their sessions immediately — leaving them live would mean an operator keeps full control-plane access until their token expires. Accounts are never deleted, so their audit trail keeps resolving to a name.
- Body
- application/json
Path parameters
idstring (uuid)required
Request body
disabledbooleanrequired
Response fields 200
disabledbooleanrequiredsessionsRevokedintegerrequiredMin -9007199254740991
Responses
- 200Updated.
- 401Missing or invalid admin credential.
- 404No such administrator.
- 409You cannot disable your own account.
curl -X POST "https://api.getengageai.app/admin/users/$ID/disabled" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"disabled": true
}'{
"disabled": true,
"sessionsRevoked": 0
}