Projects and users
Use these endpoints to manage projects, their members, and the users and machine-to-machine clients that can be added to them.
None of these endpoints use the X-Project-Id header.
Projects
| Method | Path | Description | Required role |
|---|---|---|---|
POST | /api/projects | Create a project. | Admin or Tenant admin |
GET | /api/projects | List projects. | Any |
GET | /api/projects/{id} | Get a project. | Any |
PATCH | /api/projects/{projectId} | Update a project's name, description, or members. | Tenant admin or Project admin |
POST | /api/projects/{id}/leave | Remove the caller from the project. | Member |
GET | /api/projects/{id}/user/role | Get the caller's role in the project. | Any |
Tenant admins see every project. Other callers only see the projects they are a member of, and a project they are not a member of is reported as 404.
Project roles
Project members are assigned one of the following roles. The API uses the role names on the right.
| Role in the interface | API value |
|---|---|
| Domain viewer | DOMAIN_VIEWER |
| Project viewer | VIEWER |
| Project editor | COLLABORATOR |
| Project admin | ADMIN |
Create a project
curl -X POST "https://<authorization-hub-url>/api/projects" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Payments",
"description": "Policies for the payments platform",
"members": [
{ "userId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "role": "ADMIN" }
]
}'
| Field | Required | Description |
|---|---|---|
name | Yes | 1 to 500 characters, without leading or trailing spaces. Must be unique. |
description | No | Up to 4000 characters. |
members | Yes | At least one member. Each member needs a userId (the user's or client's Authorization Hub ID, as returned by /api/principal) and a role. A user can only be listed once. |
The response is 201 with the project, including its id, which you use as the X-Project-Id header in all project requests. The project is created with the default attributes and the Default cache profile.
The user who creates a project is not added as a member automatically. Include them in members if they need access.
Update a project
PATCH /api/projects/{projectId} accepts application/json with any of name, description, and members. Omitted fields are not changed. Each entry in members has a userId, an action (ADD, UPDATE, or REMOVE), and a role. The role is required for ADD and UPDATE.
{
"description": "Updated description",
"members": [
{ "userId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "action": "UPDATE", "role": "COLLABORATOR" },
{ "userId": "0e9d8c7b-6a5f-4e3d-8c2b-1a0f9e8d7c6b", "action": "REMOVE" }
]
}
A Tenant admin always has the Project admin role in the projects they are a member of. Assigning them another role is rejected.
Project errors
| Status | errorCode | Cause |
|---|---|---|
400 | DUPLICATE_USERS | The same user is listed more than once. |
400 | ROLE_REQUIRED | An ADD or UPDATE member has no role. |
400 | MEMBER_MUST_EXIST | A user in the request does not exist, or an UPDATE targets a user that is not a member. |
403 | INSUFFICIENT_PERMISSIONS | The caller is a member but not a Project admin, or a user without the Admin or Tenant admin role tried to create a project. |
404 | PROJECT_DOES_NOT_EXIST | The project does not exist, or the caller has no access to it. |
409 | PROJECT_NAME_EXISTS | A project with this name already exists. |
409 | TENANT_ADMIN_MUST_BE_PROJECT_ADMIN | A Tenant admin was given a role other than ADMIN. |
Users
| Method | Path | Description | Required role |
|---|---|---|---|
GET | /api/principal/users | List users. | Any |
GET | /api/principal/users/current | Get the authenticated user. | Any |
GET | /api/principal/users/email | Get a user by email address. Send the address in the User-Email header. | Any |
POST | /api/principal/users | Invite users. | Admin or Tenant admin |
PATCH | /api/principal/users | Update a user's name, roles, or status. | Admin or Tenant admin |
These endpoints are not part of the Swagger UI.
Invite users
The request body is an array. Each user needs an email and at least one platform role: USER, USER_ADMIN (shown as Admin in the interface), or TENANT_ADMIN.
[
{ "email": "alex.smith@example.com", "roles": ["USER"] }
]
The response is 201 with an array that has one user response per invited user, and each user's status is INVITED. If an invitation email could not be sent, that user's entry also has an actionsRequired array with the code PWD_USER_INVITATION_EMAIL_FAILED or IDP_USER_INVITATION_EMAIL_FAILED. Follow up with the user manually in that case.
Users are created one after the other. If one fails, no users are saved in Authorization Hub, but those already created in Keycloak remain. Invite one user per request if you need to retry individual failures.
Update a user
Identify the user with id or email. If both are sent, id is used. Only the following fields can be changed:
| Field | Description |
|---|---|
firstName, lastName | The user's name. |
roles | The platform roles. At least one is required if sent. |
status | INVITED, ACTIVATED, or DEACTIVATED. Deactivating a user signs them out. Setting a deactivated user to ACTIVATED or INVITED sends a new invitation and sets the status to INVITED. |
The rules in Platform roles apply.
User response
The user endpoints do not return the user directly. Each user is wrapped in an object with the user in user, and an actionsRequired array when a follow-up is needed. Endpoints that return several users return an array of these objects.
{
"user": {
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"firstName": "Alex",
"lastName": "Smith",
"email": "alex.smith@example.com",
"roles": ["USER"],
"status": "ACTIVATED"
}
}
The user object has the following fields:
| Field | Description |
|---|---|
id | The user's Authorization Hub ID. |
externalUserId | The ID of the user in Keycloak. It is the sub claim in the user's tokens. |
firstName, lastName, email | The user's details. |
roles | The platform roles. |
status | INVITED, ACTIVATED, or DEACTIVATED. |
invitedOn, verifiedOn, lastLogin, deactivatedOn | Timestamps. |
User errors
| Status | errorCode | Cause |
|---|---|---|
403 | INSUFFICIENT_PERMISSIONS | A rule in Platform roles was violated. |
404 | USER_NOT_FOUND | No user matches the ID or email. |
409 | DUPLICATE_USER | A user with this email already exists. |
Clients
| Method | Path | Description |
|---|---|---|
GET | /api/principal/clients | List the machine-to-machine clients that can be added to projects. |
The list contains the clients defined in Keycloak, except the built-in clients that Authorization Hub needs to operate. Read Client management to create one. The call also synchronizes Authorization Hub with Keycloak, so newly created clients appear in the list, and clients that are deleted or disabled in Keycloak are shown as DEACTIVATED.
Each entry has an id, which is the value to use as userId when you add the client to a project, along with the clientId, name, description, and status.