Portal API Reference
Overview
The CAIP Portal API provides programmatic access to manage spaces, users, Kubeflow workspaces, API keys, CDH links, authentication, and cost reporting within the Connected AI Platform. It supports both user and machine-to-machine (M2M) integration.
- Base URL:
https://portal.api.caip.bmw.cloud - Version: 1.0.0
Authentication
All endpoints require authentication using a JWT bearer token or M2M token in the Authorization header:
Authorization: Bearer <your-jwt-token>
Error Handling
Below is a standard error format returned by the API in JSON:
{
"error": {
"code": "<status_code>",
"message": "<error_message>"
}
}
Common HTTP Status Codes
| Status Code | Description |
|---|---|
200 | OK - Request succeeded |
201 | Created - Resource created successfully |
204 | No Content - Request succeeded, no content returned |
400 | Bad Request - Invalid input data |
401 | Unauthorized - Invalid credentials provided |
403 | Forbidden - Access denied |
404 | Not Found - Resource not found |
500 | Internal Server Error - An error occurred on the server |
Table of Contents
- Spaces
- Users
- Admin
- Authentication
- Kubeflow Workspaces
- CDH
- API Keys
- Permissions
- Feature Flags
- Health
- Costs
- Space Workflow Mapping
Endpoints
Spaces
Endpoints for managing spaces on CAIP.
Create a New CAIP Space
- Allows superusers to create new spaces.
- Endpoint:
POST /v1/spaces - Authentication: Required
Request Body:
{
"spaceName": "Sample Space",
"appId": "App2123",
"description": "This is a sample space.",
"itsmServiceOffering": "ITSM Service Offering"
}
Response:
{
"spaceName": "Sample Space",
"appId": "App2123",
"description": "This is a sample space.",
"itsmServiceOffering": "ITSM Service Offering",
"spaceId": "507f1f77bcf86cd799439011",
"createdAt": "2025-08-20T14:35:44.922Z"
}
Example Request:
curl -X POST "https://portal.api.caip.bmw.cloud/v1/spaces" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"spaceName": "Sample Space",
"appId": "App2123",
"description": "This is a sample space.",
"itsmServiceOffering": "ITSM Service Offering"
}'
Response Codes:
201: Space created successfully403: Forbidden - Superuser access required500: Internal Server Error
Retrieve Spaces Based on User Permissions
- Superusers see all spaces, regular users see only spaces where they are owner or member.
- Endpoint:
GET /v1/spaces - Authentication: Required
Response:
[
{
"spaceName": "Sample Space",
"appId": "App2123",
"description": "This is a sample space.",
"itsmServiceOffering": "ITSM Service Offering",
"spaceId": "507f1f77bcf86cd799439011",
"createdAt": "2025-08-20T14:35:44.922Z"
}
]
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: Spaces retrieved successfully500: Internal Server Error
Retrieve a Specific Space
- Users must be members or owners of the space.
- Endpoint:
GET /v1/spaces/{id} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The unique identifier of the space |
Response:
{
"spaceName": "Sample Space",
"description": "This is a sample space.",
"appId": "App2123",
"itsmServiceOffering": "ITSM Service Offering",
"spaceId": "507f1f77bcf86cd799439011",
"createdAt": "2025-08-20T14:35:44.922Z",
"createdBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"modifiedBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"user": {
"role": "owner",
"superuser": true
},
"userCount": 5,
"kubeflowPipelinesCount": 3,
"apiKeysCount": 3,
"cdhCount": 3
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: Space retrieved successfully403: Forbidden - Space access required404: Space not found500: Internal Server Error
Update Specific space based on user role
- Only space owners can update (database lookup)
- Endpoint:
PATCH /v1/spaces/{id} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The unique identifier of the space |
Request:
{
"spaceName": "Updated CAIP Space",
"appId": "updated-app-123",
"description": "Updated description for the CAIP space",
"itsmServiceOffering": "ITSM Service Offering"
}
Response:
{
"spaceName": "Updated CAIP Space",
"description": "Updated description for the CAIP space",
"appId": "updated-app-123",
"itsmServiceOffering": "ITSM Service Offering",
"spaceId": "507f1f77bcf86cd799439011"
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: Space retrieved successfully403: Forbidden - Space access required404: Space not found500: Internal Server Error
Users
Endpoints for managing users within spaces.
Get All Users in a Space
- Retrieves all users in a specific space along with their roles.
- Endpoint:
GET /v1/spaces/{spaceId}/users - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the space |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Number of results to retrieve per page. If not provided, all results are returned. |
page | number | No | Page number for pagination. Only applies when limit is provided. |
search | string | No | Search text to filter results |
sortOrder | string | No | Sort order (default: asc) |
sortBy | string | No | Field to sort by |
role | string | No | Filter users by role (owner or member) |
Response:
{
"data": [
{
"userId": "507f1f77bcf86cd799439011",
"qNumber": "QXZ60XV",
"name": "Harshad Narayane",
"department": "JZ-IN",
"mailAddress": "harshad.narayane@bti.bmwgroup.com",
"role": "owner"
}
],
"pagination": {
"totalRecords": 100,
"currentPage": 1,
"totalPages": 10,
"nextPage": 2,
"prevPage": null
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/users" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: List of users retrieved successfully404: Space not found500: Internal Server Error
Add a User to a Space
- Adds a user to a space with a specified role. Only superusers can add users.
- Endpoint:
POST /v1/spaces/{spaceId}/users - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the space |
Request Body:
{
"qNumber": "q123456",
"name": "John Doe",
"department": "DE-791",
"mailAddress": "john.doe@bmw.com",
"role": "member"
}
Response:
{
"userId": "689317bd63657ea54b0bc206",
"qNumber": "QXZ60XV",
"name": "Harshad Narayane",
"department": "JZ-IN",
"mailAddress": "harshad.narayane@bti.bmwgroup.com",
"role": "member",
"createdAt": "2025-08-20T10:30:00.000Z"
}
Example Request:
curl -X POST "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/users" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"qNumber": "q123456",
"name": "John Doe",
"department": "DE-791",
"mailAddress": "john.doe@bmw.com",
"role": "member"
}'
Response Codes:
201: User added successfully400: Bad request - User already exists in space or invalid data403: Forbidden - Superuser access required404: Space not found500: Internal Server Error
Update User Role in a Space
- Updates a user's role within a space. Only superusers can update roles.
- Endpoint:
PATCH /v1/spaces/{spaceId}/users/{userId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the space |
userId | string | Yes | The unique identifier of the user to update |
Request Body:
{
"role": "owner"
}
Response:
{
"userId": "689317bd63657ea54b0bc206",
"qNumber": "QXZ60XV",
"name": "Harshad Narayane",
"department": "JZ-IN",
"mailAddress": "harshad.narayane@bti.bmwgroup.com",
"role": "owner",
"modifiedAt": "2025-08-20T10:30:00.000Z"
}
Example Request:
curl -X PATCH "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/users/689317bd63657ea54b0bc206" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{"role": "owner"}'
Response Codes:
200: User role updated successfully400: Bad request - Invalid data403: Forbidden - Superuser access required404: User membership not found500: Internal Server Error
Remove User from a Space
- Remove a user from a space. Only superusers can remove users.
- Endpoint:
DELETE /v1/spaces/{spaceId}/users/{userId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the space |
userId | string | Yes | The unique identifier of the user to remove |
Example Request:
curl -X DELETE "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/users/689317bd63657ea54b0bc206" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
204: User removed successfully403: Forbidden - Superuser access required404: User or space not found500: Internal Server Error
Admin
Endpoints for managing superusers in the system.
Add Superuser
- Add a new superuser to the system.
- Endpoint:
POST /v1/admin/superuser - Authentication: Required
Request Body:
{
"qNumber": "q123456",
"name": "John Doe",
"department": "DE-791",
"mailAddress": "john.doe@bmw.com"
}
Response:
{
"userId": "69c3cefa52094c17508373c5",
"qNumber": "q123111",
"name": "John Doe",
"department": "DE-791",
"mailAddress": "john.doe222@bmw.com",
"superuser": true,
"createdBy": "689317bd63657ea54b0bc415",
"createdAt": "2026-03-25T12:03:06.001Z",
"modifiedBy": "689317bd63657ea54b0bc415",
"modifiedAt": "2026-03-25T12:03:06.001Z",
}
Example Request:
curl -X POST "https://portal.api.caip.bmw.cloud/v1/admin/superuser" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"qNumber": "q123456",
"name": "John Doe",
"department": "DE-791",
"mailAddress": "john.doe@bmw.com"
}'
Response Codes:
201: Superuser created successfully400: Bad request - Superuser already exists500: Internal Server Error
Get All Superusers
- Retrieve a paginated list of all superusers in the system.
- Endpoint:
GET /v1/admin/superuser - Authentication: Required
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Number of superusers to retrieve per page. Defaults to all. |
page | number | No | Page number for pagination. Only applies with limit. |
search | string | No | Search superusers by name, email, Q number, or department |
sortBy | string | No | Field to sort by |
sortOrder | string | No | Sort order (default: asc) |
Response:
{
"data": [
{
"userId": "689317bd63657ea54b0bc206",
"qNumber": "QXZ60XV",
"name": "John Doe",
"department": "JZ-IN",
"mailAddress": "john.doe@example.com",
"superuser": true,
"createdBy": "689317bd63657ea54b0bc206",
"createdAt": "2024-06-01T12:34:56.789Z",
"modifiedBy": "689317bd63657ea54b0bc206",
"modifiedAt": "2024-06-01T12:34:56.789Z"
}
],
"pagination": {
"totalRecords": 100,
"currentPage": 1,
"totalPages": 10,
"nextPage": 2,
"prevPage": null
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/admin/superuser?limit=10&page=1" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: Paginated list of superusers retrieved successfully403: Forbidden - Superuser access required500: Internal Server Error
Update Superuser
- Update details of an existing superuser.
- Endpoint:
PATCH /v1/admin/superuser/{userId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | The unique identifier of the user to update |
Request Body:
{
"qNumber": "q123456",
"name": "John Doe",
"department": "DE-791",
"mailAddress": "john.doe@bmw.com"
}
Response:
{
"userId": "689317bd63657ea54b0bc206",
"qNumber": "QXZ60XV",
"name": "John Doe",
"department": "JZ-IN",
"mailAddress": "john.doe@example.com",
"superuser": true,
"createdBy": "689317bd63657ea54b0bc206",
"createdAt": "2024-06-01T12:34:56.789Z",
"modifiedBy": "689317bd63657ea54b0bc206",
"modifiedAt": "2024-06-01T12:34:56.789Z",
}
Example Request:
curl -X PATCH "https://portal.api.caip.bmw.cloud/v1/admin/superuser/689317bd63657ea54b0bc206" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"qNumber": "q123456",
"name": "John Doe",
"department": "DE-791",
"mailAddress": "john.doe@bmw.com"
}'
Response Codes:
200: Superuser updated successfully400: Bad request - Superuser already exists500: Internal Server Error
Kubeflow Workspaces
Endpoints for managing Kubeflow workspaces.
Create a Managed Kubeflow Workspace in a CAIP Space
- Creates a new workspace record linking Kubeflow metadata to an existing CAIP space. Multiple workspaces can be created per space, but namespace names must be unique within each space. Only superusers can create workspaces.
- Endpoint:
POST /v1/spaces/{spaceId}/mkflw-workspaces - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
Request Body:
{
"region": "emea",
"clusterName": "mcaip-kflw-prod",
"namespaceName": "ai-rsrch-myteam-prod"
}
Response:
{
"workspaceId": "507f1f77bcf86cd799439012",
"spaceId": "507f1f77bcf86cd799439011",
"region": "emea",
"clusterName": "mcaip-kflw-prod",
"namespaceName": "ai-rsrch-myteam-prod"
}
Example Request:
curl -X POST "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/mkflw-workspaces" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"region": "emea",
"clusterName": "mcaip-kflw-prod",
"namespaceName": "ai-rsrch-myteam-prod"
}'
Response Codes:
201: Kubeflow workspace created successfully400: Bad request - Invalid input data403: Forbidden - Superuser access required404: Space not found409: Conflict - Workspace exists with this namespace name500: Internal Server Error
Get Kubeflow Workspace Metadata for a CAIP Space
- Retrieves workspace metadata for a given CAIP space. If namespaceName query parameter is provided, returns a specific workspace; otherwise returns all workspaces for the space. Any space member can view workspace metadata.
- Endpoint:
GET /v1/spaces/{spaceId}/mkflw-workspaces - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
namespaceName | string | No | Namespace name of the specific workspace |
Response:
[
{
"workspaceId": "68b0287f9941ca0b5a4c7965",
"spaceId": "689318ceaffeb213ed9876c7",
"region": "cn",
"clusterName": "kubeflow_cluster_test",
"namespaceName": "kubeflow-caip",
"createdBy":
{
"qxId": "QXZ5VUW",
"name": "Shital Diwane"
},
"modifiedBy":
{
"qxId": "QXZ60XV",
"name": "Harshad Narayane"
},
"createdAt": "2025-08-28T09:59:27.065Z",
"updatedAt": "2025-08-29T06:23:19.103Z"
}
]
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/mkflw-workspaces" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: Workspace metadata retrieved successfully403: Forbidden - Space access required404: Workspace not found for the given space500: Internal Server Error
Update Kubeflow Workspace Metadata
- Updates existing workspace metadata. Only specified fields will be updated. Only superusers can update workspaces.
- Endpoint:
PATCH /v1/spaces/{spaceId}/mkflw-workspaces/{mkflwworkspaceId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
mkflwworkspaceId | string | Yes | The unique identifier of the workspace to update |
Request
{
"region": "cn",
"clusterName": "kubeflow_cluster_test",
"namespaceName": "kubeflow-caip-updated"
}
Response:
{
"workspaceId": "68b0287f9941ca0b5a4c7965",
"spaceId": "689318ceaffeb213ed9876c7",
"region": "cn",
"clusterName": "kubeflow_cluster_test",
"namespaceName": "kubeflow-caip-updated"
}
Example Request:
curl -X 'PATCH' \
'https://portal.api.caip.bmw.cloud/v1/spaces/689318ceaffeb213ed9876c7/mkflw-workspaces/68b0287f9941ca0b5a4c7965' \
-H 'accept: application/json' \
-H "Authorization: Bearer M2M token" \
-H 'Content-Type: application/json' \
-d '{
"region": "emea",
"clusterName": "kubeflow_cluster_test",
"namespaceName": "kubeflow-caip-updated"
}'
Response Codes:
- 200: The Kubeflow workspace has been successfully updated.
- 400: Bad Request - Invalid input data or region format.
- 403: Forbidden - Superuser access required.
- 404, Not Found - Workspace with given ID not found.
- 409, Conflict - A workspace with the new namespace name already exists.
- 500, Internal Server Error.
Delete Kubeflow Workspace Metadata
- Deletes an existing workspace metadata record. Only superusers can delete workspaces.
- Endpoint:
DELETE/v1/spaces/{spaceId}/mkflw-workspaces/{mkflwworkspaceId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
mkflwworkspaceId | string | Yes | The unique identifier of the workspace to update |
Example Request:
curl -X DELETE\
'https://portal.api.caip.bmw.cloud/v1/spaces/689318ceaffeb213ed9876c7/mkflw-workspaces/68b0287f9941ca0b5a4c7965' \
-H 'accept: application/json' \
-H 'Authorization: Bearer M2M token\
-H 'Content-Type: application/json' \
Response Codes:
- 204 The Kubeflow workspace has been successfully deleted.
- 400 Bad Request - Invalid workspace ID format.
- 403 Forbidden - Superuser access required.
- 404 Not Found - Workspace with given ID not found.
- 500 Internal Server Error.
CDH
Endpoints for managing CDH links.
Get CDH Links for Given SpaceId
- Retrieves all CDH links for given spaceId with optional pagination, search, and sorting. CDH mappings can be viewed by Space Members and Space Owners.
- Endpoint:
GET /v1/spaces/{spaceId}/cdh-links - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
stage | string | No | Filter by stage (Dev, Int, Prod) |
cdhType | string | No | Filter by CDH type (Provider, UseCase) |
limit | number | No | Number of results to retrieve per page. If not provided, all results are returned. |
page | number | No | Page number for pagination. Only applies when limit is provided. |
search | string | No | Search text to filter results |
sortOrder | string | No | Sort order (default: asc) |
sortBy | string | No | Field to sort by |
Response:
{
"data": [
{
"cdhWorkspaceId": "507f1f77bcf86cd799439012",
"cdhEnvAccountID": "507f1f77bcf86cd799439012",
"name": "My CDH",
"cdhType": "Provider",
"cdhHub": "global",
"cdhProviderId": "507f1f77bcf86cd799439012",
"cdhUseCaseId": "507f1f77bcf86cd799439012",
"stage": "Dev",
"spaceId": "507f1f77bcf86cd799439011",
"cdhLink": "https://data.bmw.cloud/<CDHHub>/providers/<CDHProviderID>/environments/<CDHEnvAccountID>",
"createdBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"modifiedBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"createdAt": "2025-08-20T14:35:44.922Z",
"updatedAt": "2025-08-20T14:35:44.922Z"
}
],
"pagination": {
"totalRecords": 100,
"currentPage": 1,
"totalPages": 10,
"nextPage": 2,
"prevPage": null
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/cdh-links" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: CDH Links retrieved successfully403: Forbidden - access required404: CDH Link/Links not found for the given space500: Internal Server Error
Create a CDH Workspace in a CAIP Space
- Creates a new workspace record linking CDH metadata to an existing CAIP space. Multiple workspaces can be created per space, Only superusers can create workspaces.
- Endpoint:
POST /v1/spaces/{spaceId}/cdh-links - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
Request Body:
{
"cdhEnvAccountID": "507f1f77bcf86cd799439012",
"name": "My CDH",
"cdhType": "Provider",
"cdhHub": "global",
"cdhProviderId": "507f1f77bcf86cd799439012",
"cdhUseCaseId": "507f1f77bcf86cd799439012",
"stage": "Dev"
}
Response:
{
"cdhWorkspaceId": "507f1f77bcf86cd799439012",
"cdhEnvAccountID": "507f1f77bcf86cd799439012",
"name": "My CDH",
"cdhType": "Provider",
"cdhHub": "global",
"cdhProviderId": "507f1f77bcf86cd799439012",
"cdhUseCaseId": "507f1f77bcf86cd799439012",
"stage": "Dev",
"spaceId": "507f1f77bcf86cd799439011",
"cdhLink": "https://data.bmw.cloud/global/providers/507f1f77bcf86cd799439012/environments/507f1f77bcf86cd799439012"
}
Example Request:
curl -X POST "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/cdh-links" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"cdhEnvAccountID": "507f1f77bcf86cd799439012",
"name": "My CDH",
"cdhType": "Provider",
"cdhHub": "global",
"cdhProviderId": "507f1f77bcf86cd799439012",
"cdhUseCaseId": "507f1f77bcf86cd799439012",
"stage": "Dev"
}'
Response Codes:
201: CDH workspace created successfully400: Bad request - Invalid input data403: Forbidden - Superuser access required404: Space not found409: Conflict - Workspace exists with this name500: Internal Server Error
Update CDH Workspace Metadata
- Updates existing workspace metadata. Only specified fields will be updated.
- Endpoint:
PATCH /v1/spaces/{spaceId}/cdh-links/{cdhworkspaceId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
cdhworkspaceId | string | Yes | The unique identifier of the workspace to update |
Request Body:
{
"cdhEnvAccountID": "507f1f77bcf86cd799439012",
"name": "My CDH",
"cdhType": "Provider",
"cdhHub": "global",
"cdhProviderId": "507f1f77bcf86cd799439012",
"cdhUseCaseId": "507f1f77bcf86cd799439012",
"stage": "Dev"
}
Response:
{
"cdhWorkspaceId": "507f1f77bcf86cd799439012",
"cdhEnvAccountID": "507f1f77bcf86cd799439012",
"name": "My CDH",
"cdhType": "Provider",
"cdhHub": "global",
"cdhProviderId": "507f1f77bcf86cd799439012",
"cdhUseCaseId": "507f1f77bcf86cd799439012",
"stage": "Dev",
"spaceId": "507f1f77bcf86cd799439011"
}
Example Request:
curl -X PATCH "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/cdh-links/507f1f77bcf86cd799439012" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"cdhEnvAccountID": "507f1f77bcf86cd799439012",
"name": "My CDH",
"cdhType": "Provider",
"cdhHub": "global",
"cdhProviderId": "507f1f77bcf86cd799439012",
"cdhUseCaseId": "507f1f77bcf86cd799439012",
"stage": "Dev"
}'
Response Codes:
200: CDH workspace updated successfully400: Bad request - Invalid input data403: Forbidden - Superuser access required404: Workspace not found500: Internal Server Error
Delete CDH Workspace Metadata
- Deletes an existing mapping metadata record. Only superusers can delete cdh mapping.
- Endpoint:
DELETE /v1/spaces/{spaceId}/cdh-links/{cdhworkspaceId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
cdhworkspaceId | string | Yes | The unique identifier of the mapping to delete |
Example Request:
curl -X DELETE "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/cdh-links/507f1f77bcf86cd799439012" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
204: CDH mapping deleted successfully400: Bad request - Invalid workspace ID format403: Forbidden - Superuser access required404: CDH mapping not found500: Internal Server Error
API Keys
Endpoints for managing API keys within spaces.
Create a New API Key for a CAIP Space
- Creates a new API key for the specified CAIP space.
- Endpoint:
POST /v1/spaces/{spaceId}/apikeys - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
Request Body:
{
"name": "caip-api-key"
}
Response:
{
"apiKeyId": "5d50e8400e29b41d4a71644665544",
"spaceId": "6d50e840029b41d4a71644665544",
"name": "caip-api-key",
"expiryDate": "2024-12-31T23:59:59.999Z",
"apiKeyArn": "***",
"status": "Active",
"revokedAt": "2024-01-01T12:00:00.000Z",
"createdBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"createdAt": "2024-01-01T12:00:00.000Z",
"modifiedBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"updatedAt": "2024-01-01T12:00:00.000Z",
"apiKeyValue": "550e8400e29b41d4a71644665544"
}
Example Request:
curl -X POST "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/apikeys" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"name": "caip-api-key"
}'
Response Codes:
201: API key created successfully400: Bad request - Invalid input data403: Forbidden - Superuser access required404: Space not found500: Internal Server Error
Get All API Keys for a CAIP Space
- Retrieves all API keys for the specified space with audit information.
- Endpoint:
GET /v1/spaces/{spaceId}/apikeys - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Number of results to retrieve per page. If not provided, all results are returned. |
page | number | No | Page number for pagination. Only applies when limit is provided. |
search | string | No | Search text to filter results |
sortOrder | string | No | Sort order (default: asc) |
sortBy | string | No | Field to sort by |
status | string | No | Filter API keys by status (Active or Revoked) |
Response:
{
"data": [
{
"apiKeyId": "5d50e8400e29b41d4a71644665544",
"spaceId": "6d50e840029b41d4a71644665544",
"name": "caip-api-key",
"expiryDate": "2024-12-31T23:59:59.999Z",
"apiKeyArn": "***",
"status": "Active",
"revokedAt": "2024-01-01T12:00:00.000Z",
"createdBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"createdAt": "2024-01-01T12:00:00.000Z",
"modifiedBy": {
"qxId": "QXZ60XV",
"name": "John Doe"
},
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"totalRecords": 100,
"currentPage": 1,
"totalPages": 10,
"nextPage": 2,
"prevPage": null
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/apikeys" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: API keys retrieved successfully403: Forbidden - Space access required500: Internal Server Error
Delete an API Key for a CAIP Space
- Deletes the specified API key from the CAIP space.
- Endpoint:
DELETE /v1/spaces/{spaceId}/apikeys/{apiKeyId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The unique identifier of the CAIP space |
apiKeyId | string | Yes | The unique identifier of the API key to delete |
Example Request:
curl -X DELETE "https://portal.api.caip.bmw.cloud/v1/spaces/507f1f77bcf86cd799439011/apikeys/5d50e8400e29b41d4a71644665544" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
204: API key deleted successfully400: Bad request - Invalid API Key ID format403: Forbidden - Owner access required404: API key not found500: Internal Server Error
Permissions
Endpoints for managing user permissions.
Get User Permissions for a Space
- Returns user roles and permissions for OPA authorization.
- Endpoint:
GET /v1/permissions/{spaceId}/{userId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | Space ID |
userId | string | Yes | User QX ID (e.g., QXZ60XV) |
Response:
{
"roles": ["Space Owner"],
"isSuperuser": false,
"isSpaceOwner": true,
"isSpaceMember": true
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/permissions/507f1f77bcf86cd799439011/QXZ60XV" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: User permissions retrieved successfully404: User or space not found
Get User Global Permissions
- Returns user superuser status for OPA authorization.
- Endpoint:
GET /v1/permissions/{userId} - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | User QX ID (e.g., QXZ60XV) |
Response:
{
"user": {
"qNumber": "QXZ60XV",
"superuser": true
},
"authenticated": true
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/permissions/QXZ60XV" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: User global permissions retrieved successfully404: User not found
Feature Flags
Endpoints for retrieving feature flags and their statuses.
Get All Feature Flags
- Returns all feature flags with their current enabled/disabled status.
- Endpoint:
GET /v1/feature-flags - Authentication: Required
Response:
{
"enable_agent_feature":
{
"enabled": true,
"isPreview": false
},
"enable_cost_feature":
{
"enabled": true,
"isPreview": true
},
"enable_workflow_feature":
{
"enabled": true,
"isPreview": false
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/feature-flags" \
-H "Authorization: Bearer M2M token \
-H "Content-Type: application/json"
Response Codes:
200: Feature flags retrieved successfully401: Unauthorized - Authentication required
Get Feature Flags Service Health Status
- Returns health and status information about the AppConfig sidecar.
- Endpoint:
GET /v1/feature-flags/health - Authentication: Not required
Response:
{
"status": "healthy",
"sidecarHealthy": true,
"serviceStatus": {
"available": true,
"agentUrl": "http://localhost:2772"
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/feature-flags/health" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: Health status retrieved successfully
Health
Endpoints for checking the health status of the API.
Health Check Endpoint
- Returns the health status of the API including dependency checks.
- Endpoint:
GET/health - Authentication: Not required
Response
{
"status": "healthy",
"timestamp": "2026-03-26T08:02:15.897Z", "uptime": 5259.401624688,
"environment": "test",
"authentication": "Multi-Method: JWT, Kong Headers, API Keys",
"message": "CAIP Portal API is running successfully",
"checks":
{
"database": "healthy"
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/health" \
-H "Content-Type: application/json"
Response Codes:
200: API health status retrieved successfully
Liveness Probe Endpoint
- Returns liveness status of the API indicating if the application process is alive.
- Endpoint:
GET/liveness - Authentication: Not required
Response
{
"status": "alive",
"timestamp": "2026-03-26T08:04:42.205Z"
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/liveness" \
-H "Content-Type: application/json"
Response Codes:
200: API process is alive500: API process has failed
Readiness Probe Endpoint
- Returns readiness status of the API indicating if the application is ready to serve traffic.
- Endpoint:
GET/readiness - Authentication: Not required
Response
{ "status": "ready",
"timestamp": "2026-03-26T08:07:14.926Z", "checks":
{
"database": "ready"
}
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/readiness" \
-H "Content-Type: application/json"
Response Codes:
200: API is ready to serve traffic503: API is not ready
Costs
Endpoints for managing costs and generating reports.
Get Monthly Cost Report for a Space (User Only)
- Retrieving monthly aggregated cost data. Supports both completed months (pre-aggregated) and current month (real-time). Validated through WEN authentication at ingress level.
- Endpoint:
GET /v1/spaces/{spaceId}/costs/report - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The ID of the space |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
month | string | Yes | Month in YYYY-MM format |
includeDetails | boolean | No | Include detailed daily entries |
Response:
{
"spaceId": "space-12345",
"month": "2025-08",
"currency": "EUR",
"services": [
{
"service": "managed-kubeflow",
"totalCost": 1245.32,
"billingPositions": [
{
"day": "2025-08-01",
"calculatedCost": 38.92
},
{
"day": "2025-08-02",
"calculatedCost": 40.1
}
]
}
],
"totals": {
"overallCost": 1768.09,
"services": {
"managed-kubeflow": 1245.32
}
},
"generatedAt": "2025-08-20T03:00:00Z"
}
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces/space-12345/costs/report?month=2025-08&includeDetails=false" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: Monthly cost report retrieved successfully401: Unauthorized - User bearer token required403: Forbidden - M2M tokens not allowed
Create Cost Entry for a Space (M2M Only)
- M2M-only endpoint for creating cost entries.
- Endpoint:
POST /v1/spaces/{spaceId}/costs - Authentication: Required
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
spaceId | string | Yes | The ID of the space |
Request Body:
{
"day": "2025-08-20",
"service": "managed-kubeflow",
"calculatedCost": 0.94,
"currency": "EUR",
"usageDetails": "{\"cluster\":\"mcaip-train\",\"namespace\":\"mkf-usecase-a\",\"origin\":\"kubecost\"}",
"description": "daily MKF infra share"
}
Response:
{
"entryId": "60f1edn8abcf89cd7e45643",
"day": "2025-08-20",
"service": "managed-kubeflow",
"calculatedCost": 0.94,
"currency": "EUR",
"status": "Recorded"
}
Example Request:
curl -X POST "https://portal.api.caip.bmw.cloud/v1/spaces/space-12345/costs" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json" \
-d '{
"day": "2025-08-20",
"service": "managed-kubeflow",
"calculatedCost": 0.94,
"currency": "EUR",
"usageDetails": "{\"cluster\":\"mcaip-train\",\"namespace\":\"mkf-usecase-a\",\"origin\":\"kubecost\"}",
"description": "daily MKF infra share"
}'
Response Codes:
201: Cost entry created successfully401: Unauthorized - M2M token required403: Forbidden - User tokens not allowed on this endpoint404: Space not found
Space Workflow Mapping
Endpoints for retrieving space and workflow mappings.
Get All Spaces with Their Workflow Mappings
- Returns all spaces with associated Kubeflow workspace details. Requires M2M authentication.
- Endpoint:
GET /v1/spaces-with-workflows - Authentication: Required
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
clusterName | string | No | Filter to return spaces with workflows on the specified cluster |
Response:
[
{
"spaceId": "507f1f77bcf86cd799439011",
"spaceName": "My CAIP Space",
"description": "Space description",
"appId": "APP123456",
"itsmServiceOffering": "SRV789012",
"workspaces": [
{
"workspaceId": "507f1f77bcf86cd799439012",
"clusterName": "mcaip-train",
"namespaceName": "mkf-usecase-a",
"region": "emea"
}
]
}
]
Example Request:
curl -X GET "https://portal.api.caip.bmw.cloud/v1/spaces-with-workflows?clusterName=mcaip-train" \
-H "Authorization: Bearer M2M token" \
-H "Content-Type: application/json"
Response Codes:
200: List of all spaces with workflow mappings retrieved successfully401: Unauthorized - M2M authentication required500: Internal Server Error
Support
For questions, issues, or feature requests:
- Email: caip-offboard-bmw@list.bmw.com
- CAIP Portal: https://caip.bmw.cloud
External Documentation
Contact
For support, contact: paul.weber@bmw.de
License: Terms of Use