← Zurück

Public API v1

Tenant-scoped REST-API für externe Tools (z. B. Claude Code, CLIs, Scripts), um Einträge auf Boards zu lesen, anzulegen und zu aktualisieren. Dieselben Schlüssel bedienen auch den MCP-Server, mit dem KI-Assistenten direkt mit deinem Board sprechen.

Base URL

https://roadlight.pro/api/v1

Lokal:

http://localhost:3000/api/v1

Authentifizierung

Jeder Request braucht einen API-Schlüssel im Authorization-Header:

Authorization: Bearer vt_live_<token>

API-Schlüssel werden im Tenant-Admin-UI unter „API-Schlüssel“ erstellt (/tenant-admin.html?tenant=<slug>). Der Klartext-Token wird nur einmal beim Erstellen angezeigt – danach speichert die Datenbank nur einen SHA-256-Hash.

Jeder Schlüssel ist auf genau einen Tenant gescoped – er sieht ausschließlich Boards und Einträge dieses Workspaces.

Scopes

ScopeErlaubt
suggestions:readBoards und Einträge lesen
suggestions:writeEinträge anlegen (auto-freigegeben)
suggestions:statusStatus, Priorität und Labels ändern
comments:readKommentare lesen
comments:writeAdmin-Kommentare schreiben (auto-freigegeben)

Fehlt ein erforderlicher Scope, gibt der Endpoint 403 zurück.

Rate Limits

Pro Schlüssel:

Überschreitung → 429 Too Many Requests.

Fehler-Format

{ "error": "human-readable message" }

Endpoints

GET /me

Sanity-Check für den Schlüssel. Gibt Tenant- und Scope-Info zurück.

curl -H "Authorization: Bearer vt_live_…" \
  https://roadlight.pro/api/v1/me

Response:

{
  "tenant": { "id": "tenant_abc", "slug": "acme", "name": "Acme Workspace" },
  "key": { "name": "Claude Code lokal", "scopes": ["suggestions:read", "suggestions:write"] }
}

GET /apps

Liste der Boards im Tenant. Benötigt suggestions:read.

curl -H "Authorization: Bearer vt_live_…" \
  https://roadlight.pro/api/v1/apps

Response:

[
  {
    "id": "app_xyz",
    "slug": "customer-feedback",
    "name": "Customer Feedback",
    "description": "Wünsche und Bugs unserer Kund:innen",
    "ticketPrefix": "CF"
  }
]

GET /apps/:appSlug/suggestions

Liste aller Einträge in einem Board (auch nicht-freigegebene). Benötigt suggestions:read.

Query-Filter (optional):

curl -H "Authorization: Bearer vt_live_…" \
  "https://roadlight.pro/api/v1/apps/customer-feedback/suggestions?type=bug&status=offen"

POST /apps/:appSlug/suggestions

Neuen Eintrag erstellen – automatisch freigegeben. Benötigt suggestions:write.

Body:

{
  "type": "feature",
  "title": "Dark mode für die Mobile App",
  "description": "Auf dem iPhone fehlt aktuell der Dark-Mode-Schalter."
}

Bug-Variante:

{
  "type": "bug",
  "title": "Login schlägt mit 500 fehl",
  "description": "Beim Login mit Google kommt 500.",
  "severity": "high",
  "stepsToReproduce": "1. /login öffnen\n2. Google-Button klicken",
  "expectedBehavior": "Erfolgreicher Login",
  "actualBehavior": "500 Internal Server Error",
  "environment": { "platform": "iOS 17.4", "browser": "Safari 17" }
}

Ticket-Variante:

{
  "type": "ticket",
  "title": "Domain umziehen",
  "description": "DNS-Records auf Cloudflare migrieren",
  "priority": "hoch"
}

Response (201):

{
  "id": "sug_abc123",
  "ticketNumber": "CF-042",
  "type": "feature",
  "title": "Dark mode für die Mobile App",
  "description": "…",
  "status": "neu",
  "priority": "mittel",
  "labels": [],
  "approved": true,
  "votes": 0,
  "appId": "app_xyz",
  "tenantId": "tenant_abc",
  "severity": null,
  "createdAt": "2026-05-21T14:12:33.000Z"
}

GET /suggestions/:id

Einzelnen Eintrag laden. Benötigt suggestions:read. 404, wenn Eintrag nicht zum Tenant des Schlüssels gehört.

PATCH /suggestions/:id

Status, Priorität und/oder Labels ändern. Benötigt suggestions:status.

Body (alle Felder optional, mindestens eines erforderlich):

{
  "status": "wird umgesetzt",
  "priority": "hoch",
  "labels": ["mobile", "ux"]
}

Setzt automatisch approved: true, falls ein Status ≠ neu gesetzt wird.

GET /suggestions/:id/comments

Liste aller Kommentare (auch pending). Benötigt comments:read.

POST /suggestions/:id/comments

Admin-Kommentar hinzufügen (auto-freigegeben). Benötigt comments:write.

{
  "text": "Wir haben das in Sprint 42 eingeplant.",
  "screenshots": []
}

screenshots ist optional und akzeptiert Base64-Data-URLs (data:image/png;base64,…), max. 5 Bilder, je max. 300 KB, gesamt max. 800 KB.

Konstanten

Suggestion-Typen: feature, bug, ticket

Status (Feature): neu, wird geprüft, wird umgesetzt, im Test, ist umgesetzt, wird nicht umgesetzt

Status (Bug/Ticket): neu, offen, in Bearbeitung, im Test, wartend, gelöst, geschlossen

Prioritäten: niedrig, mittel, hoch, kritisch

Bug-Severities: low, medium, high, critical (wird beim Erstellen automatisch in priority gemappt)

Audit

Jeder Write-Call (POST/PATCH/DELETE) wird mit actor: "api:<keyId>" protokolliert. Im Tenant-Admin-UI sind die Aktionen in der Eintrags-Historie sichtbar.

Beispiel: Eintrag aus einem Bash-Script anlegen

#!/usr/bin/env bash
set -euo pipefail

: "${VOTING_TOOL_API_KEY:?Bitte API-Schlüssel in VOTING_TOOL_API_KEY setzen}"

curl -fsS -X POST \
  -H "Authorization: Bearer $VOTING_TOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "bug",
    "title": "CI rot nach Merge",
    "description": "PR #42 hat E2E-Tests gerötet",
    "severity": "medium",
    "stepsToReproduce": "main pullen, npm test",
    "expectedBehavior": "alle Tests grün",
    "actualBehavior": "tenant-admin.spec.js schlägt fehl"
  }' \
  https://roadlight.pro/api/v1/apps/customer-feedback/suggestions