Skip to content
Dashboard Gallery
Get Support

Public HTTP API

The gallery’s own pages are built on a public, unauthenticated JSON API. There is no key to obtain and no sign-in, and every endpoint here is subject to the limits in Limits and quotas.

Base URL: https://dashboards.lanpulse.com

EndpointMethodWhat it does
/api/dashboardsGETList published dashboards, optionally filtered
/api/dashboards/{slug}GETOne published dashboard
/api/facetsGETThe category taxonomy, with published counts
/api/chatPOSTAsk a plain-language question
/api/requestsPOSTSubmit a dashboard request
/api/requests/similarPOSTThe duplicate check
/api/requests/clarifyPOSTOne clarifying question about a draft
/api/dashboards/{slug}/viewPOSTThe view beacon
/d/{slug}/download/{platform}GETThe export bundle
/assets/{id}/{rev}/{file}GETImages and stored bundles

Only published dashboards are reachable through any of them. The published check is written into the SQL of every query rather than applied by whatever calls it.

Lists published dashboards, newest publication first.

ParameterTypeDefaultNotes
facetstring, repeatableA category id. Repeat it to select several; values are ORed within a kind and ANDed across kinds
limitnumber60Capped at 100
offsetnumber0Negative values are treated as 0
GET /api/dashboards?facet=r-network-engineer&facet=d-switching&limit=20

Returns { "dashboards": [ … ] }. Each entry is the same shape everywhere it appears in this API:

FieldTypeNotes
slugstringThe permalink segment — /d/{slug}
titlestring
summarystring | null
descriptionstring | null
imagestringPath to the full redacted screenshot
thumbstringPath to the thumbnail
downloadstringThe canonical RUCKUS One bundle path
downloadsarrayOne entry per platform — { id, label, available, note?, href }, with href null when unavailable
image_w, image_hnumber | nullPixel dimensions of the full image
chart_countnumber | nullCharts read out of the bundle
viz_typesstring[]Chart types used
datasetsstring[]Internal dataset names — the identifiers stay server-side
facetsarray{ kind, label, slug } per category
published_atnumber | nullEpoch milliseconds

One dashboard, in the shape above, as { "dashboard": { … } }. A slug that is not published returns 404 with { "error": "not found" }.

The whole category taxonomy, plus the configuration the gallery’s page needs before it paints.

{
"kinds": [ { "kind": "role", "label": "Role", "sort": 5, "derived": false } ],
"facets": [ { "id": "r-network-engineer", "kind": "role", "label": "Network engineer", "slug": "network-engineer", "count": 10 } ],
"suggestions": [ "…" ],
"examples": [ "…" ],
"demos": [ { "slug": "…", "prompt": "…" } ],
"requests": { "enabled": true, "site_key": "…", "planned": 3 }
}
  • count is over published dashboards only, so a category with a count of zero has nothing public behind it.
  • derived marks the kinds read out of an export bundledataset and viz — rather than assigned by a person. The gallery collapses those groups in its rail from this flag rather than from a list of kind names in the page.
  • requests.planned is the number of requests accepted for building. It is the only public read of the request table there is.

Ask a question in plain language.

{ "message": "which dashboards suit a help desk technician?" }
FieldRequiredNotes
messageYes1 to 800 characters

A history field is never read. It is not validated and rejected — there is simply no path by which a conversation could reach the model. Every request is a single fresh turn.

The default response is JSON:

{
"reply": "…",
"dashboards": [ /* the same dashboard shape as above */ ],
"filter": { "id": "d-switching", "label": "Switching", "count": 16 }
}

filter is the category the answer’s dashboards all share, with the number that carry it — or null. It is present only when every returned dashboard carries the category, since one question may search several.

Sending Accept: application/x-ndjson returns progress instead: one JSON object per line, with t set to turn, search or results as the work happens, and a final answer line carrying the same three fields. An error line replaces it on failure.

StatusMeaning
400Empty message, over 800 characters, or an unparseable body
429Rate limited, or the day’s model allowance is spent — the message says which
503The model was unavailable or the call timed out

Submit a dashboard request. This is the only public write that stores text you typed, and the only one with a bot check.

{ "body": "Roaming failures by AP…", "email": "you@example.com", "token": "…" }
FieldRequiredNotes
bodyYes10 to 1,200 characters
emailNoUp to 254 characters, shape-checked
tokenYesA Cloudflare Turnstile token, verified server-side

Returns 201 with { "ok": true, "id": "…" }. The id is all you get back — there is no endpoint that reads a request, so there is nothing to fetch it with.

StatusMeaning
400Too short, too long, or a malformed email address
403The Turnstile verification did not pass
429Rate limited
503The bot check is not configured — the endpoint fails closed

The body is validated before the token is verified, because a token verifies exactly once: refusing a too-short request afterwards would leave you holding a spent token and a form you cannot resubmit.

The duplicate check. Runs the gallery’s own retrieval over a draft — no model call.

{ "query": "roaming failures by AP" }

Returns { "dashboards": [ … ], "total": n }, at most 3 dashboards. A query under 10 characters returns an empty list, and so does any failure: this endpoint never reports an error to the page, because a duplicate check that blocks a form has inverted its own purpose.

Asks one question about a request draft.

{ "draft": "Roaming failures by AP…" }

Returns { "question": "…" }, or { "question": null } when the draft is under 40 characters, the day’s model allowance is spent, the caller is rate limited, or anything at all goes wrong.

The view beacon. No body is read; the slug is in the path.

Returns 204. A slug that is not published returns 404, so a counter can only ever name something the gallery actually publishes. It is ungated on purpose — no gate makes a client-reported counter unforgeable without putting a bot-detection script on every dashboard open, which is a cost every reader would pay to protect a number nobody bills against.

The export bundle. The bare /d/{slug}/download means ruckus-one and is the canonical URL.

PlatformAvailable
ruckus-oneYes
ruckus-aiNo — returns 404

Responds with application/zip, Content-Disposition: attachment, and Cache-Control: no-store. Every response is different: dashboard and chart identifiers are regenerated per request, while dataset and database identifiers are preserved. An unknown platform, an unknown slug, an unpublished dashboard and a dashboard with no stored bundle all return 404.

Serves a published dashboard’s artifacts. file is one of full.webp, thumb.webp or export.zip; anything else is a 404.

The route never accepts a storage key — it takes an id, a revision and one of those three filenames and constructs the key itself, so there is no input that can address anything outside the public namespace. It serves only assets belonging to a currently published dashboard, and only at the revision that record currently points at: an earlier revision number is a 404, because the reason a redaction gets tightened is that the previous one covered too little.

Responses are cached immutably for one year.

Path
/sitemap.xmlThe gallery, the how-it-works page and every published permalink
/robots.txtAllows everything except /admin