Skip to content

Public API

Taco exposes a public, self-service REST API under /api/v1 for managing client registrations and driving the approval workflow programmatically. It is a separate surface from the internal reviewer/admin UI — see the scope boundary below.

The API is an OAuth2 resource server — it validates bearer tokens (JWT or opaque) issued by an authorization server you configure. Taco never issues its own API tokens. See the API_AUTH_* variables on the Configuration page.

Authorization: Bearer <access_token>

The token asserts who is calling (sub) and what they may do (scope). It never asserts which organization — every request states that explicitly.

Every resource lives under an organization. There are two equivalent route trees:

  • Explicit (always available): /api/v1/organizations/{organizationId}/registrations
  • Default-organization convenience (opt-in via API_DEFAULT_ORGANIZATION_ENABLED=true): /api/v1/registrations — resolves the organization from the caller’s default-organization mapping instead of a path segment.

A token subject is granted access to specific organizations (and optionally marked as that organization’s default) from Settings → Organization → API Access, by an org admin.

GET /api/v1/organizations lists every organization the caller’s token subject can act on.

The public API intentionally does not expose reviewer/admin actions: approve, reject, request-changes, suspend, unsuspend, deprecate, change-set approve/reject, or the review queue and comments. A token — however broadly scoped — cannot reach those transitions through this API; they remain reachable only through the internal reviewer UI. The public API can create, edit, submit, and withdraw a registration in an authorized organization, and propose change sets against an active client.

  • GET /api/v1/organizations/{organizationId}/capabilities — plan gating, the caller’s granted scopes, available grant/application types per client type, visible policy profile constraints, platform policy, templates, and rate limits.
  • Every registration/change-set response includes an actions array (e.g. ["edit", "submit", "delete"]) naming exactly which self-service transitions are currently allowed, so the UI never has to guess from status strings.

Every non-2xx response uses a structured envelope:

{
"error": {
"code": "validation_failed",
"message": "Request body failed validation.",
"fields": [{ "path": "config.redirectUris", "message": "Invalid url" }],
"requestId": "..."
}
}

See the OpenAPI document for the full code enum.

ResourceExplicit path
RegistrationsGET/POST /api/v1/organizations/{organizationId}/registrations
RegistrationGET/PATCH/DELETE .../registrations/{id}
Lifecycle actionsPOST .../registrations/{id}/actions/{submit|withdraw}
Change setsGET/POST .../registrations/{id}/change-sets
Change setGET .../change-sets/{id}
Policy profiles (read-only)GET .../policy-profiles[/{id}]
Templates (read-only)GET .../templates[/{id}]
CapabilitiesGET .../capabilities

Each of the above also exists unprefixed (e.g. POST /api/v1/registrations) when API_DEFAULT_ORGANIZATION_ENABLED=true.