Metabase Dashboard API - cURL Examples
This document contains cURL examples for all Metabase Dashboard API endpoints.
Prerequisites
- Base URL: Replace
http://localhost:4000with your actual API URL - Authentication: All endpoints require Firebase authentication token
- Token: Replace
YOUR_FIREBASE_ID_TOKENwith your actual Firebase ID token
Environment Variables
# Set these before running the commands
export API_URL="http://localhost:4000"
export FIREBASE_TOKEN="YOUR_FIREBASE_ID_TOKEN"
export BUSINESS_ID="your-business-uuid"
export DASHBOARD_ID="your-dashboard-uuid"
export DASHBOARD_CODE="sales-dashboard"
1. Get Embed URL by Dashboard Code (Recommended)
Endpoint: GET /reports/dashboard/:code/embed-url
This is the main endpoint that:
- Looks up dashboard by code
- Gets environment-specific Metabase ID
- Checks business and role access
- Generates embed URL
# Get embed URL for sales-dashboard
curl -X GET \
"${API_URL}/reports/dashboard/sales-dashboard/embed-url?businessId=${BUSINESS_ID}" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response:
{
"embedUrl": "https://metabase.example.com/embed/dashboard/eyJhbGc..."
}
2. Get Embed URL by Numeric Metabase Dashboard ID
Endpoint: GET /reports/dashboard/:dashboardId/embed-url
Legacy endpoint for direct Metabase dashboard IDs (numeric).
# Get embed URL for Metabase dashboard ID 3
curl -X GET \
"${API_URL}/reports/dashboard/3/embed-url?businessId=${BUSINESS_ID}" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response:
{
"embedUrl": "https://metabase.example.com/embed/dashboard/eyJhbGc..."
}
3. Create Dashboard
Endpoint: POST /reports/dashboard
curl -X POST \
"${API_URL}/reports/dashboard" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"code": "inventory-dashboard",
"name": "Inventory Dashboard",
"description": "Dashboard showing inventory metrics and stock levels",
"icon": "inventory_2",
"isActive": true,
"businessId": null,
"createdBy": "user-uuid-here"
}'
Response:
{
"id": "uuid-here",
"code": "inventory-dashboard",
"name": "Inventory Dashboard",
"description": "Dashboard showing inventory metrics and stock levels",
"icon": "inventory_2",
"isActive": true,
"businessId": null,
"createdAt": "2025-11-25T15:00:00.000Z",
"createdBy": "user-uuid-here",
"updatedAt": null,
"updatedBy": null
}
4. List All Dashboards (with Pagination)
Endpoint: GET /reports/dashboard
# Get all dashboards
curl -X GET \
"${API_URL}/reports/dashboard?page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
# Get dashboards with business filter
curl -X GET \
"${API_URL}/reports/dashboard?businessId=${BUSINESS_ID}&page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
# Get dashboards with search
curl -X GET \
"${API_URL}/reports/dashboard?search=sales&page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
# Get dashboards with sorting
curl -X GET \
"${API_URL}/reports/dashboard?orderBy=name&order=asc&page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
# Get dashboards filtered by role (explicit role parameter)
curl -X GET \
"${API_URL}/reports/dashboard?role=admin&page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
# Get dashboards with role and business filter
curl -X GET \
"${API_URL}/reports/dashboard?role=admin&businessId=${BUSINESS_ID}&page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Query Parameters:
page(optional): Page number (default: 1)size(optional): Items per page (default: 10, 0 = all)search(optional): Search term for name, code, or descriptionorderBy(optional): Sort field (name,code,createdAt)order(optional): Sort direction (ascordesc)businessId(optional): Filter by business IDrole(optional): Filter by user role (e.g.,admin,owner,accountant). If not provided, the role from the authenticated user's token will be used automatically. If no role is available, all active dashboards are returned.
Response:
{
"count": 5,
"results": [
{
"id": "uuid-here",
"code": "sales-dashboard",
"name": "Sales Dashboard",
"description": "Dashboard showing sales metrics and analytics",
"icon": "dashboard",
"isActive": true,
"businessId": null,
"createdAt": "2025-11-25T15:00:00.000Z",
"createdBy": "user-uuid-here",
"updatedAt": null,
"updatedBy": null
}
],
"page": 1,
"size": 10,
"totalPages": 1
}
5. Get Dashboard by Code
Endpoint: GET /reports/dashboard/code/:code
# Get dashboard by code
curl -X GET \
"${API_URL}/reports/dashboard/code/sales-dashboard" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response:
{
"id": "uuid-here",
"code": "sales-dashboard",
"name": "Sales Dashboard",
"description": "Dashboard showing sales metrics and analytics",
"icon": "dashboard",
"isActive": true,
"businessId": null,
"createdAt": "2025-11-25T15:00:00.000Z",
"createdBy": "user-uuid-here",
"updatedAt": null,
"updatedBy": null
}
6. Get Dashboard by UUID
Endpoint: GET /reports/dashboard/:id
# Get dashboard by UUID
curl -X GET \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response:
{
"id": "uuid-here",
"code": "sales-dashboard",
"name": "Sales Dashboard",
"description": "Dashboard showing sales metrics and analytics",
"icon": "dashboard",
"isActive": true,
"businessId": null,
"createdAt": "2025-11-25T15:00:00.000Z",
"createdBy": "user-uuid-here",
"updatedAt": null,
"updatedBy": null
}
7. Update Dashboard
Endpoint: PATCH /reports/dashboard/:id
# Update dashboard
curl -X PATCH \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Sales Dashboard",
"description": "Updated description",
"icon": "bar_chart",
"isActive": true,
"updatedBy": "user-uuid-here"
}'
Note: All fields in the body are optional. Only include fields you want to update.
Response:
{
"id": "uuid-here",
"code": "sales-dashboard",
"name": "Updated Sales Dashboard",
"description": "Updated description",
"icon": "bar_chart",
"isActive": true,
"businessId": null,
"createdAt": "2025-11-25T15:00:00.000Z",
"createdBy": "user-uuid-here",
"updatedAt": "2025-11-25T16:00:00.000Z",
"updatedBy": "user-uuid-here"
}
8. Delete Dashboard
Endpoint: DELETE /reports/dashboard/:id
# Delete dashboard
curl -X DELETE \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response: 204 No Content (on success)
Complete Example Script
Save this as test-metabase-api.sh:
#!/bin/bash
# Configuration
API_URL="${API_URL:-http://localhost:4000}"
FIREBASE_TOKEN="${FIREBASE_TOKEN:-YOUR_FIREBASE_ID_TOKEN}"
BUSINESS_ID="${BUSINESS_ID:-your-business-uuid}"
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}=== Testing Metabase Dashboard API ===${NC}\n"
# 1. Get embed URL by code
echo -e "${GREEN}1. Get embed URL by code (sales-dashboard)${NC}"
curl -X GET \
"${API_URL}/reports/dashboard/sales-dashboard/embed-url?businessId=${BUSINESS_ID}" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-w "\nHTTP Status: %{http_code}\n\n"
# 2. List all dashboards
echo -e "${GREEN}2. List all dashboards${NC}"
curl -X GET \
"${API_URL}/reports/dashboard?page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-w "\nHTTP Status: %{http_code}\n\n"
# 2b. List dashboards with role filter
echo -e "${GREEN}2b. List dashboards with role filter${NC}"
curl -X GET \
"${API_URL}/reports/dashboard?role=admin&page=1&size=10" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-w "\nHTTP Status: %{http_code}\n\n"
# 3. Get dashboard by code
echo -e "${GREEN}3. Get dashboard by code${NC}"
curl -X GET \
"${API_URL}/reports/dashboard/code/sales-dashboard" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-w "\nHTTP Status: %{http_code}\n\n"
# 4. Create a new dashboard
echo -e "${GREEN}4. Create new dashboard${NC}"
curl -X POST \
"${API_URL}/reports/dashboard" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"code": "test-dashboard",
"name": "Test Dashboard",
"description": "Test dashboard for API testing",
"icon": "dashboard",
"isActive": true,
"createdBy": "user-uuid-here"
}' \
-w "\nHTTP Status: %{http_code}\n\n"
Make it executable:
chmod +x test-metabase-api.sh
./test-metabase-api.sh
Error Responses
All endpoints may return the following error responses:
400 Bad Request
{
"statusCode": 400,
"message": "businessId is required",
"error": "Bad Request"
}
401 Unauthorized
{
"statusCode": 401,
"message": "Unauthorized"
}
404 Not Found
{
"statusCode": 404,
"message": "Dashboard with code sales-dashboard not found",
"error": "Not Found"
}
9. Dashboard Instance Management (CRUD)
9.1. Get All Dashboard Instances
Endpoint: GET /reports/dashboard/:dashboardId/instances
Returns all environment-specific instances (staging + production) for a dashboard.
curl -X GET \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instances" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response:
[
{
"id": "uuid-here",
"dashboardId": "3d0d5b03-2f5a-4773-a32a-be5ac0b69e19",
"environment": "staging",
"metabaseDashboardId": 3,
"isActive": true,
"createdAt": "2025-11-25T15:00:00.000Z",
"updatedAt": null,
"updatedBy": null
},
{
"id": "uuid-here",
"dashboardId": "3d0d5b03-2f5a-4773-a32a-be5ac0b69e19",
"environment": "production",
"metabaseDashboardId": 5,
"isActive": true,
"createdAt": "2025-11-25T15:00:00.000Z",
"updatedAt": null,
"updatedBy": null
}
]
9.2. Get Single Dashboard Instance
Endpoint: GET /reports/dashboard/:dashboardId/instance/:environment
Returns a specific instance by environment.
# Get staging instance
curl -X GET \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/staging" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
# Get production instance
curl -X GET \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/production" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response:
{
"id": "uuid-here",
"dashboardId": "3d0d5b03-2f5a-4773-a32a-be5ac0b69e19",
"environment": "staging",
"metabaseDashboardId": 3,
"isActive": true,
"createdAt": "2025-11-25T15:00:00.000Z",
"updatedAt": null,
"updatedBy": null
}
9.3. Create Dashboard Instance
Endpoint: POST /reports/dashboard/:dashboardId/instance/:environment
Creates a new environment-specific instance for a dashboard.
# Create staging instance
curl -X POST \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/staging" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"dashboardId": "3d0d5b03-2f5a-4773-a32a-be5ac0b69e19",
"environment": "staging",
"metabaseDashboardId": 3,
"isActive": true,
"updatedBy": "user-uuid-here"
}'
# Create production instance
curl -X POST \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/production" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"dashboardId": "3d0d5b03-2f5a-4773-a32a-be5ac0b69e19",
"environment": "production",
"metabaseDashboardId": 5,
"isActive": true,
"updatedBy": "user-uuid-here"
}'
Note: The dashboardId and environment in the body must match the URL parameters.
Response:
{
"id": "uuid-here",
"dashboardId": "3d0d5b03-2f5a-4773-a32a-be5ac0b69e19",
"environment": "staging",
"metabaseDashboardId": 3,
"isActive": true,
"createdAt": "2025-11-25T15:00:00.000Z",
"updatedAt": null,
"updatedBy": "user-uuid-here"
}
9.4. Update Dashboard Instance
Endpoint: PATCH /reports/dashboard/:dashboardId/instance/:environment
Updates the Metabase dashboard ID or active status for a specific environment.
# Update staging instance
curl -X PATCH \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/staging" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"metabaseDashboardId": 7,
"isActive": true,
"updatedBy": "user-uuid-here"
}'
# Update production instance
curl -X PATCH \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/production" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"metabaseDashboardId": 10,
"isActive": true,
"updatedBy": "user-uuid-here"
}'
Body Parameters:
metabaseDashboardId(required): The numeric Metabase dashboard IDisActive(optional): Whether the instance is activeupdatedBy(required): UUID of the user making the update
Response:
{
"id": "uuid-here",
"dashboardId": "3d0d5b03-2f5a-4773-a32a-be5ac0b69e19",
"environment": "staging",
"metabaseDashboardId": 7,
"isActive": true,
"createdAt": "2025-11-25T15:00:00.000Z",
"updatedAt": "2025-11-25T16:00:00.000Z",
"updatedBy": "user-uuid-here"
}
9.5. Delete Dashboard Instance
Endpoint: DELETE /reports/dashboard/:dashboardId/instance/:environment
Deletes a specific environment instance.
# Delete staging instance
curl -X DELETE \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/staging" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
# Delete production instance
curl -X DELETE \
"${API_URL}/reports/dashboard/${DASHBOARD_ID}/instance/production" \
-H "Authorization: Bearer ${FIREBASE_TOKEN}" \
-H "Content-Type: application/json"
Response: Returns the deleted instance object
Notes
- Authentication: All endpoints require a valid Firebase ID token in the
Authorizationheader - Business ID: The
businessIdquery parameter is required for embed URL endpoints - Environment: The embed URL endpoint automatically uses the correct environment (staging/production) based on
DEPLOY_ENV - Route Priority: The route
dashboard/:code/embed-urlcomes beforedashboard/:idto handle codes properly - Numeric IDs: If you pass a numeric string to the code endpoint, it will automatically route to the numeric ID endpoint
- Role Filtering:
- The
rolequery parameter filters dashboards based on role access defined inmetabase_dashboard_roletable - If
roleis not provided, the system automatically uses the role from the authenticated user's Firebase token (req.firebaseUser?.role) - If no role is available, all active dashboards are returned
- Only dashboards where the role has
isAllowed = truein themetabase_dashboard_roletable are returned
- The
- Dashboard Instances:
- Each dashboard can have instances for
stagingandproductionenvironments - The
metabaseDashboardIdis the numeric ID from your Metabase instance - Update these IDs after creating dashboards in Metabase
- The
environmentparameter must be eitherstagingorproduction
- Each dashboard can have instances for