Organizations & Members

Invite users, manage membership roles, and control who has access to your org. All endpoints require an org_admin role unless noted otherwise.

ℹ️
All org management endpoints require authentication (access_token cookie) and org_admin membership unless stated. Non-admin members can only call GET /org and GET /org/members.

Get organization

GET /org
Response (200)
{
  "status": "success",
  "data": {
    "org": {
      "id": "org_01ABCD",
      "name": "Acme Corp",
      "slug": "acme-corp",
      "plan": "pro",
      "status": "active",
      "appUrl": "https://app.acme.com",
      "createdAt": "2024-11-01T09:00:00.000Z"
    }
  }
}

List members

GET /org/members
Response (200)
{
  "status": "success",
  "data": {
    "members": [
      {
        "userId": "usr_01HXYZ",
        "name": "Alice Chen",
        "email": "alice@acme.com",
        "role": "org_admin",
        "status": "active",
        "joinedAt": "2024-11-01T09:00:00.000Z"
      },
      {
        "userId": "usr_01HABC",
        "name": "Bob Smith",
        "email": "bob@acme.com",
        "role": "member",
        "status": "active",
        "joinedAt": "2025-01-10T14:30:00.000Z"
      }
    ]
  }
}

Invite a member

Sends an invitation email to the address. The invite link is valid for 7 days. If an appUrl is set on the org, the invite email includes a prominent link to your application so new members know where to go after joining.

POST /org/members/invite

Request body

FieldTypeDescription
emailstringrequiredEmail address to invite.
rolestringoptional"member" (default) or "org_admin".
Request
{ "email": "bob@acme.com", "role": "member" }
Response (201)
{
  "status": "success",
  "data": {
    "invite": {
      "id": "inv_01XYZ",
      "email": "bob@acme.com",
      "role": "member",
      "expiresAt": "2025-06-01T00:00:00.000Z"
    }
  }
}

Error responses

StatusCause
409Email is already a member or has a pending invite.
403Caller is not an org_admin.

List pending invites

GET /org/invites
Response (200)
{
  "status": "success",
  "data": {
    "invites": [
      {
        "id": "inv_01XYZ",
        "email": "bob@acme.com",
        "role": "member",
        "invitedBy": "alice@acme.com",
        "expiresAt": "2025-06-01T00:00:00.000Z"
      }
    ]
  }
}

Accept an invite

The invited user calls this endpoint with the token from their email link. If the user does not have an account, they are created. On success, a full auth session is established (access + refresh token cookies set).

POST /org/invites/:token/accept

Path parameters

ParameterDescription
tokenThe invite token from the email link.

Request body (new users only)

FieldTypeDescription
namestringrequired for new usersDisplay name for the new account.
passwordstringrequired for new usersPassword for the new account (min 8 chars).
Response (200)
{
  "status": "success",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
    "user": { "id": "usr_01HABC", "name": "Bob Smith", "email": "bob@acme.com" },
    "membership": { "role": "member", "status": "active" },
    "org": { "name": "Acme Corp", "slug": "acme-corp", "appUrl": "https://app.acme.com" }
  }
}

Error responses

StatusCause
400Token is invalid or expired.
409Email already belongs to an existing account (send login instead of registration fields).

Remove a member

DELETE /org/members/:userId

Path parameters

ParameterDescription
userIdID of the member to remove.
Response (200)
{ "status": "success", "data": { "message": "Member removed successfully" } }

Error responses

StatusCause
400Cannot remove yourself or the last admin.
403Caller is not an org_admin.
404User is not a member of this org.