User Endpoints
Endpoints are under /v1/users.
Base URL: https://api.gpcn.com/v1
See the API Reference → for examples in TypeScript, Python, Go, and C#.
Get Current User
GET /users/me
Returns the authenticated user's profile. No special permission required.
List Users
GET /users
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number |
limit |
integer | 10 |
Items per page (max 100) |
sort |
string | createdAt:desc |
Sort field and direction |
search |
string | — | Search by email, first name, or last name |
entityId |
UUID | — | List the users of this tenant instead of your own (must be your own tenant or one beneath it) |
excludeResourceGroupId |
UUID | — | Exclude users who are live members of this resource group. Naming the Default group excludes everyone, since every user is a member of it. |
inviteStatus |
string | — | Filter: activated, pending, expired (repeatable) |
resourceGroupId |
UUID | — | Filter by resource group (repeatable; OR'd together). Matches explicit memberships, except the tenant's Default group id matches every live user. |
roleId |
string | — | Filter by role (repeatable; use 0 for no roles) |
noResourceGroup |
boolean | — | Retired. Every user belongs to the tenant's Default group, so this answers 400 when true. |
noRole |
boolean | — | Shorthand for roleId=0 — only users with no roles assigned |
deletedFilter |
string | exclude |
exclude, include, or only |
curl https://api.gpcn.com/v1/users \
-H "X-API-Key: gpcn_your_api_key_here"
Error: 400 Bad Request
The retired "no resource group" filter was used (noResourceGroup=true or resourceGroupId=0):
{
"success": false,
"message": "Filtering users by \"no resource group\" is retired: every user of a tenant belongs to its Default resource group.",
"error": { "code": "Validation Error", "statusCode": 400 }
}
Create User (Invite or Register)
POST /users
Request Body (Invite)
{
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Developer",
"action": "invite",
"roleNames": ["tenant-viewer"],
"resourceGroupIds": ["880e8400-e29b-41d4-a716-446655440001"]
}
Request Body (Register)
{
"email": "jane@example.com",
"password": "SecurePass123!",
"firstName": "Jane",
"lastName": "Developer",
"action": "register",
"roleNames": ["tenant-viewer"],
"resourceGroupIds": ["880e8400-e29b-41d4-a716-446655440001"],
"entityId": "entity-uuid"
}
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | Yes | User email |
action |
string | No | "invite" (default) or "register" |
password |
string | Register only | 12–50 chars, mixed case + number + special |
firstName |
string | Yes on invite | First name |
lastName |
string | Yes on invite | Last name |
roleNames |
string[] | No | Roles to assign, max 20. Defaults to ["tenant-viewer"]. An unknown name is a 422; a role above your own privilege is a 403. |
resourceGroupIds |
UUID[] | No | Resource groups to add the user to besides the tenant's Default group, which every user belongs to automatically. Max 50; each must belong to the target tenant. |
entityId |
UUID | No | Tenant to create in (defaults to yours; must be your own tenant or one beneath it) |
curl -X POST https://api.gpcn.com/v1/users \
-H "X-API-Key: gpcn_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Developer",
"action": "invite",
"roleNames": ["tenant-viewer"],
"resourceGroupIds": ["880e8400-e29b-41d4-a716-446655440001"]
}'
Error: 422 Unprocessable Entity
A resourceGroupIds list longer than 50, more than 20 roleNames, or an unknown role name:
{
"success": false,
"message": "Invalid Parameters: roleNames: Unknown role \"tenant-super\"",
"error": { "code": "Validation Error", "statusCode": 422 }
}
Response (201 Created)
Get User Details
GET /users/{id}
Edit User
PUT /users/{id}
Request Body
{ "firstName": "Jane", "lastName": "Senior Dev", "email": "jane.new@example.com" }
Delete User
DELETE /users/{id}
Soft-delete. User can no longer sign in.
Response (204 No Content)
Resend Invitation
POST /users/{id}/resend-invite
Get User's Resource Groups
GET /users/{id}/resource-groups
Paginated list of resource groups the user is an explicit member of. The tenant's Default group isn't listed here, even though every user belongs to it implicitly.
Update Password (Self)
PUT /users/{id}/password
No special permission (self-service only).
Request Body
{ "currentPassword": "OldPass123!", "newPassword": "NewPass456!" }
Forgot Password
POST /users/forgot-password
Public endpoint (no auth required). Rate limited: 5 requests per IP per 15 minutes.
Request Body
{ "email": "jane@example.com" }
Get User's Roles
GET /users/{userId}/roles
Assign Role
POST /users/{userId}/roles
Requires role:create for an organization-wide assignment, or role:assign-scoped (held by Tenant Manager) for one scoped to a resource group.
Request Body
{ "roleName": "tenant-operator", "resourceGroupId": "880e8400-e29b-41d4-a716-446655440001" }
| Field | Type | Required | Description |
|---|---|---|---|
roleName |
string | Yes | A system role or one of the tenant's custom roles |
entityId |
UUID | No | Tenant scope (defaults to yours) |
resourceGroupId |
UUID | No | Scopes the assignment to one resource group instead of the whole tenant |
Error: 422 Unprocessable Entity
tenant-admin or tenant-manager named with a resourceGroupId:
{
"success": false,
"message": "tenant-admin and tenant-manager are tenant-wide roles and cannot be assigned to a resource group",
"error": { "code": "Validation Error", "statusCode": 422 }
}
Revoke Role
DELETE /users/{userId}/roles/{roleName}
Pass resourceGroupId as a query parameter to revoke a resource-group-scoped assignment; omit it to revoke an organization-wide one.
Error: 404 Not Found
The user holds no live assignment of that role at that scope:
{
"success": false,
"message": "Role assignment not found",
"error": { "code": "Role Not Found", "statusCode": 404 }
}
Response (204 No Content)
Bulk Delete Users
POST /users/bulk/delete
{ "ids": ["user-uuid-1", "user-uuid-2"] }
1–50 IDs.
Bulk Resend Invites
POST /users/bulk/resend-invite
{ "ids": ["user-uuid-1", "user-uuid-2"] }
Bulk Assign Roles
POST /users/bulk/assign-roles
Assigns a single organization-wide role to multiple users.
{ "userIds": ["user-uuid-1", "user-uuid-2"], "roleName": "tenant-viewer" }
1–50 user IDs.
Bulk Assign Resource Groups
POST /users/bulk/assign-resource-groups
Creates every user–group combination. Each assignment is attempted independently; partial success is possible.
{ "userIds": ["user-uuid-1"], "resourceGroupIds": ["880e8400-e29b-41d4-a716-446655440001"] }
1–50 IDs in each array.
Bulk Remove Resource Groups
POST /users/bulk/remove-resource-groups
Removes multiple users from multiple resource groups — every user–group pair, each attempted independently and reported under the id <userId>::<resourceGroupId>. Removing a user from a group also revokes any role assignment they hold scoped to it. A pair with no membership succeeds unchanged.
{ "userIds": ["user-uuid-1"], "resourceGroupIds": ["880e8400-e29b-41d4-a716-446655440001"] }
1–50 IDs in each array, no duplicates.
Error: 422 Unprocessable Entity
An empty array, more than 50 ids in either array, or a duplicate id:
{
"success": false,
"message": "Invalid Parameters: userIds: Array must contain at most 50 element(s)",
"error": {
"code": "Validation Error",
"statusCode": 422,
"details": { "issues": [{ "path": "userIds", "message": "Array must contain at most 50 element(s)" }] }
}
}
A pair naming the tenant's Default group fails that one pair with "error": "Every user of the tenant is a member of the Default resource group" in its own result row — every user always belongs to it.
Next Steps
- Manage Users in the Portal → — invite and manage users from the dashboard
- Resource Group Endpoints → — manage resource groups via API
- Authentication → — API keys and permission scoping
.png)