StateAnchor
Documentation
Back to app →
Reference

API Reference

StateAnchor exposes REST endpoints for the GitHub Action, programmatic integrations, and public project status. All endpoints return JSON.

Authentication

StateAnchor uses two authentication methods depending on the caller:

MethodUsed byHow it works
Clerk sessionBrowser / dashboardAutomatic via cookie. Used by all /api/projects/* and dashboard routes.
GitHub OIDC action tokenGitHub Action (machine)Short-lived token minted via /api/action/oidc/exchange. Passed as Bearer token in the Authorization header. Used by /api/action/* endpoints.

The action token flow: GitHub provides an OIDC JWT → the action exchanges it with StateAnchor → StateAnchor returns a scoped action token bound to the repo, ref, and event type. This token is valid for 5 minutes.

Base URL

https://stateanchor.dev

All endpoint paths below are relative to this base URL.


POST /api/action/validate

Validates a stateanchor.yaml spec file. Returns validation result and parsed config summary.

Authentication

Required. Action token via Authorization: Bearer <action_token>.

Request body

{
  "config_content": "<raw YAML string>",
  "repo": "owner/repo",
  "ref": "refs/heads/main",
  "commit_sha": "abc123..."
}

Success response (200)

{
  "valid": true,
  "config_summary": {
    "service": "payments-api",
    "version": "1.0.0",
    "endpoint_count": 3,
    "outputs": ["typescript", "python", "mcp"]
  }
}

Error responses

StatusError codeDescription
401invalid_action_tokenToken missing, expired, or invalid.
403repo_not_linkedRepository is not connected in StateAnchor.
403ref_not_allowedBranch/ref is not in the allowed mappings.
422invalid_configYAML parse error or schema validation failure. Includes errors array.
429rate_limitedToo many requests. Retry after the Retry-After header value.

POST /api/action/gate-check

Diffs the incoming spec against the previous IR, scores breaking changes, evaluates the gate policy, creates a sync run, and returns the gate decision. This is the primary endpoint the GitHub Action calls after validation passes.

Authentication

Required. Action token via Authorization: Bearer <action_token>.

Request body

{
  "config_content": "<raw YAML string>",
  "repo": "owner/repo",
  "ref": "refs/heads/main",
  "commit_sha": "abc123...",
  "mode": "sync"
}

Success response (200)

{
  "gate_action": "allow",
  "gate_score": 0,
  "gate_reason": "No breaking changes detected",
  "sync_run_id": "fb87c28a-4509-4463-9fc0-ac35e2438c3b",
  "breaking_operations": [],
  "diff_summary": {
    "total_changes": 1,
    "breaking_changes": 0,
    "additions": 1,
    "removals": 0
  }
}

Blocked response (200 with gate_action: block)

{
  "gate_action": "block",
  "gate_score": 40,
  "gate_reason": "Breaking changes exceed block threshold (60)",
  "sync_run_id": "a1b2c3d4-...",
  "breaking_operations": [
    {
      "kind": "endpoint_removed",
      "path": "/users",
      "score": 40,
      "severity": "error",
      "description": "Endpoint GET /users was removed"
    }
  ]
}

Error responses

StatusError codeDescription
401invalid_action_tokenToken missing, expired, or invalid.
403repo_not_linkedRepository is not connected in StateAnchor.
403ref_not_allowedBranch/ref is not in the allowed mappings.
422invalid_configSpec failed validation.
429rate_limitedToo many requests.

POST /api/waitlist

Public endpoint. Adds an email to the StateAnchor waitlist. No authentication required.

Request body

{
  "email": "user@example.com"
}

Success response (200)

{
  "ok": true
}

Error responses

StatusError codeDescription
400missing_emailEmail field is missing or empty.
409already_registeredEmail is already on the waitlist.

Rate limits

EndpointLimitScope
/api/action/validate10 requests / minutePer repository
/api/action/gate-check5 requests / minutePer sync run
/api/waitlist5 requests / minutePer IP

Rate-limited responses return 429 with a Retry-After header indicating seconds to wait before retrying.


Error format

All error responses use a consistent JSON shape:

{
  "error": "error_code_string"
}

The error field is a machine-readable snake_case code. Some endpoints include additional fields like errors (array of validation issues) ordetail (human-readable explanation).

// Example: validation failure with details
{
  "error": "invalid_config",
  "errors": [
    "endpoints[0]: missing required field 'method'",
    "outputs: at least one output must be enabled"
  ]
}