Skip to main content

Metabase Dashboard API - cURL Examples

This document contains cURL examples for all Metabase Dashboard API endpoints.

Prerequisites

  • Base URL: Replace http://localhost:4000 with your actual API URL
  • Authentication: All endpoints require Firebase authentication token
  • Token: Replace YOUR_FIREBASE_ID_TOKEN with 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"

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 description
  • orderBy (optional): Sort field (name, code, createdAt)
  • order (optional): Sort direction (asc or desc)
  • businessId (optional): Filter by business ID
  • role (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 ID
  • isActive (optional): Whether the instance is active
  • updatedBy (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

  1. Authentication: All endpoints require a valid Firebase ID token in the Authorization header
  2. Business ID: The businessId query parameter is required for embed URL endpoints
  3. Environment: The embed URL endpoint automatically uses the correct environment (staging/production) based on DEPLOY_ENV
  4. Route Priority: The route dashboard/:code/embed-url comes before dashboard/:id to handle codes properly
  5. Numeric IDs: If you pass a numeric string to the code endpoint, it will automatically route to the numeric ID endpoint
  6. Role Filtering:
    • The role query parameter filters dashboards based on role access defined in metabase_dashboard_role table
    • If role is 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 = true in the metabase_dashboard_role table are returned
  7. Dashboard Instances:
    • Each dashboard can have instances for staging and production environments
    • The metabaseDashboardId is the numeric ID from your Metabase instance
    • Update these IDs after creating dashboards in Metabase
    • The environment parameter must be either staging or production