---
type: explanation
---

# Management API

How customers manage Caputchin (create site keys, rotate secrets, configure [hosted-verification](hosted-verification.md) destinations, manage domain allowlists, issue tokens) across four modalities — all backed by **one canonical API** inside the web app. The decision is recorded in [ADR-0012](adr/0012-four-management-modalities.md); the Terraform provider's language exception is in [ADR-0013](adr/0013-terraform-provider-in-go.md).

This page is the conceptual layer. For the modality-specific reference see [dashboard](dashboard.md) and [api.md](api.md). The runtime [`/siteverify`](api.md#post-siteverify-customer-backend--platform) endpoint is **not** part of this management API — it serves customer backends, not customer admins.

## Architecture

```mermaid
flowchart TB
  H["Humans<br/>(account owners, admins)"]
  D["Custom apps<br/>(any language)"]
  A["AI agents"]
  T["Terraform / IaC"]

  UI["Dashboard UI<br/><b>app.caputchin.com</b>"]
  API["OpenAPI<br/><b>api.caputchin.com</b>"]
  MCP["MCP server<br/><b>mcp.caputchin.com</b><br/>+ <code>@caputchin/mcp</code> npm"]
  TF["Terraform provider<br/><b>caputchin/caputchin</b><br/>(Terraform Registry)"]

  H --> UI
  D --> API
  A --> MCP
  T --> TF

  CORE["Canonical Management API<br/>(web app on Cloudflare Workers, D1)"]

  UI -- "BFF routes<br/>(session cookie)" --> CORE
  API -- "HTTP + JSON<br/>(management token)" --> CORE
  MCP -- "MCP tool calls → HTTP<br/>(management token)" --> CORE
  TF -- "gRPC plan/apply → HTTP<br/>(management token)" --> CORE

  CORE --> DB[(D1)]
```

Modalities differ only at the edge. Schema, validation, RBAC, audit logging, and rate limits live in the canonical API — not duplicated per modality.

## Modalities

| Modality | Audience | Protocol | Auth | Distribution |
|---|---|---|---|---|
| Dashboard UI | Humans | HTML + cookies | Session cookie | Web app route on `app.caputchin.com` — see [dashboard](dashboard.md) |
| OpenAPI | Custom apps in any language | HTTP + JSON | Management token | Spec served at `https://api.caputchin.com/openapi.json` — see [api.md — OpenAPI spec](api.md#openapi-spec) |
| MCP server | AI agents | MCP (stdio or HTTP) | Management token | `@caputchin/mcp` on npm (runnable via `npx`) and hosted at `mcp.caputchin.com`. One implementation, two delivery surfaces. |
| Terraform provider | DevOps / IaC | Terraform plugin protocol (gRPC) | Management token | Published to the Terraform Registry as `caputchin/caputchin` — see [ADR-0013](adr/0013-terraform-provider-in-go.md) |

## Authentication

| Credential | Used by | Issued from | Notes |
|---|---|---|---|
| Session cookie | Dashboard UI | Magic-link or OAuth — see [account-login](account-login.md) | D1-backed, revocable session row keyed on a `caput_session` cookie. Rolling 30-day TTL. Mechanism in [ADR-0020](adr/0020-magic-link-and-github-google-oauth-account-login.md). |
| **Management token** | OpenAPI, MCP, Terraform | Dashboard "Tokens" surface (paid-tier surfaces and account-wide actions) | Account-level. Distinct from the per-site-key `cpt_sec_...` (which is for `/siteverify`). Format: `cpt_pat_...`. Rotatable and revocable. |
| Per-site-key secret (`cpt_sec_...`) | Customer backends calling [`/siteverify`](api.md#post-siteverify-customer-backend--platform) | Created with the site key | Not a management credential — runtime only. See [dashboard](dashboard.md#site-key-shape). |

The runtime `/siteverify` secret and the management token are deliberately separate. A leaked management token compromises account configuration; a leaked `cpt_sec_...` only compromises one site key's verification flow. Different blast radii, different rotation cadences, different storage expectations on the customer side.

## What lives in the management API

The canonical API covers everything the dashboard exposes plus equivalents for non-UI consumers:

- Site keys: create, list, update, delete, rotate secret, edit domain allowlist
- Hosted-verification configuration (paid-tier): toggle, destinations (webhook + email), webhook signing keys — see [hosted-verification](hosted-verification.md)
- Account-level tokens: issue, list, revoke
- Aggregate counters: read per-site-key (the same numbers the [dashboard's integration health diagnostics](dashboard.md#integration-health-diagnostics) display)

What it does **not** cover:

- The runtime endpoints `/game/start`, `/game/complete`, `/siteverify` — those are the [data-plane API](api.md), not the management plane. Different audience, different auth, different security posture.

## Adding a management capability

Any new management feature touches the canonical API first; modality surfaces follow. A typical change:

1. Add the operation to the canonical API + D1 schema migration.
2. Update the OpenAPI spec.
3. Surface in the dashboard.
4. Add the MCP tool definition (in `@caputchin/mcp`).
5. Add the Terraform resource / data source (in `caputchin-terraform`).

Steps 4 and 5 may lag step 1 by one release cycle in practice — see [ADR-0013](adr/0013-terraform-provider-in-go.md). Document the lag in release notes when applicable.

## Why four modalities at MVP

Picking fewer would force customers in the omitted populations to build their own wrappers, which we'd later have to displace. The four-modality scope is the lowest-friction onboarding for the four populations we care about (humans, custom apps, AI agents, IaC). Reasoning in [ADR-0012](adr/0012-four-management-modalities.md).
