Webhooks & API
Molar Guard exposes a Fastify REST API at https://api.molar.it/v1 (or http://localhost:4000/v1 locally), GitHub webhooks for PR automation, Server-Sent Events for live logs, and an MCP server for AI agent integration.
OpenAPI spec: GET /v1/openapi.json on your Guard API host.
Authentication
| Method | Use case | Header |
|---|---|---|
| Session cookie | Dashboard browser (Better Auth) | HttpOnly cookie — do not extract for scripts |
| API key | CI, GitHub Action, scripts | Authorization: Bearer molar_… |
| Org scope | All tenant-scoped calls | x-org-id: <uuid> |
| Signed URL JWT | One-shot PR comment Approve/Reject | Query param token= (short-lived) |
| MCP OAuth | IDE agents via Molar API | Bearer from OAuth AS |
Create API keys: app.molar.it → Settings → API keys.
API keys support scoped permissions (mcp:read, mcp:write, mcp:run, scheduled_checks:manage, etc.).
GitHub webhooks (inbound)
Guard receives GitHub App events at:
POST https://api.molar.it/v1/webhooks/github
Security
Every delivery is validated before processing:
- HMAC-SHA256 signature (
X-Hub-Signature-256) via webhook secret - Replay prevention: delivery ID stored in Redis (
SETEX guard:webhook:delivery:{id} 86400 1, NX) - Body size limit: 25 MB
- Timestamp skew: reject deliveries older than 10 minutes
Subscribed events
pull_request, push, check_run, check_suite, installation, installation_repositories, pull_request_review
Typical flow
GitHub → POST /v1/webhooks/github
→ verify + dedupe
→ enqueue BullMQ (guard-pr | guard-schedule | mender)
→ 200 OK within seconds
→ worker processes asynchronously
If GH_APP_ID is unset (plug-and-play mode), GitHub webhooks are ignored — use the GitHub Action + API key path instead.
Outbound webhooks (alerts)
Configure generic webhooks in Settings → Notifications. Guard POSTs JSON on:
- Incident opened / resolved
- PR gate failure (optional)
- Mender PR opened
- Shadow-prod diff detected
Payload shape (example):
{
"event": "incident.opened",
"orgId": "00000000-0000-0000-0000-000000000001",
"incidentId": "…",
"scenarioSlug": "stripe-subscription-upgrade",
"region": "us-east-1",
"runId": "…",
"failureSignature": "step-7: assertion .subscription-status",
"traceUrl": "https://trace.molar.it/…",
"timestamp": "2026-05-19T14:22:00Z"
}
Verify webhook authenticity via shared secret in notification settings (HMAC on request body).
REST API reference
Base URL: https://api.molar.it/v1
Runs
| Method | Path | Description |
|---|---|---|
POST | /runs/manual | Trigger manual run |
GET | /runs | List runs (filters: type, status, scenario, repo) |
GET | /runs/:id | Run detail + metadata |
GET | /runs/:id/logs | SSE log stream |
GET | /runs/:id/artifacts/{kind} | Presigned URL (screenshot, video, har, trace, etc.) |
Manual run example:
curl -X POST https://api.molar.it/v1/runs/manual \
-H "Authorization: Bearer $MOLAR_API_KEY" \
-H "x-org-id: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"scenarioId": "00000000-0000-0000-0000-000000000001",
"region": "us-east-1",
"baseUrl": "https://staging.example.com"
}'
SSE logs:
curl -N https://api.molar.it/v1/runs/$RUN_ID/logs \
-H "Authorization: Bearer $MOLAR_API_KEY" \
-H "x-org-id: $ORG_ID"
Scheduled checks
| Method | Path | Description |
|---|---|---|
POST | /scheduled_checks | Create |
GET | /scheduled_checks | List |
PUT | /scheduled_checks/:id | Update |
DELETE | /scheduled_checks/:id | Delete |
POST | /scheduled_checks/:id/pause | Pause N hours |
Incidents
| Method | Path | Description |
|---|---|---|
GET | /incidents | List (filter by status, type) |
GET | /incidents/:id | Detail + timeline |
POST | /incidents/:id/ack | Acknowledge |
POST | /incidents/:id/suppress | Suppress with reason |
Mender
| Method | Path | Description |
|---|---|---|
GET | /mender | List attempts |
GET | /mender/:id | Attempt detail |
GET | /mender/:id/preview | Patch diff preview |
POST | /mender/:id/apply | Suggestive → open GitHub PR |
POST | /mender/:id/reject | Reject with reason (RLHF) |
Scenarios & affected detection
| Method | Path | Description |
|---|---|---|
GET | /scenarios | List scenarios |
GET | /scenarios/:id | Scenario detail |
GET | /scenarios/:id/affected_by/:sha | Debug affected graph for commit |
Monitoring & status
| Method | Path | Description |
|---|---|---|
GET | /monitoring/grid | Production health matrix |
GET | /shadow-diff/:runId | Shadow-prod observation pair |
GET | /status | Public status page data (overall + per-scenario health) |
Onboarding
| Method | Path | Description |
|---|---|---|
POST | /onboarding/analytics-ack | Acknowledge analytics filters |
GET | /onboarding/status | Onboarding checklist progress |
Org & billing
| Method | Path | Description |
|---|---|---|
GET | /orgs/:id | Org metadata |
GET | /billing/usage | Metered usage vs plan |
POST | /api-keys | Create API key |
DELETE | /api-keys/:id | Revoke |
Audit
| Method | Path | Description |
|---|---|---|
GET | /audit-events | Tamper-evident audit log (Owner/Admin) |
Error responses
Standard shape:
{ "error": "<code>", "message": "<human explanation>" }
Common codes: 401 Unauthorized, 403 Forbidden, 429 Quota Exceeded, 429 Too Many Requests, 422 validation, 503 unavailable.
Full reference: Error codes
MCP server
Guard also publishes a standalone MCP server (stdio transport) with org-scoped API key auth:
Resources
| URI | Content |
|---|---|
molar://incidents/{orgId} | Open incidents |
molar://orgs/{orgId}/runs/{runId}/trace | Run trace |
molar://scenarios/{id}/healthcheck?orgId=… | Current scenario status |
Tools (standalone Guard MCP)
| Tool | Description |
|---|---|
molar_rerun | Re-enqueue a failed run |
molar_mender_reject | Reject a Mender suggestion (RLHF) |
molar_ack_incident | Acknowledge an incident |
molar_suppress_incident | Suppress an incident |
molar_list_scenarios | List scenarios for an org |
The unified Molar MCP connector at mcp.molar.cloud (via molar-platform/packages/guards-mcp) exposes additional tools — molar_get_run, molar_get_mender_attempts, molar_run_scenarios, etc. — proxied through the Molar API.
Capability manifest: docs.molar.it/.well-known/molar-capabilities.json
MCP auth
Org API key with MCP scopes, or OAuth2 via the Molar API (mcp:read, mcp:write, mcp:run). MCP credentials do not use dashboard session cookies.
Rate limits
- GitHub API calls: Octokit throttling + retry (per installation)
- Guard REST: per-IP and per-org limits; honor
Retry-Afteron429 - Webhook processing: per-installation BullMQ partition prevents noisy-neighbor starvation
Health & metrics
| Endpoint | Purpose |
|---|---|
GET /healthz | Liveness |
GET /readyz | Postgres + Redis readiness |
GET /metrics | Prometheus metrics (ops) |
SDKs and CLI
| Tool | Install |
|---|---|
| CLI | npx @molar/guard |
| GitHub Action | molar/guard-action@v1 |
| Synthetic middleware | @molar/synthetic-middleware (npm) |
No official language SDK yet — use REST + API key. OpenAPI client generation supported via /v1/openapi.json.
Next
- Configuration — environment variables
- Security — API key scopes and RBAC
- Troubleshooting — webhook delivery failures