Blog

API Dashboard Examples: JSON In, Live Widgets Out

6 min read

An API dashboard is a dashboard whose every widget is fed by an HTTP endpoint: the endpoint returns JSON, and the dashboard renders it. Below are real examples of that JSON for the widgets people use most, a KPI, a line chart, a bar chart, a table, a status light and a gauge, each exactly as dashboardbase accepts it, plus a short FastAPI endpoint that serves one. Copy any of them into the public endpoint validator to see the widget render, no account needed.

If you want the idea behind this first, one JSON endpoint away from a live dashboard explains it, and the dashboard builder guide shows where these responses go. This page is the reference.

The envelope every widget shares

Every response has the same outer shape. title and data are required; actions (links shown in the widget's menu) and alert are optional. Only what's inside data changes from widget to widget.

Two rules catch people out:

  • Chart data points are objects with a value, never bare numbers or x/y pairs.
  • Table cells are objects with a text, never bare strings, which is what lets a cell carry a link, an image or a badge.

Example 1: KPI with a trend

The everyday tile: one number, a comparison, a coloured badge.

response.json dashboardbase.com/s/your-company
{
  "title": "Total Sales",
  "actions": [
    {
      "title": "View Report",
      "type": "link",
      "url": "https://example.com/kpi-report"
    }
  ],
  "data": {
    "header": {
      "title": "5.4%",
      "subtitle": "vs last month",
      "badge": {
        "text": "-1%",
        "icon": "ArrowDown",
        "color": "Danger"
      }
    }
  }
}

The endpoint chooses the colour. A falling metric isn't always bad, so Danger versus Success is your call, not the dashboard's.

Example 2: Line chart

A time series with a headline above it. labels are the x-axis; each dataset is a series.

response.json dashboardbase.com/s/your-company
{
  "title": "Website Traffic",
  "actions": [
    {
      "title": "Analyze Traffic",
      "type": "link",
      "url": "https://example.com/traffic-analysis"
    }
  ],
  "data": {
    "header": {
      "title": "1010",
      "subtitle": "Last 7 days",
      "badge": {
        "text": "+70%",
        "icon": "ArrowUp",
        "color": "Success"
      }
    },
    "labels": [
      "Mon",
      "Tue",
      "Wed",
      "Thu",
      "Fri",
      "Sat",
      "Sun"
    ],
    "datasets": [
      {
        "data": [
          {
            "value": 100
          },
          {
            "value": 120
          },
          {
            "value": 150
          },
          {
            "value": 130
          },
          {
            "value": 160
          },
          {
            "value": 180
          },
          {
            "value": 170
          }
        ],
        "label": "Page Views"
      }
    ]
  }
}

Add a second object to datasets for a second line, such as this week against last week.

Example 3: Horizontal bar chart for a ranking

Rankings with long labels read better sideways. Set indexAxis to y:

response.json dashboardbase.com/s/your-company
{
  "title": "Top referrers",
  "data": {
    "header": {
      "title": "Top referrers",
      "subtitle": "Last 30 days"
    },
    "labels": [
      "Google",
      "Direct",
      "Twitter / X",
      "Newsletter",
      "Product Hunt"
    ],
    "datasets": [
      {
        "data": [
          {
            "value": 4200
          },
          {
            "value": 3100
          },
          {
            "value": 1800
          },
          {
            "value": 1200
          },
          {
            "value": 640
          }
        ],
        "label": "Visits"
      }
    ],
    "indexAxis": "y"
  }
}

Example 4: Table with links and badges

Columns carry a text and a width in percent; every cell is an object.

response.json dashboardbase.com/s/your-company
{
  "title": "Top customers",
  "actions": [
    {
      "title": "View All",
      "type": "link",
      "url": "https://example.com/customers"
    }
  ],
  "data": {
    "columns": [
      {
        "text": "Customer",
        "width": 45
      },
      {
        "text": "Plan",
        "width": 30
      },
      {
        "text": "MRR",
        "width": 25
      }
    ],
    "rows": [
      [
        {
          "text": "Acme Corp",
          "link": "https://example.com/customers/acme"
        },
        {
          "text": "Enterprise",
          "badge": {
            "text": "Enterprise",
            "color": "Dark"
          }
        },
        {
          "text": "$1,200"
        }
      ],
      [
        {
          "text": "Globex",
          "link": "https://example.com/customers/globex"
        },
        {
          "text": "Pro",
          "badge": {
            "text": "Pro",
            "color": "Success"
          }
        },
        {
          "text": "$480"
        }
      ]
    ]
  }
}

On a phone, tapping a row opens a detail view with every column laid out as a list, so a wide table stays usable.

Example 5: Status light with an alert

For anything that's up or down. When the endpoint includes an active alert, the widget shows a pulsing dot and opted-in members are notified by email, push or Slack.

response.json dashboardbase.com/s/your-company
{
  "title": "Payments API",
  "actions": [
    {
      "title": "Open Incident",
      "type": "link",
      "url": "https://example.com/incident"
    }
  ],
  "data": {
    "header": {
      "title": "Down",
      "subtitle": "All checks failing"
    },
    "status": "Error"
  },
  "alert": {
    "active": true,
    "level": "critical",
    "message": "Payments API has been down for 8 minutes"
  }
}

Example 6: Gauge

A single value against a maximum, such as uptime, quota or server load:

response.json dashboardbase.com/s/your-company
{
  "title": "Uptime",
  "actions": [
    {
      "title": "View Status",
      "type": "link",
      "url": "https://example.com/status"
    }
  ],
  "data": {
    "header": {
      "title": "99.9%",
      "subtitle": "Last 30 days"
    },
    "value": {
      "value": 99.9,
      "postfix": "%"
    },
    "maxValue": 100
  }
}

Serving one: a FastAPI endpoint

Here's the line chart from Example 2 served from Python, protected by the workspace secret that dashboardbase sends on every request:

import os
import secrets

from fastapi import Depends, FastAPI, Header, HTTPException

app = FastAPI()

# Fail at import rather than serving data unprotected.
ENDPOINT_SECRET = os.environ["DASHBOARDBASE_ENDPOINT_SECRET"]


def verify(x_dashboardbase_secret: str = Header(default="")) -> None:
    if not secrets.compare_digest(x_dashboardbase_secret, ENDPOINT_SECRET):
        raise HTTPException(status_code=401, detail="unauthorized")


@app.get("/dashboard/traffic", dependencies=[Depends(verify)])
def traffic() -> dict:
    days, views = page_views_last_7_days()  # your own query
    change = round((views[-1] - views[0]) / views[0] * 100) if views[0] else 0
    return {
        "title": "Website Traffic",
        "actions": [
            {"title": "Analyze Traffic", "type": "link", "url": "https://example.com/traffic-analysis"}
        ],
        "data": {
            "header": {
                "title": str(sum(views)),
                "subtitle": "Last 7 days",
                "badge": {
                    "text": f"{'+' if change >= 0 else ''}{change}%",
                    "icon": "ArrowUp" if change >= 0 else "ArrowDown",
                    "color": "Success" if change >= 0 else "Danger",
                },
            },
            "labels": days,
            "datasets": [{"data": [{"value": v} for v in views], "label": "Page Views"}],
        },
    }

The same pattern works in any language; there are versions for Node.js, Go, PHP and more. When you test the datasource in dashboardbase, it also makes one request with every credential stripped and tells you whether your endpoint really refused it.

More widget types

For a full worked board, see the internal dashboard or SaaS metrics dashboard guides. Beyond these six, dashboardbase renders pie and donut charts, countdowns, a GitHub-style contributions grid, progress lists, clocks, text blocks and images, all with the same envelope. The full set, with every variant, is in the documentation, and you can see them running on the live demo.

Generating endpoints instead of writing them

Two ways to skip the typing:

  • The Skill. The free dashboardbase Skill teaches Claude Code, Cursor and other agents the whole contract, so "add a top-referrers bar chart endpoint" comes back correctly shaped.
  • In-app prompts. The editor generates a copy-pasteable prompt, per widget or for a whole dashboard, for any AI tool you already use. Nothing runs on our side; the prompt is a draft you review.

FAQ

What is an API dashboard? A dashboard where each widget reads from an HTTP endpoint that returns JSON, instead of from a database connection or a pre-built connector.

What JSON format does a dashboard API need? For dashboardbase: an object with title and data, optional actions and alert, and widget-specific fields inside data, as in the examples above.

Can I test the JSON without an account? Yes. The endpoint validator renders a pasted response as the real widget, or names the field that's wrong.

Do I need a frontend? No. The endpoint returns data; dashboardbase renders it on the web, on TVs and in native iOS and Android apps.

Your first dashboard in ten minutes.

Return JSON from an endpoint you already own. We handle the charts, hosting, sharing and the mobile app — free for 14 days.