FixControl/Documentatie

Gebruikershandleiding

Publieke API

Tenant-gescopete REST-API voor issues, patches, integraties en webhooks. Bearer-token-authenticatie.

Met de FixControl Public API kun je vanuit je eigen tools FixControl uitlezen en aansturen — een eigen dashboard, een PM-script, een interne automatisering. Het basispad is /api/public/v1/ op je FixControl-host.

Een API-key aanmaken

  1. Open Settings → Integraties → Publieke API.
  2. Klik Key aanmaken.
  3. Geef hem een naam (zodat je hem terug kunt vinden) en kies scopes — zie hieronder.
  4. Klik Aanmaken. De volledige token wordt één keer getoond. Zet hem direct in je secret manager.

De UI bewaart de prefix (fck_live_a1b2…) en de aanmaaktijd zodat je de key later kunt herkennen, maar de volledige token is niet terug te halen. Kwijt? Trek 'm in en maak een nieuwe aan.

Scopes

Een key draagt één of meer scopes. Kies de kleinste set die het werk doet.

ScopeEndpoints
issues:readGET /api/public/v1/issues, GET /api/public/v1/issues/:key
issues:writePOST /api/public/v1/issues
patches:readGET /api/public/v1/patches, GET /api/public/v1/patches/:id
patches:writegereserveerd voor toekomstige write-acties op patches — vandaag geen endpoints
integrations:readGET /api/public/v1/integrations/status
webhooks:readGET /api/public/v1/webhooks
webhooks:writePOST /api/public/v1/webhooks

Een key zonder scopes kan zich wel authenticeren, maar elke geautoriseerde endpoint geeft 403 met code: insufficient_scope.

Authenticatie

Elke request heeft een Authorization: Bearer <token>-header nodig. De token is gebonden aan één tenant — er is geen aparte tenant-querystring of body-veld; de tenant wordt afgedwongen vanuit de key.

curl https://<jouw-host>/api/public/v1/issues \
  -H "Authorization: Bearer fck_live_a1b2c3d4..."

Een ontbrekende token geeft 401 met code: missing_token. Een ongeldige of ingetrokken token geeft 401 met code: invalid_token. Een geldige token zonder de juiste scope geeft 403 met code: insufficient_scope.

Rate limits

Elke key heeft een token-bucket-budget van 60 requests per minuut (1 token per seconde nominaal, met een burst van 60). De bucket is per-key, dus twee keys in dezelfde tenant delen geen budget.

Bij overschrijding krijg je 429 Too Many Requests met Retry-After in seconden en code: rate_limited. Heb je voor een legitieme use-case meer ruimte nodig, neem contact op.

Endpoints

Issues

# Recente issues opvragen (tenant van de key)
GET /api/public/v1/issues
→ { "items": PublicIssue[] }

# Eén issue ophalen op key
GET /api/public/v1/issues/:key
→ PublicIssue

# Een issue aanmaken
POST /api/public/v1/issues
{
  "title":    "Checkout faalt op mobiel",
  "kind":     "BUG",
  "priority": "high",
  "reporter": "alex@acme.com",
  "summary":  "Optionele samenvatting",
  "body":     "Optionele lange beschrijving",
  "customer": "Optionele klantnaam",
  "flags":    ["payment"],
  "assignee": "Optionele interne id"
}
→ 201 Created → PublicIssue

PublicIssue bevat: key, tenant, kind, title, summary, body, priority, status, readiness, confidence, flags, reporter, assignee, customer, createdAt, updatedAt, externalTracker, externalKey, externalUrl, externalStatus.

Patches

# Patches lijsten (nieuwste eerst)
GET /api/public/v1/patches?limit=100      # limit: 1..200
→ { "items": PublicPatch[] }

# Eén patch ophalen
GET /api/public/v1/patches/:id
→ PublicPatch

PublicPatch draagt patch-id, workspace-id, versie, status, aantal bestanden, additions/deletions, bestandslijst en timestamps.

Integraties

GET /api/public/v1/integrations/status
→ { "items": [
    { "id": "...", "type": "github", "name": "...", "status": "connected",
      "provider": "github", "authKind": "app",
      "createdAt": "...", "lastError": null },
    ...
  ] }

Geen tokens, refresh-tokens, installation-id's of recipient-routingregels in het antwoord — alleen de publiek-veilige samenvatting.

Webhooks

# Uitgaande webhooks lijsten
GET /api/public/v1/webhooks
→ { "items": PublicWebhook[] }

# Aanmaken — geeft het plaintext-secret PRECIES ÉÉN keer terug.
POST /api/public/v1/webhooks
{
  "name":   "Billing notifier",
  "url":    "https://hooks.acme.com/fc",
  "events": ["issue.created", "patch.approved"],
  "enabled": true
}
→ 201 Created → { "webhook": PublicWebhook, "secret": "ws_AB3cD..." }

Geldige event-waarden: issue.created, issue.updated, patch.ready, patch.approved, patch.failed, pr.created, integration.error. Zie de webhooks-handleiding voor het delivery-formaat en de signature.

Error-responses

Elke fout geeft JSON in dit formaat:

{ "error": "Leesbare melding", "code": "stabiele_machine_code" }

De HTTP-status geeft de categorie; code is de stabiele identifier voor je client-logica.

Statuscode-voorbeelden
400missing_field, invalid_field, invalid_url, invalid_events, invalid_body
401missing_token, invalid_token
403insufficient_scope
404not_found
429rate_limited (met Retry-After-header)
5xxinternal_error

OpenAPI

De OpenAPI 3.1-spec wordt geserveerd op:

GET /api/public/v1/openapi.json

Dat is de bron van de waarheid — laat je codegenerator hierop wijzen. De docs volgen de spec.

Best practices

  • Behandel de token als een wachtwoord. Nooit committen, nooit in logs printen.
  • Eén key per integratie. Makkelijker te roteren, te auditen en te scopen.
  • Roteer regelmatig. Maak de nieuwe key, switch je client, trek dan pas de oude in.
  • Webhooks boven polling. Abonneer een uitgaande webhook in plaats van GET /issues te pollen.
  • Behandel 429 met backoff. Honoreer de Retry-After-header in plaats van direct opnieuw te proberen.

Veelgestelde vragen

Is de API hetzelfde als de interne API van het dashboard? Nee. Het dashboard praat met interne routes die een session-cookie nodig hebben en niet stabiel zijn. De Public API op /api/public/v1/... is wat we committen — geversioneerd en met OpenAPI-spec.

Kan een key meerdere tenants benaderen? Nee. Keys zijn per ontwerp tenant-gescoped.

Wat als een key lekt? Trek hem direct in via Settings → Integraties → Publieke API. Intrekken is direct — in-flight requests met de oude key krijgen binnen seconden 401. Check daarna de audit-log voor activiteit met die key.

Iets onduidelijk of fout?Laat het ons weten →

FixControl is een handelsnaam van FixControl B.V. i.o.