Public API: Members

A member is a user who belongs to your organization, holding a single role that grants their permissions. This API lists your members alongside any pending invitations, invites existing users, changes a member's role, and removes a member.

Membership is organization-scoped, so this API is org-level: the path carries no {orgId}, since your token already names its org. Every call here takes a Bearer token, either a service token or a personal access token.

Plain text
https://app.avsb.cloud/api/v1/members
Plain text1 line

Every endpoint here follows the shared conventions: the { data } envelope, an Idempotency-Key on every write below, and the standard error shape. Every /api/v1 token is rate-limited the same way everywhere: a scoped token gets 600 reads and 120 writes per minute, and an admin:* token gets 600 requests per minute, reads and writes together. Every endpoint here also needs the Integrations and API access plan feature, or every call fails with 403 feature_disabled. See rate-limit headers and Refusals at 403.

Scopes are the only gate here

The AvsB dashboard limits inviting, role changes, and removal to organization admins. This API does not. Any token carrying members:write can do all three, including changing or removing another admin. The owner is the one exception. The owner cannot be removed, the owner's role cannot be changed, and no member can be moved on to the owner role (see below). Keep members:write off any token that should not change who has access.

Scopes

A scope is a named permission on your token. It decides exactly what that token is allowed to read or change.

OperationScope
List members and invitationsmembers:read
Invite, change role, removemembers:write

List members and invitations

GET /api/v1/members: every member plus every pending or rejected invitation in the org. This is a composite response, not a paginated list: organizations are small, so it returns both sets in one call.

curl https://app.avsb.cloud/api/v1/members \  -H "Authorization: Bearer avsb_svc_..."
Shell2 lines
Response
{  "data": {    "members": [      {        "orgId": "<orgId>",        "userId": "<userId>",        "roleId": "<roleId>",        "role": { "id": "<roleId>", "name": "DEVELOPER", "isBuiltIn": true, "icon": null },        "user": { "name": "Jo Bloggs", "email": "jo@example.com", "image": null }      }    ],    "invitations": [      {        "id": "<invitationId>",        "email": "new@example.com",        "roleId": "<roleId>",        "status": "PENDING",        "expires": "2026-07-01T00:00:00.000Z",        "createdAt": "2026-06-16T00:00:00.000Z",        "role": { "id": "<roleId>", "name": "VIEWER", "isBuiltIn": true, "icon": null }      }    ]  }}
JSON24 lines

Invite a member

POST /api/v1/members: invite an existing user (one who already has an account) into your org with a role. The roleId must name a role in your org, and the user must already exist, or the request fails with 404.

curl -X POST https://app.avsb.cloud/api/v1/members \  -H "Authorization: Bearer avsb_svc_..." \  -H "Content-Type: application/json" \  -H "Idempotency-Key: $(uuidgen)" \  -d '{ "email": "new@example.com", "roleId": "<roleId>" }'
Shell5 lines

Returns 201:

Response
{  "data": {    "orgId": "<orgId>",    "userId": "<userId>",    "roleId": "<roleId>",    "role": { "id": "<roleId>", "name": "VIEWER", "isBuiltIn": true, "icon": null },    "user": { "name": "New User", "email": "new@example.com", "image": null }  }}
JSON9 lines
Info

A user already in the org returns 409. An unknown email returns 404. A roleId outside your org returns 400. An org already at its plan's seat limit returns 403 with details.kind: "quota", see Refusals at 403.

409: already a member
{  "error": {    "code": "validation_failed",    "message": "User is already a member.",    "docUrl": "https://docs.avsb.cloud/docs/developer-reference/public-api/conventions#validation-errors",    "requestId": "req_9f2c41ab7e0b4d1e8c35a6f0d2b91e77"  }}
JSON8 lines

Change a member's role

PATCH /api/v1/members/{userId}: move a member to a different role. The roleId must name a role in your org. A member outside your org returns 404.

Two changes are always refused with 403. You cannot change the owner's role, and you cannot move a member on to the built-in owner role. Ownership stays put, so an org can never be left with no owner. A custom role of your own named "OWNER" is an ordinary role, and none of this applies to it.

curl -X PATCH https://app.avsb.cloud/api/v1/members/<userId> \  -H "Authorization: Bearer avsb_svc_..." \  -H "Content-Type: application/json" \  -H "Idempotency-Key: $(uuidgen)" \  -d '{ "roleId": "<roleId>" }'
Shell5 lines
Response
{  "data": {    "orgId": "<orgId>",    "userId": "<userId>",    "roleId": "<roleId>",    "role": { "id": "<roleId>", "name": "ADMIN", "isBuiltIn": true, "icon": null },    "user": { "name": "Jo Bloggs", "email": "jo@example.com", "image": null }  }}
JSON9 lines
403: cannot change the owner's role
{  "error": {    "code": "forbidden",    "message": "Cannot change the organization owner's role.",    "docUrl": "https://docs.avsb.cloud/docs/developer-reference/public-api/conventions#refusals-at-403",    "requestId": "req_9f2c41ab7e0b4d1e8c35a6f0d2b91e77"  }}
JSON8 lines
403: cannot move a member on to the owner role
{  "error": {    "code": "forbidden",    "message": "Ownership transfer is not available through this endpoint.",    "docUrl": "https://docs.avsb.cloud/docs/developer-reference/public-api/conventions#refusals-at-403",    "requestId": "req_9f2c41ab7e0b4d1e8c35a6f0d2b91e77"  }}
JSON8 lines

Both refusals are deliberate, and no token can get past either one. Moving the owner role is a confirmed action the owner takes in the dashboard, not something an API token performs. See Transferring ownership.

Remove a member

DELETE /api/v1/members/{userId}: remove a member from the org. The organization owner cannot be removed. A member outside your org returns 404.

curl -X DELETE https://app.avsb.cloud/api/v1/members/<userId> \  -H "Authorization: Bearer avsb_svc_..." \  -H "Idempotency-Key: $(uuidgen)"
Shell3 lines
Response
{  "data": { "userId": "<userId>", "removed": true }}
JSON3 lines
403: cannot remove the owner
{  "error": {    "code": "forbidden",    "message": "Cannot remove the organization owner.",    "docUrl": "https://docs.avsb.cloud/docs/developer-reference/public-api/conventions#refusals-at-403",    "requestId": "req_9f2c41ab7e0b4d1e8c35a6f0d2b91e77"  }}
JSON8 lines

Next steps

Was this helpful?