The Widget Layout Backend provides a RESTful API for managing dashboard templates and widget configurations. This API enables users to create, read, update, and delete personalized dashboard layouts, as well as manage base templates and widget mappings.
Base URL: /api/widget-layout/v1
All endpoints (except /widget-mapping) require a valid x-rh-identity header containing user identity information. For local development and testing, use the identity header generator:
make generate-identityFor detailed instructions on generating and using identity headers, see docs/DEVELOPMENT_IDENTITY_HEADER.md.
All successful responses return the requested data with appropriate HTTP status codes (200, 201, 204).
List endpoints return data in a consistent format with metadata:
{
"data": [
/* Array of items */
],
"meta": {
"count": 2
}
}Endpoints using list format:
GET /- Dashboard templates listGET /base-templates- Base templates list
Note: The GET /widget-mapping endpoint uses a different format with a data object containing key-value mappings instead of an array.
{
"errors": [
{
"code": 404,
"message": "Dashboard template not found"
}
]
}Dashboard templates are user-specific widget layouts that define how widgets are arranged on a dashboard across different screen sizes (sm, md, lg, xl).
Get all dashboard templates for the authenticated user.
Query Parameters:
dashboardType(optional): Filter templates by dashboard type/base template name
Request:
# Get all templates
curl -X GET \
'http://localhost:8080/api/widget-layout/v1/' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'
# Filter by dashboard type
curl -X GET \
'http://localhost:8080/api/widget-layout/v1/?dashboardType=default-dashboard' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"data": [
{
"id": 1,
"userId": "user-123",
"createdAt": "2024-01-01T12:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z",
"templateConfig": {
"sm": [
{
"w": 2,
"h": 2,
"x": 0,
"y": 0,
"i": "widget1",
"static": false,
"maxH": 4,
"minH": 1
}
],
"md": [...],
"lg": [...],
"xl": [...]
},
"templateBase": {
"name": "custom-dashboard-template",
"displayName": "My Custom Dashboard"
},
"default": true
}
],
"meta": {
"count": 1
}
}Auto-Creation Behavior:
When filtering by dashboardType, if the user has no templates of that type but a matching base template exists, the API will automatically create and return a new template for the user with a 404 status code.
Error Responses:
404- No templates found (may include auto-created template in response body)500- Internal server error
Get a specific dashboard template by ID.
Request:
curl -X GET \
'http://localhost:8080/api/widget-layout/v1/1' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"id": 1,
"userId": "user-123",
"createdAt": "2024-01-01T12:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z",
"templateConfig": {
"sm": [
{
"w": 2,
"h": 2,
"x": 0,
"y": 0,
"i": "widget1",
"static": false,
"maxH": 4,
"minH": 1
}
],
"md": [...],
"lg": [...],
"xl": [...]
},
"templateBase": {
"name": "custom-dashboard-template",
"displayName": "My Custom Dashboard"
},
"default": false
}Error Responses:
403- Unauthorized access (template belongs to different user)404- Dashboard template not found500- Internal server error
Update a specific dashboard template.
Request:
curl -X PATCH \
'http://localhost:8080/api/widget-layout/v1/1' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...' \
-H 'Content-Type: application/json' \
-d '{
"templateConfig": {
"sm": [
{
"w": 3,
"h": 2,
"x": 0,
"y": 0,
"i": "widget1",
"static": false,
"maxH": 4,
"minH": 1
}
],
"md": [...],
"lg": [...],
"xl": [...]
}
}'Response (200 OK):
{
"id": 1,
"userId": "user-123",
"createdAt": "2024-01-01T12:00:00Z",
"updatedAt": "2024-01-01T12:30:00Z",
"templateConfig": {
"sm": [
{
"w": 3,
"h": 2,
"x": 0,
"y": 0,
"i": "widget1",
"static": false,
"maxH": 4,
"minH": 1
}
],
"md": [...],
"lg": [...],
"xl": [...]
},
"templateBase": {
"name": "custom-dashboard-template",
"displayName": "My Custom Dashboard"
},
"default": false
}Error Responses:
400- Bad request (invalid template data)403- Unauthorized access (template belongs to different user)404- Dashboard template not found500- Internal server error
Delete a specific dashboard template.
Request:
curl -X DELETE \
'http://localhost:8080/api/widget-layout/v1/1' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (204 No Content):
(Empty response body)
Error Responses:
403- Unauthorized access (template belongs to different user)404- Dashboard template not found500- Internal server error
Create a copy of a specific dashboard template.
Request:
curl -X POST \
'http://localhost:8080/api/widget-layout/v1/1/copy' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"id": 2,
"userId": "user-123",
"createdAt": "2024-01-01T13:00:00Z",
"updatedAt": "2024-01-01T13:00:00Z",
"templateConfig": {
"sm": [...],
"md": [...],
"lg": [...],
"xl": [...]
},
"templateBase": {
"name": "custom-dashboard-template-copy",
"displayName": "Copy of My Custom Dashboard"
},
"default": false
}Error Responses:
404- Dashboard template not found500- Internal server error
Set a specific dashboard template as the default.
Request:
curl -X POST \
'http://localhost:8080/api/widget-layout/v1/1/default' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"id": 1,
"userId": "user-123",
"createdAt": "2024-01-01T12:00:00Z",
"updatedAt": "2024-01-01T13:30:00Z",
"templateConfig": {
"sm": [...],
"md": [...],
"lg": [...],
"xl": [...]
},
"templateBase": {
"name": "custom-dashboard-template",
"displayName": "My Custom Dashboard"
},
"default": true
}Error Responses:
403- Unauthorized access (template belongs to different user)404- Dashboard template not found500- Internal server error
Reset a specific dashboard template to its default state.
Request:
curl -X POST \
'http://localhost:8080/api/widget-layout/v1/1/reset' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"id": 1,
"userId": "user-123",
"createdAt": "2024-01-01T12:00:00Z",
"updatedAt": "2024-01-01T14:00:00Z",
"templateConfig": {
"sm": [...],
"md": [...],
"lg": [...],
"xl": [...]
},
"templateBase": {
"name": "custom-dashboard-template",
"displayName": "My Custom Dashboard"
},
"default": false
}Error Responses:
403- Unauthorized access (template belongs to different user)404- Dashboard template not found500- Internal server error
Base templates are predefined widget layouts that serve as starting points for creating custom dashboard templates.
Get all available base widget dashboard templates.
Request:
curl -X GET \
'http://localhost:8080/api/widget-layout/v1/base-templates' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"data": [
{
"name": "default-dashboard",
"displayName": "Default Dashboard",
"templateConfig": {
"sm": [
{
"w": 2,
"h": 2,
"x": 0,
"y": 0,
"i": "insights-dashboard-widget",
"static": false,
"maxH": 4,
"minH": 1
}
],
"md": [...],
"lg": [...],
"xl": [...]
}
}
],
"meta": {
"count": 1
}
}Error Responses:
500- Internal server error
Get a specific base widget dashboard template by name.
Request:
curl -X GET \
'http://localhost:8080/api/widget-layout/v1/base-templates/default-dashboard' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"name": "default-dashboard",
"displayName": "Default Dashboard",
"templateConfig": {
"sm": [
{
"w": 2,
"h": 2,
"x": 0,
"y": 0,
"i": "insights-dashboard-widget",
"static": false,
"maxH": 4,
"minH": 1
}
],
"md": [...],
"lg": [...],
"xl": [...]
}
}Error Responses:
404- Base template not found500- Internal server error
Create a user-specific copy of a base template.
Request:
curl -X GET \
'http://localhost:8080/api/widget-layout/v1/base-templates/default-dashboard/fork' \
-H 'x-rh-identity: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'Response (200 OK):
{
"id": 3,
"userId": "user-123",
"createdAt": "2024-01-01T15:00:00Z",
"updatedAt": "2024-01-01T15:00:00Z",
"templateConfig": {
"sm": [...],
"md": [...],
"lg": [...],
"xl": [...]
},
"templateBase": {
"name": "default-dashboard",
"displayName": "Default Dashboard"
},
"default": false
}Error Responses:
404- Base template not found500- Internal server error
Widget mapping provides metadata about available widgets including their configurations, dimensions, and module federation information.
📝 Note: The widget mapping endpoint returns a different format than other list endpoints. It provides a key-value mapping rather than an array with metadata.
Get the mapping of all available widgets.
Request:
curl -X GET \
'http://localhost:8080/api/widget-layout/v1/widget-mapping'Response (200 OK):
{
"data": {
"insights@dashboard-widget": {
"scope": "insights",
"module": "dashboard-widget",
"importName": "DashboardWidget",
"featureFlag": "",
"config": {
"title": "Dashboard Overview",
"icon": "dashboard-icon",
"headerLink": {
"name": "View Dashboard",
"href": "/dashboard"
},
"permissions": ["dashboard:read"]
},
"defaults": {
"w": 2,
"h": 3,
"maxH": 6,
"minH": 1
}
},
"monitoring@alerts-widget": {
"scope": "monitoring",
"module": "alerts-widget",
"importName": "AlertsWidget",
"featureFlag": "alerts.enabled",
"config": {
"title": "Alert Status",
"icon": "alert-icon",
"headerLink": {
"name": "View Alerts",
"href": "/alerts"
},
"permissions": ["alerts:read"]
},
"defaults": {
"w": 1,
"h": 2,
"maxH": 4,
"minH": 1
}
}
}
}Error Responses:
500- Internal server error
📋 Configuration Details: For information about how widget mappings and base templates are configured, see docs/CONFIGURATION.md. This includes JSON structure examples, environment variable setup, and the important cx/cy coordinate system details.
Represents a single widget in a dashboard layout.
{
"w": 2, // Width (1-4)
"h": 2, // Height (minimum 1)
"x": 0, // X position (0-3)
"y": 0, // Y position (minimum 0)
"i": "widget-id", // Widget type identifier
"static": false, // Whether widget is locked
"maxH": 4, // Maximum height
"minH": 1 // Minimum height
}Defines widget layouts for different screen sizes.
{
"sm": [/* WidgetItem array for small screens */],
"md": [/* WidgetItem array for medium screens */],
"lg": [/* WidgetItem array for large screens */],
"xl": [/* WidgetItem array for extra large screens */]
}Complete dashboard template with metadata and configuration.
{
"id": 1,
"userId": "user-123",
"createdAt": "2024-01-01T12:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z",
"deletedAt": null,
"templateConfig": {/* DashboardTemplateConfig */},
"templateBase": {
"name": "dashboard-template-v1",
"displayName": "Template Display Name"
},
"default": false
}Base template definition without user-specific metadata.
{
"name": "insights-dashboard-template",
"displayName": "Template Display Name",
"templateConfig": {/* DashboardTemplateConfig */}
}Metadata for widget module federation and configuration.
{
"scope": "insights",
"module": "dashboard-widget",
"importName": "DashboardWidget",
"featureFlag": "feature.enabled",
"config": {
"title": "Widget Title",
"icon": "widget-icon",
"headerLink": {
"name": "Link Name",
"href": "/link-url"
},
"permissions": ["permission:read"]
},
"defaults": {
"w": 2,
"h": 3,
"maxH": 6,
"minH": 1
}
}All errors follow a consistent format:
{
"errors": [
{
"code": 400,
"message": "Detailed error message"
}
]
}400- Bad Request (invalid data)403- Forbidden (unauthorized access)404- Not Found (resource doesn't exist)500- Internal Server Error
The API implements user-based authorization where:
- User Identity: Extracted from
x-rh-identityheader - Template Ownership: Users can only access their own dashboard templates
- Base Templates: Available to all authenticated users
- Widget Mapping: Available without authentication
For testing the API locally:
- Start the server:
make dev - Generate identity header:
make generate-identity - Use the provided curl examples with your generated identity header
For comprehensive testing patterns and examples, see docs/TESTING.md.
The complete OpenAPI specification is available at:
- YAML format:
/api/widget-layout/v1/openapi.yaml - JSON format:
/api/widget-layout/v1/openapi.json
- docs/TESTING.md - Testing patterns and examples
- docs/CONFIGURATION.md - Widget mapping and base template configuration
- docs/DEVELOPMENT_IDENTITY_HEADER.md - Identity header for local development
- docs/AI_AGENT_CONTEXT.md - AI-assisted development guidelines