Bentori
Bentori

Bentori Documentation

API reference, CLI guide, card schemas, and download links.

Quick Start

  1. 1. Register — Visit /register and submit your email. You will receive a namespace URL and API key.
  2. 2. Sign in — Paste your API key in the Settings (gear icon) on your dashboard to set the session cookie. Alternatively, call POST /api/:namespace/session.
  3. 3. Create cards — Use the "+" menu in the dashboard header, or the CLI / API.
  4. 4. Share — Click "Share" to create a public read-only link for any dashboard.

REST API Reference

All mutations require an API key via X-API-Key header or bentori_api_key session cookie.

Dashboards

MethodEndpointBody / Notes
GET/api/:ns/dashboardsList all dashboards
POST/api/:ns/dashboards{"name":"...","bg_color":"midnight","refresh_interval":0}
GET/api/:ns/dashboards/:idGet dashboard
PUT/api/:ns/dashboards/:id{"name","bg_color","refresh_interval"} (any subset)
DEL/api/:ns/dashboards/:idDelete dashboard (cards are detached, not deleted)
POST/api/:ns/dashboards/:id/duplicate{"name":"..."} (optional)
POST/api/:ns/dashboards/:id/publicCreate public share token
DEL/api/:ns/dashboards/:id/publicRevoke public token

Cards

MethodEndpointBody / Notes
GET/api/:ns/cardsList all cards in namespace
POST/api/:ns/cards{"type":"metric","title":"...","data_json":{},"refresh_interval":60,"dashboard_id":1,"size":"1x1"}
GET/api/:ns/cards/:idGet card
PUT/api/:ns/cards/:id{"title","data_json","refresh_interval"} (type is immutable)
DEL/api/:ns/cards/:idDelete card permanently
GET/api/:ns/card-typesList available types + default data_json

Dashboard-Cards (junction)

MethodEndpointBody / Notes
GET/api/:ns/dashboards/:id/cardsList attached cards
POST/api/:ns/dashboards/:id/cards/:card_id{"position":0,"size":"1x1"} — attach
PUT/api/:ns/dashboards/:id/cards/:card_id{"position","size"} — move/resize
DEL/api/:ns/dashboards/:id/cards/:card_idDetach (card still exists)
PUT/api/:ns/dashboards/:id/reorder{"cards":[{"card_id","position","size"}]} — bulk

Account & Session

MethodEndpointNotes
POST/api/:ns/session{"api_key":"..."} — sets 1-year HttpOnly cookie
GET/api/:ns/accountAccount metadata (requires auth)
POST/api/:ns/account/regenerate-api-keyNew key + updates cookie
PUT/api/:ns/account/roleAdmin only: {"namespace":"...","role":"admin|free|membership|betatester"}

CLI Tool (bentori-cli)

Global flags: -ns, -key, -base-url. All global flags must come before the command.

Dashboards

# Create a dashboard
bentori-cli dashboard create -name "Production" -bg-color emerald -refresh 0

# Update (any subset of fields)
bentori-cli dashboard update -id 1 -name "Prod" -bg-color emerald -refresh 300

# Duplicate
bentori-cli dashboard duplicate -id 1 -name "Production Copy"

# List / Delete
bentori-cli dashboard list
bentori-cli dashboard delete -id 2

Cards

# Create a standalone card (default refresh: 60s)
bentori-cli card create -type metric -title "CPU" -data '{"value":42}' -refresh 30

# Update title, data, and/or refresh
bentori-cli card update -id 5 -title "Updated" -data '{"value":55}' -refresh 120

# Push data (auto-fetches title)
bentori-cli card push -id 5 -data '{"value":60}' -refresh 120

# Delete / List
bentori-cli card delete -id 5
bentori-cli card list

Attach & Move

# Attach existing card to dashboard
bentori-cli card attach -dashboard-id 1 -card-id 5 -position 0 -size 2x2

# Detach / Move
bentori-cli card detach -dashboard-id 1 -card-id 5
bentori-cli card move -dashboard-id 1 -card-id 5 -position 1 -size 1x2

# Create + attach in one step
bentori-cli card add -type metric -title "CPU" -data '{"value":42}' \
  -dashboard-id 1 -position 0 -size 2x2 -refresh 30

Populate

# Create a dashboard with one card of every type
bentori-cli populate
bentori-cli populate -name "Demo Dashboard"

Card Layouts

Bentori uses 16 general layout templates. The type field selects the layout; data_json provides the content. Card type is immutable after creation.

TypeDescriptionRequired fields
metricBig number + badge + sparklinelabel, value
line-chartChart.js line chart (1-2 datasets)labels, datasets
bar-listHorizontal bars with labelsitems[]: {name, pct, color}
progressProgress bar + fractionlabel
statusColored status indicatorslabel, items[]: {name, value, color}
event-listEvent rows with color dot + timelabel, items[]: {color, text, time}
calendarDate-block event listevents[]: {month_short, day, title, time}
quoteQuote + authortext, author
weatherGradient bg + temp/conditiontemp, condition, high, low
mapInteractive map with markerslat, lng, markers[]: {lat, lng, label, color}
streamHLS live video streamurl, poster, muted, autoplay, controls
embedYouTube, Vimeo, video file, or generic iframe embedurl, autoplay, muted, controls
clockClock with timezone + optional secondstimezone, show_seconds, label
admin-metricKPI big number (inline CSS)value, label
admin-chartKPI sparkline bars (inline CSS)items, label
admin-bar-listKPI horizontal bars (inline CSS)items[]: {name, value}, total

Call GET /api/:namespace/card-types to fetch default data_json for every type. Use it to pre-fill the Data JSON field when creating cards.

Download Bentori

Pre-built server binaries.

FAQ & Troubleshooting

My card shows "unknown card type"

You are using an old content-specific type name (e.g. cpu, revenue). Bentori now uses 16 general layouts. Restart the server to trigger the automatic card migration, or manually update the card type via the API.

How do I share a dashboard publicly?

Open the dashboard, click the "Share" button in the header. A read-only token is created and the URL is copied to your clipboard. Anyone with the link can view the dashboard without signing in.

What is the API key for?

The API key is your write token. All mutations (create, update, delete) require it, either as an X-API-Key header or via the bentori_api_key HttpOnly session cookie. The cookie is set automatically when you register.

How do auto-refresh intervals work?

Cards and dashboards have a refresh_interval field (seconds). When set to a value > 0, a <meta http-equiv="refresh"> tag is injected into the HTML. Cards default to 60s; dashboards default to 0 (disabled). Minimum is 15s.

Can I run Bentori behind a reverse proxy?

Yes. Set BENTORI_BASE_URL (or -base-url) to the public-facing URL. All internal paths use relative URLs so they work behind proxies. Use any reverse proxy (nginx, Caddy, Traefik) for TLS termination.