Developers

Plug it into your own tooling

WAM exposes the same REST API the panel uses. The backup heartbeat endpoint and GitHub webhook are live today; the rest is on the roadmap.

  • Live

    REST API

    The /api/v1 endpoints the panel uses: JSON, Bearer access tokens, RFC 7807 error bodies and a consistent error_code in every response.

  • Live

    Backup heartbeat

    One request at the end of your backup script: did it succeed, how long did it take, how big is it. Delays and failures become alerts.

  • Live

    GitHub webhook

    GitHub App events arrive as signed webhooks (HMAC, constant-time verification); deployment and commit status update instantly.

  • Soon

    API keys and OpenAPI

    Scoped, revocable API keys, rate limits and an OpenAPI schema with interactive docs.

  • Soon

    Outbound webhooks

    Signed webhooks for incident opened/closed, SSL and domain expiry; compatible with Zapier, Make and n8n.

  • Soon

    Prometheus and Grafana

    A Prometheus-compatible metrics endpoint and ready-made Grafana dashboards for your own observability stack.

Authentication flow

You connect to the same API the dashboard uses, with a session token. The access token is short-lived; when it expires the refresh cookie issues a new one.

Sign inPOST /api/v1/auth/login
Access tokenShort-lived JWT
API requestAuthorization: Bearer <token>
RefreshPOST /api/v1/auth/refresh · HttpOnly cookie

Today the API works with session tokens. Scoped, revocable API keys are on the roadmap. The backup heartbeat and webhook endpoints work separately with their own tokens.

Endpoint catalog

A selection of commonly used endpoints. All live under /api/v1; permissions apply according to your role.

Identity

  • POST/auth/loginEmail + password → access token
  • POST/auth/refreshNew access token (rotating cookie)
  • GET/auth/meUser, organization, role and permissions

Websites and domains

  • GET/websitesList (cursor-paginated)
  • POST/websitesAdd a website (plan limit applies)
  • GET/websites/{id}/monitoringUptime, response-time series, incidents
  • POST/websites/{id}/checkManual check (quota-limited)
  • GET/domainsDomain list, expiry, registrar

Alerts and tasks

  • GET/alertsActive, resolved, all
  • POST/alerts/{id}/resolveMark as resolved manually
  • GET/alerts/rulesEffective rules (default + organization)

Code and backups

  • GET/repositoriesRepository list, latest commit
  • GET/deploymentsProduction deployment status
  • POST/backups/targetsBackup target + one-time token
  • POST/backups/targets/{id}/rotate-tokenRotate the token

Inbound

  • POST/ingest/backupsReport a backup result (Bearer token)
  • POST/webhooks/githubGitHub App events (HMAC-signed)

General

  • GET/public/plansPlans on sale and their limits
  • GET/dashboard/summaryKPIs and action-required items
  • GET/exports/{resource}Filtered export

Webhook verification

GitHub App events arrive signed. The signature is compared in constant time over the raw body; if valid, 202 returns immediately and processing happens in the background.

GitHub eventpush, deployment, workflow_run…
Signature verifiedHMAC-SHA256, constant time
202 AcceptedDelivery ID prevents replays
Processed in queueCommit and deployment status updated
X-Hub-Signature-256X-GitHub-EventX-GitHub-Delivery

Error contract

All errors return as RFC 7807 application/problem+json; validation errors include a per-field errors object.

  • 400Validation error
  • 401Token missing or invalid
  • 403No permission or plan limit
  • 404Not found (another organization's record also returns 404)
  • 409Conflict (e.g. domain already registered)
  • 429Rate limit or quota; Retry-After header
application/problem+json
{
  "type": "plan-limit",
  "title": "Plan limit reached",
  "status": 403,
  "detail": "Website limit for your plan has been reached.",
  "traceId": "00-8f2c…-01"
}

Cursor pagination

List endpoints use an opaque cursor instead of offsets: constant cost even on large data.

cursor pagination
GET /api/v1/websites?limit=50&cursor=eyJ0IjoiMjAyNi0xMC0wNyIsImlkIjoiLi4uIn0

{
  "items": [ … ],
  "nextCursor": "eyJ0IjoiMjAyNi0xMC0wNiIs…"
}

Limits

  • Backup heartbeat: 60 requests per minute per token.
  • Scan now / manual check: daily plan quota and per-website cooldown (429).
  • Plan limit exceeded: 403 with type: plan-limit.
  • The refresh endpoint requires a custom header (CSRF protection).

Backup heartbeat example

The token travels only in the Authorization header. WAM receives the result only; it never accesses the backup file.

You create the token in the Backup section of a website's detail page.

Responses

  • 202Accepted, returns runId
  • 400Invalid body
  • 401Missing or invalid token
  • 429More than 60 requests per minute for this token
bashPOST /api/v1/ingest/backups
curl -sS -X POST "https://wamdesk.com/api/v1/ingest/backups" \
  -H "Authorization: Bearer $WAM_BACKUP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status":"SUCCESS","sizeBytes":123456789,"durationSec":94,"location":"r2://backups/2026-10-07.sql.gz","message":"nightly backup"}'

Missing an endpoint?

Tell us which automation you need; we order the roadmap accordingly.