Public API
This documents the HTTP endpoints Mergen's runtime already accepts authenticated calls on today. It exists because the website listed "Public API" as a shipped capability while nothing described these endpoints as a product surface — the routes were real, just undocumented as a set. This page closes that gap by describing what's actually callable, not by promising a separate, packaged API product that doesn't exist yet. See What this is not (yet) at the bottom before you build production tooling against it.
For the full local runtime (every route, mergen-server internals, MCP
tools), see CODEBASE_MAP.md and
CLI_REFERENCE.md. This page covers only the routes
meant to be called by an external system with an API key or admin secret —
not the local dashboard/IDE-extension traffic, which talks to 127.0.0.1
without one.
Authentication — two independent layers
Which one applies depends on deployment mode and route. Both are described in full in the main README's Security section — this is the short version for API callers specifically.
1. x-mergen-secret — admin mutation guard (local and cloud).
Every mutating route in MUTATING_PATHS (server/src/app.ts) — including
POST /incident and POST /ci/gate — requires this header to match
~/.mergen/secret (auto-generated on first run) or MERGEN_ADMIN_SECRET if
you've set one. This exists so that an AI agent with plain filesystem access
on the machine can't forge an admin action by hitting the HTTP API directly —
it is not a "public" credential to hand out to arbitrary integrations.
curl -s http://127.0.0.1:3000/ci/gate \
-H "x-mergen-secret: $(cat ~/.mergen/secret)" \
-H 'Content-Type: application/json' \
-d '{"files":["src/auth.ts"],"prTitle":"fix: token refresh"}'
2. x-api-key — tenant-scoped cloud auth (MERGEN_CLOUD_MODE=true only).
On the multi-tenant cloud deployment, the routes below are additionally
wrapped in cloudAuthMiddleware (server/src/sensor/cloud-auth.ts), which
validates a plain-text key against its SHA-256 hash, enforces a per-key rate
limit (default 1000 events/minute), and sets req.tenantId so every read and
write is isolated to your organization's data — see the Deployment
boundary note in the main README for exactly which routes are
tenant-partitioned versus process-global.
curl -s https://your-cloud-instance/ci/gate \
-H 'x-api-key: mrgn_live_...' \
-H 'Content-Type: application/json' \
-d '{"files":["src/auth.ts"],"prTitle":"fix: token refresh"}'
Getting a key today is an operator action, not self-service. POST /api-keys (below) itself requires x-mergen-secret — there is no public
sign-up flow that mints a key without admin access to the instance. This is
intentional: keys are provisioned by whoever runs the cloud instance, the
same way mergen-server config set requires the same secret.
curl -s -X POST https://your-cloud-instance/api-keys \
-H "x-mergen-secret: ..." -H 'Content-Type: application/json' \
-d '{"tenantId":"acme-corp","label":"ci-pipeline"}'
# → { "ok": true, "id": "...", "key": "mrgn_live_...", "note": "Store this key securely — it will not be shown again." }
GET /api-keys (list, no plain text) and DELETE /api-keys/:id (revoke) are
also admin-secret-guarded — see server/src/routes/api-keys.ts.
Endpoints
Incident intake — POST /incident
Triggers the same autonomous triage pipeline as a PagerDuty webhook, for any
monitoring tool that can POST JSON (UptimeRobot, Cronitor, Checkly, Grafana,
a custom script). Full schema and examples are in the route's own docstring:
server/src/routes/incident-webhook.ts.
curl -X POST http://127.0.0.1:3000/incident \
-H "x-mergen-secret: $(cat ~/.mergen/secret)" \
-H 'Content-Type: application/json' \
-d '{"title":"api is down","service":"api"}'
# → { "ok": true, "pid": "<uuid>", "message": "Autopilot started" }
CI Gate — POST /ci/gate
The Change Authorization Gate (Gate C) — checks changed files, a PR
title/description, and optional taskDescription/planSummary against the
override corpus, blast-radius analysis, and the deterministic diff-content
detectors, returning pass / warn / require_review / block. This is
the endpoint the bundled action.yml GitHub Action POSTs to as a workflow
step — see action.yml's own description: for the full input contract, and
server/src/routes/ci-gate.ts for the response shape.
Telemetry ingest — POST /ingest, POST /v1/traces, POST /v1/logs
/ingest accepts Mergen's native event shapes (console, network, terminal,
diagnostic). /v1/traces and /v1/logs speak OTLP over HTTP, JSON
encoding only — see the main README's Backend instrumentation section
for the exact OTEL_EXPORTER_OTLP_PROTOCOL=http/json requirement most SDKs
need set explicitly. /v1/metrics returns 200 but stores nothing today.
Ephemeral cloud credentials — GET /credentials/scopes, POST /credentials/request
Requests a short-lived AWS/GCP/Azure credential scoped to an
operator-defined role, brokered via STS AssumeRole (AWS) or Mergen's own OIDC
issuer (GCP/Azure workload identity federation) — see
server/src/intelligence/credential-broker.ts. Requires a verified agent
identity (x-mergen-agent-token, from mergen-server agent-register), and
is itself routed through Gate A, so an operator can write an ordinary policy
rule restricting which agents/scopes may request which credentials. Paid
capability (Starter plan and above).
curl http://127.0.0.1:3000/credentials/scopes -H 'x-mergen-agent-token: ...'
curl -X POST http://127.0.0.1:3000/credentials/request \
-H 'x-mergen-agent-token: ...' -H 'Content-Type: application/json' \
-d '{"scope":"staging-readonly","taskId":"task-123"}'
Service topology — GET /service-graph, GET /route-reachability
Read-only views of the live service dependency graph built from observed
OTLP spans — the same data GET /topology renders as an interactive D3
graph. /route-reachability narrows this to which routes are provably
reachable, used to suppress hypotheses about unreachable code paths during
diagnosis.
What this is not (yet)
Being straightforward about maturity, since the whole point of this page is to stop overclaiming:
- No stable versioning scheme. There is no
/v1/-prefixed convention for Mergen's own endpoints (OTLP's/v1/tracespath is OTLP's own spec, not ours) — a breaking change to a route's shape is not yet fenced by a version number. - No official client SDKs, beyond the one-line Node auto-instrumentation
(
import 'mergen-server/sdk/node.js'). Every example above is a rawcurlcall. - No published, guaranteed rate-limit contract beyond the per-API-key default (1000 events/minute, configurable per key at creation).
- No OpenAPI/Swagger spec. This document is hand-maintained against the
route source files, not generated — unlike
CONFIGURATION.md, which a census test keeps in sync withconfig/registry.tsautomatically. If this page drifts from the routes, the routes' own docstrings (linked above) are the source of truth.