Skip to content
engage-ai

List organizations

GET/admin/organizations

Metadata only. No endpoint returns credential material — see the note below.

Query parameters

  • cursorstring
  • limitinteger

    Max 100

Response fields 200
  • itemsOrganizationSummary[]required
  • nextCursorstring | nullrequired

    Opaque. Pass back verbatim as cursor. Null means the end.

  • hasMorebooleanrequired

OrganizationSummary

  • idstring (uuid)required
  • slugstringrequired
  • namestringrequired
  • planstringrequired
  • statusstringrequired
  • defaultLocalestringrequired
  • defaultTimezonestringrequired

Responses

  • 200A page of organizations, newest first.
  • 401Missing or invalid admin credential.
Request
curl "https://api.getengageai.app/admin/organizations" \
  -H "Authorization: Bearer $ADMIN_TOKEN"
Response · 200
{
  "items": [
    {
      "id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
      "slug": "copper-kettle-cafe",
      "name": "Copper Kettle Cafe",
      "plan": "string",
      "status": "string",
      "defaultLocale": "en-GB",
      "defaultTimezone": "Europe/London"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}

Provision an organization

POST/admin/organizations

Creates the organization, a default agent profile and a first API key in one transaction. All three or none: an organization without a profile receives messages it can never answer, and one without a key cannot be configured by any endpoint.

The returned key is shown once. Only a peppered hash is stored, so it cannot be recovered — issue a new one instead.

Requires the ADMIN_API_KEY credential, which is separate from tenant keys.

Body
application/json

Request body

  • namestringrequired

    Display name, e.g. "Acme Outdoors".

    Max 255 characters

  • slugstring

    URL-safe identifier. Derived from the name when omitted. Immutable once set.

    Min 3 characters · Max 63 characters

  • planenum

    One of FREE, STARTER, GROWTH, ENTERPRISE

  • defaultLocalestring

    Max 16 characters

  • defaultTimezonestring

    IANA name, e.g. Europe/London.

    Max 64 characters

  • settingsobject

    Business hours, escalation contacts, branding.

  • personastring

    Seeds the default agent profile's persona. Editable afterwards.

    Max 4000 characters

  • environmentenum

    Prefixes the issued key. Cosmetic; both are equally real.

    One of live, test

  • ownerobjectrequired

    The person who will administer this organization. A password is generated for them and returned once, under login.

  • owner.emailstring (email)required

    They sign in with this.

    Max 320 characters

  • owner.namestring

    Max 255 characters

Response fields 201
  • organizationobjectrequired
  • organization.idstring (uuid)required
  • organization.slugstringrequired
  • organization.namestringrequired
  • organization.planstringrequired
  • agentProfileIdstring (uuid)required

    The default profile, created with conservative guardrails.

  • loginobjectrequired

    Hand this to the organization.

  • login.urlstringrequired

    Where to POST them.

  • login.emailstring (email)required
  • login.passwordstringrequired

    Shown once. It appears here and nowhere else — not in the audit log, not in any log line — and only a scrypt hash is stored. Lost means reissue, never retrieve.

  • login.mustChangePasswordtruerequired

    They are expected to replace it via POST /auth/password.

  • login.userIdstring (uuid)required
  • apiKeyobjectrequired
  • apiKey.idstring (uuid)required
  • apiKey.prefixstringrequired

    Non-secret. Safe to store and to quote in support.

  • apiKey.plaintextstringrequired

    Shown exactly once. Only a peppered hash is stored, so this cannot be recovered — issue a new key instead.

OrganizationProvisioned

  • organizationobjectrequired
  • organization.idstring (uuid)required
  • organization.slugstringrequired
  • organization.namestringrequired
  • organization.planstringrequired
  • agentProfileIdstring (uuid)required

    The default profile, created with conservative guardrails.

  • loginobjectrequired

    Hand this to the organization.

  • login.urlstringrequired

    Where to POST them.

  • login.emailstring (email)required
  • login.passwordstringrequired

    Shown once. It appears here and nowhere else — not in the audit log, not in any log line — and only a scrypt hash is stored. Lost means reissue, never retrieve.

  • login.mustChangePasswordtruerequired

    They are expected to replace it via POST /auth/password.

  • login.userIdstring (uuid)required
  • apiKeyobjectrequired
  • apiKey.idstring (uuid)required
  • apiKey.prefixstringrequired

    Non-secret. Safe to store and to quote in support.

  • apiKey.plaintextstringrequired

    Shown exactly once. Only a peppered hash is stored, so this cannot be recovered — issue a new key instead.

Responses

  • 201Provisioned. Store the key now.
  • 401Missing or invalid admin credential.
  • 409The slug is already taken.
  • 422Invalid name, or no slug could be derived from it.
Request
curl -X POST "https://api.getengageai.app/admin/organizations" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Copper Kettle Cafe",
    "owner": {
      "email": "manager@copperkettle.example",
      "name": "Sam Patel"
    }
  }'
Response · 201
{
  "organization": {
    "id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
    "slug": "copper-kettle-cafe",
    "name": "Trailhead Mid GTX Boot",
    "plan": "string"
  },
  "agentProfileId": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
  "login": {
    "url": "https://acme.example/products/trailhead-mid",
    "email": "owner@acme.example",
    "password": "mFGVaAer-jKcyPp34-qxmLNojm",
    "mustChangePassword": true,
    "userId": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91"
  },
  "apiKey": {
    "id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
    "prefix": "eng_live_312cf6e6",
    "plaintext": "eng_live_312cf6e6.fPCz8Qk…"
  }
}

Describe an organization

GET/admin/organizations/{id}

Who can sign in, which API keys exist, and when each was last used — enough to answer a support question.

Credentials are not retrievable. Passwords are stored as scrypt hashes and keys as peppered HMACs; no code path reverses either, deliberately. What you get here are identifiers — emails and key prefixes — never anything usable. When a customer has lost a credential, reissue it below.

Path parameters

  • idstring (uuid)required
Response fields 200
  • idstring (uuid)required
  • slugstringrequired
  • namestringrequired
  • planstringrequired
  • statusstringrequired
  • membersobject[]required
  • members[].userIdstring (uuid)required
  • members[].emailstring (email)required
  • members[].namestring | nullrequired
  • members[].rolestringrequired
  • members[].mustChangePasswordbooleanrequired

    True while the password is one an administrator issued.

  • members[].lastLoginAtstring (date-time) | nullrequired

    Null means they have never signed in.

  • apiKeysobject[]required
  • apiKeys[].idstring (uuid)required
  • apiKeys[].namestringrequired
  • apiKeys[].prefixstringrequired

    Non-secret. Identifies a key without being one.

  • apiKeys[].lastUsedAtstring (date-time) | nullrequired
  • apiKeys[].revokedAtstring (date-time) | nullrequired

OrganizationDetail

  • idstring (uuid)required
  • slugstringrequired
  • namestringrequired
  • planstringrequired
  • statusstringrequired
  • membersobject[]required
  • members[].userIdstring (uuid)required
  • members[].emailstring (email)required
  • members[].namestring | nullrequired
  • members[].rolestringrequired
  • members[].mustChangePasswordbooleanrequired

    True while the password is one an administrator issued.

  • members[].lastLoginAtstring (date-time) | nullrequired

    Null means they have never signed in.

  • apiKeysobject[]required
  • apiKeys[].idstring (uuid)required
  • apiKeys[].namestringrequired
  • apiKeys[].prefixstringrequired

    Non-secret. Identifies a key without being one.

  • apiKeys[].lastUsedAtstring (date-time) | nullrequired
  • apiKeys[].revokedAtstring (date-time) | nullrequired

Responses

  • 200The organization and its credential inventory.
  • 404No such organization.
Request
curl "https://api.getengageai.app/admin/organizations/$ID" \
  -H "Authorization: Bearer $ADMIN_TOKEN"
Response · 200
{
  "id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
  "slug": "copper-kettle-cafe",
  "name": "Copper Kettle Cafe",
  "plan": "string",
  "status": "string",
  "members": [
    {
      "userId": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
      "email": "owner@acme.example",
      "name": "Copper Kettle Cafe",
      "role": "string",
      "mustChangePassword": true,
      "lastLoginAt": "2026-10-16T09:30:00.000Z"
    }
  ],
  "apiKeys": [
    {
      "id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
      "name": "Copper Kettle Cafe",
      "prefix": "eng_live_312cf6e6",
      "lastUsedAt": "2026-10-16T09:30:00.000Z",
      "revokedAt": "2026-10-16T09:30:00.000Z"
    }
  ]
}

Issue a new password for a member

POST/admin/organizations/{id}/password-reset

The recovery path when a customer cannot sign in. Returns a new temporary password, flagged for replacement, and revokes every session that member held — a reset that left live tokens valid would change nothing for whoever already had one.

Defaults to the OWNER; name another member with email.

Body
application/json

Path parameters

  • idstring (uuid)required

Request body

  • emailstring (email)

    Which member to reset. Defaults to the OWNER when there is exactly one.

Response fields 201
  • userIdstring (uuid)required
  • emailstring (email)required
  • temporaryPasswordstringrequired

    Shown once. Every session that member held has been revoked.

  • mustChangePasswordtruerequired

PasswordReset

  • userIdstring (uuid)required
  • emailstring (email)required
  • temporaryPasswordstringrequired

    Shown once. Every session that member held has been revoked.

  • mustChangePasswordtruerequired

Responses

  • 201Reset. Hand the password over once.
  • 404No such organization, or no such member.
  • 422Several members and no OWNER; name one with `email`.
Request
curl -X POST "https://api.getengageai.app/admin/organizations/$ID/password-reset" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
Response · 201
{
  "userId": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
  "email": "owner@acme.example",
  "temporaryPassword": "h7TN5737-LD9FH2hW-mJ9uu6oj",
  "mustChangePassword": true
}

Issue an API key for an organization

POST/admin/organizations/{id}/api-keys

A tenant issues its own keys through POST /api-keys, but only while holding a working credential. This is the way back when every one of them has been lost.

Body
application/json

Path parameters

  • idstring (uuid)required

Request body

  • namestring

    Default "Replacement key" · Max 128 characters

  • environmentenum

    One of live, test

Response fields 201
  • idstring (uuid)
  • namestring
  • prefixstring
  • scopesstring[]
  • lastUsedAtstring (date-time) | null
  • expiresAtstring (date-time) | null
  • revokedAtstring (date-time) | null
  • createdAtstring (date-time)
  • plaintextstring

    Shown exactly once.

Responses

  • 201Issued. The plaintext is shown once.
  • 404No such organization.
Request
curl -X POST "https://api.getengageai.app/admin/organizations/$ID/api-keys" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Replacement key"
  }'
Response · 201
{
  "id": "3f6c2a1e-8b4d-4e7a-9c15-2d0b7e6f4a91",
  "name": "Trailhead Mid GTX Boot",
  "prefix": "eng_live_312cf6e6",
  "scopes": [
    "string"
  ],
  "lastUsedAt": "2026-10-16T09:30:00.000Z",
  "expiresAt": "2026-10-16T09:30:00.000Z",
  "revokedAt": "2026-10-16T09:30:00.000Z",
  "createdAt": "2026-10-16T09:30:00.000Z",
  "plaintext": "eng_live_312cf6e6.fPCz8Qk…"
}