{
  "openapi": "3.0.3",
  "info": {
    "title": "Sidecar Network API",
    "version": "1.0",
    "description": "Control-plane API for the Sidecar relay fleet. Gives any Docker container its own public IPv6 (and optionally IPv4) address via WireGuard — no proxying, full L3/L4 reachability. Each relay POP exposes this API on port 8443 (TLS 1.3, SPKI-pinned). Authentication uses Bearer tokens issued at signup or via the billing flow.",
    "contact": {
      "name": "Sidecar Network",
      "url": "https://sidecar.network",
      "email": "support@sidecar.network"
    },
    "license": {
      "name": "Proprietary — binary distribution only",
      "url": "https://sidecar.network/terms"
    }
  },
  "servers": [
    {
      "url": "https://relay-us-east.sidecar.network:8443",
      "description": "US East relay (default)"
    },
    {
      "url": "https://relay-us-west.sidecar.network:8443",
      "description": "US West relay"
    },
    {
      "url": "https://relay-us-west1.sidecar.network:8443",
      "description": "US West 1 relay (dedicated /56)"
    },
    {
      "url": "https://relay-ca-east.sidecar.network:8443",
      "description": "Canada East relay"
    },
    {
      "url": "https://relay-eu-west.sidecar.network:8443",
      "description": "EU West relay"
    },
    {
      "url": "https://relay-eu-central.sidecar.network:8443",
      "description": "EU Central relay"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer token issued at free signup or via the billing/checkout flow. Pass as: Authorization: Bearer <token>"
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "peers": {
            "type": "integer",
            "description": "Current connected peer count on this relay"
          },
          "relay": {
            "type": "string",
            "description": "WireGuard endpoint advertised by this relay",
            "example": "relay-us-east.sidecar.network:51820"
          }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "service": {
            "type": "string",
            "example": "sidecar-network"
          },
          "relay": {
            "type": "string",
            "description": "WireGuard public key of this relay (base64)"
          },
          "privacy": {
            "type": "object",
            "properties": {
              "db_location": {
                "type": "string",
                "example": "tmpfs (/run/sidecar) — RAM only"
              },
              "traffic_logs": {
                "type": "boolean",
                "example": false
              },
              "session_logs": {
                "type": "boolean",
                "example": false
              },
              "wal_encryption": {
                "type": "string",
                "example": "AES-256-GCM before leaving host"
              }
            }
          },
          "pq_crypto": {
            "type": "string",
            "example": "X-Wing hybrid KEM (X25519 + ML-KEM-768, IETF draft-connolly-cfrg-xwing-kem-05)"
          },
          "canary": {
            "type": "string",
            "example": "https://sidecar.network/canary"
          }
        }
      },
      "VersionResponse": {
        "type": "object",
        "properties": {
          "service": {
            "type": "string",
            "example": "sidecar-ctrl"
          },
          "version": {
            "type": "string",
            "example": "v1.0.3"
          },
          "commit": {
            "type": "string",
            "example": "d4b7e36"
          },
          "build_time": {
            "type": "string",
            "format": "date-time"
          },
          "go": {
            "type": "string",
            "example": "go1.26.3"
          }
        }
      },
      "FreeSignupRequest": {
        "type": "object",
        "required": ["email", "altcha"],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Customer email address. Always returns 202 regardless of whether the address is new (account enumeration prevention)."
          },
          "altcha": {
            "type": "string",
            "description": "Base64-encoded Altcha proof-of-work payload from the <altcha-widget>."
          }
        }
      },
      "MagicLinkRequest": {
        "type": "object",
        "required": ["email"],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "MagicLinkVerifyRequest": {
        "type": "object",
        "required": ["token"],
        "properties": {
          "token": {
            "type": "string",
            "description": "Magic-link token read from the URL fragment by client-side JS."
          }
        }
      },
      "AddPeerRequest": {
        "type": "object",
        "required": ["pubkey", "container_id"],
        "properties": {
          "pubkey": {
            "type": "string",
            "description": "WireGuard public key of the peer (base64)."
          },
          "container_id": {
            "type": "string",
            "description": "Docker container ID this peer belongs to."
          },
          "mlkem_ek": {
            "type": "string",
            "description": "X-Wing public key for hybrid PQ-PSK derivation (base64, 1216 raw bytes). Optional; enables post-quantum PSK."
          },
          "psk_version": {
            "type": "string",
            "description": "PSK derivation version. Empty or 'legacy' = pre-HKDF. 'SIDECAR-PSK/v1' = current HKDF-based derivation.",
            "example": "SIDECAR-PSK/v1"
          },
          "relay_mode": {
            "type": "string",
            "description": "Set to 'onion' for two-hop nested tunnel mode.",
            "enum": ["", "onion"]
          },
          "layer": {
            "type": "string",
            "description": "Required when relay_mode=onion. Must be 'outer' or 'inner'.",
            "enum": ["outer", "inner"]
          }
        }
      },
      "AddPeerResponse": {
        "type": "object",
        "properties": {
          "ipv6": {
            "type": "string",
            "description": "Allocated /128 IPv6 address for this peer.",
            "example": "2604:2dc0:20d:fa00::1"
          },
          "ipv4": {
            "type": "string",
            "description": "Allocated /32 IPv4 address (if tier includes dedicated IPv4).",
            "example": "15.204.133.174"
          },
          "relay_pubkey": {
            "type": "string",
            "description": "WireGuard public key of the relay (base64)."
          },
          "endpoint": {
            "type": "string",
            "description": "WireGuard UDP endpoint for this relay.",
            "example": "relay-us-east.sidecar.network:51820"
          },
          "peer_id": {
            "type": "string",
            "description": "Opaque peer ID for future rotate-psk / teardown calls."
          },
          "psk": {
            "type": "string",
            "description": "Pre-shared key (base64). Present when X-Wing key was supplied."
          },
          "psk_version": {
            "type": "string",
            "example": "SIDECAR-PSK/v1"
          }
        }
      },
      "PeerInfo": {
        "type": "object",
        "properties": {
          "peer_id": {
            "type": "string"
          },
          "pubkey": {
            "type": "string"
          },
          "ipv6": {
            "type": "string"
          },
          "ipv4": {
            "type": "string"
          },
          "container_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TokenInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "plan": {
            "type": "string",
            "description": "Tier slug: free | micro | spark | launch | pulse | pulse_ipv4 | relay",
            "example": "spark"
          },
          "max_peers": {
            "type": "integer"
          },
          "max_ipv6": {
            "type": "integer"
          },
          "max_ipv4": {
            "type": "integer"
          },
          "email": {
            "type": "string"
          }
        }
      },
      "CheckoutCreateRequest": {
        "type": "object",
        "required": ["tier", "altcha"],
        "properties": {
          "tier": {
            "type": "string",
            "description": "Tier slug to purchase.",
            "enum": ["micro", "spark", "launch", "pulse", "pulse_ipv4", "relay"]
          },
          "altcha": {
            "type": "string",
            "description": "Altcha proof-of-work payload."
          }
        }
      },
      "SubscribeRequest": {
        "type": "object",
        "required": ["tier"],
        "properties": {
          "tier": {
            "type": "string",
            "description": "Tier slug for the PayPal subscription.",
            "enum": ["micro", "spark", "launch", "pulse", "pulse_ipv4", "relay"]
          }
        }
      },
      "TosAcceptRequest": {
        "type": "object",
        "required": ["session_id", "accepted"],
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Server-issued session ID from checkout/create response."
          },
          "accepted": {
            "type": "boolean",
            "description": "Must be true."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        }
      }
    }
  },
  "paths": {
    "/v1/version": {
      "get": {
        "summary": "Relay binary version",
        "description": "Returns the running binary version, commit hash, build time, and Go version. No authentication required.",
        "operationId": "getVersion",
        "tags": ["Public"],
        "responses": {
          "200": {
            "description": "Version information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/health": {
      "get": {
        "summary": "Liveness probe",
        "description": "Returns relay health including current connected peer count. No authentication required.",
        "operationId": "getHealth",
        "tags": ["Public"],
        "responses": {
          "200": {
            "description": "Relay is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/status": {
      "get": {
        "summary": "Structured public relay status",
        "description": "Returns relay public key, privacy policy snapshot, and post-quantum crypto in use. Safe for public consumption — does not reveal peer counts.",
        "operationId": "getStatus",
        "tags": ["Public"],
        "responses": {
          "200": {
            "description": "Relay status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            }
          }
        }
      }
    },
    "/canary": {
      "get": {
        "summary": "Warrant canary",
        "description": "Serves the warrant canary text from /etc/sidecar/CANARY.txt. The X-Canary-Updated response header carries the last update timestamp.",
        "operationId": "getCanary",
        "tags": ["Public"],
        "responses": {
          "200": {
            "description": "Warrant canary text",
            "headers": {
              "X-Canary-Updated": {
                "description": "RFC 3339 timestamp of the last canary update",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "503": {
            "description": "Canary file temporarily unavailable"
          }
        }
      }
    },
    "/pgp": {
      "get": {
        "summary": "PGP public key",
        "description": "Returns the PGP public key used to sign releases.",
        "operationId": "getPGP",
        "tags": ["Public"],
        "responses": {
          "200": {
            "description": "PGP public key (ASCII-armored)",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v1/signup/free": {
      "post": {
        "summary": "Create free-tier account",
        "description": "Registers a new free-tier account. Requires an Altcha proof-of-work. Always returns 202 regardless of whether the email is new (account enumeration prevention). If the email already exists a magic-link is sent instead.",
        "operationId": "signupFree",
        "tags": ["Auth"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FreeSignupRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — email sent (or silently suppressed)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "sent"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/v1/auth/magic-link": {
      "post": {
        "summary": "Request a magic-link login email",
        "description": "Sends a one-time login link to the given email address. Always returns 202 to prevent account enumeration. The link uses a URL fragment (#t=TOKEN) so email scanners cannot pre-fetch the token.",
        "operationId": "requestMagicLink",
        "tags": ["Auth"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MagicLinkRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/v1/auth/magic-link/verify": {
      "post": {
        "summary": "Verify magic-link token",
        "description": "Called by the client JS on /auth/verify after reading the token from the URL fragment. On success sets a 30-day HMAC-signed session cookie and returns a redirect URL.",
        "operationId": "verifyMagicLink",
        "tags": ["Auth"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MagicLinkVerifyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful — session cookie set",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "redirect": {
                      "type": "string",
                      "example": "/dashboard"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Token expired or malformed"
          },
          "401": {
            "description": "Token invalid or already used"
          }
        }
      }
    },
    "/v1/auth/logout": {
      "post": {
        "summary": "Log out",
        "description": "Revokes the current session cookie.",
        "operationId": "logout",
        "tags": ["Auth"],
        "responses": {
          "200": {
            "description": "Logged out"
          }
        }
      }
    },
    "/v1/peers": {
      "post": {
        "summary": "Register a WireGuard peer",
        "description": "Adds a WireGuard peer to this relay, allocates an IPv6 /128 (and optionally an IPv4 /32 for qualifying tiers), programs NDP proxy entries, and returns the relay's WireGuard public key and endpoint. Requires a valid Bearer token and a compatible agent version header.",
        "operationId": "addPeer",
        "tags": ["Peers"],
        "security": [{"bearerAuth": []}],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddPeerRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Peer registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddPeerResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request (missing fields, unsupported psk_version)"
          },
          "401": {
            "description": "Unauthorized"
          },
          "429": {
            "description": "Rate limit exceeded or peer quota exhausted"
          }
        }
      },
      "get": {
        "summary": "List peers for this token",
        "description": "Returns all active peers registered under the authenticated token.",
        "operationId": "listPeers",
        "tags": ["Peers"],
        "security": [{"bearerAuth": []}],
        "responses": {
          "200": {
            "description": "Peer list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PeerInfo"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/peers/{pubkey}": {
      "delete": {
        "summary": "Remove a WireGuard peer",
        "description": "Deregisters the peer identified by its WireGuard public key, removes the /128 route and NDP proxy entry, and releases the IPv6 allocation.",
        "operationId": "deletePeer",
        "tags": ["Peers"],
        "security": [{"bearerAuth": []}],
        "parameters": [
          {
            "name": "pubkey",
            "in": "path",
            "required": true,
            "description": "WireGuard public key of the peer to remove (base64, URL-encoded)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Peer removed"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Peer not found"
          }
        }
      }
    },
    "/v1/peers/{ipv6}": {
      "get": {
        "summary": "Get peer by IPv6 address",
        "description": "Looks up a peer by its allocated IPv6 address.",
        "operationId": "getPeerByIPv6",
        "tags": ["Peers"],
        "security": [{"bearerAuth": []}],
        "parameters": [
          {
            "name": "ipv6",
            "in": "path",
            "required": true,
            "description": "IPv6 address of the peer (URL-encoded if needed)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Peer information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PeerInfo"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Peer not found"
          }
        }
      }
    },
    "/v1/peers/{peer_id}/rotate-psk": {
      "post": {
        "summary": "Rotate PSK for a peer",
        "description": "Derives a new pre-shared key for the given peer using the current HKDF derivation. Requires re-negotiation on the agent side.",
        "operationId": "rotatePSK",
        "tags": ["Peers"],
        "security": [{"bearerAuth": []}],
        "parameters": [
          {
            "name": "peer_id",
            "in": "path",
            "required": true,
            "description": "Opaque peer ID returned at peer registration",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mlkem_ek": {
                    "type": "string",
                    "description": "Updated X-Wing public key (base64) for renewed PQ-PSK derivation."
                  },
                  "psk_version": {
                    "type": "string",
                    "example": "SIDECAR-PSK/v1"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "New PSK issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "psk": {
                      "type": "string"
                    },
                    "psk_version": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Peer not found"
          }
        }
      }
    },
    "/v1/tokens/me": {
      "get": {
        "summary": "Get token details",
        "description": "Returns quota, tier, and metadata for the authenticated token.",
        "operationId": "getTokensMe",
        "tags": ["Tokens"],
        "security": [{"bearerAuth": []}],
        "responses": {
          "200": {
            "description": "Token information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenInfo"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/tokens/rotate": {
      "post": {
        "summary": "Rotate token secret",
        "description": "Issues a new token secret, invalidating the previous one. The response contains the new token value.",
        "operationId": "rotateToken",
        "tags": ["Tokens"],
        "security": [{"bearerAuth": []}],
        "responses": {
          "200": {
            "description": "New token issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/billing/tos/accept": {
      "post": {
        "summary": "Accept Terms of Service",
        "description": "Records ToS acceptance for a checkout session. Must be called before a checkout can be finalized.",
        "operationId": "tosAccept",
        "tags": ["Billing"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TosAcceptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ToS accepted"
          },
          "400": {
            "description": "Invalid session or already accepted"
          }
        }
      }
    },
    "/v1/billing/checkout/create": {
      "post": {
        "summary": "Create a checkout session",
        "description": "Creates a server-side one-time checkout session for the Hosted Card Fields flow. Returns a session ID and PayPal client token. Requires Altcha proof-of-work.",
        "operationId": "checkoutCreate",
        "tags": ["Billing"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckoutCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout session created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string"
                    },
                    "client_token": {
                      "type": "string",
                      "description": "PayPal client token for the Hosted Card Fields widget"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/v1/billing/checkout/finalize": {
      "post": {
        "summary": "Finalize a checkout (capture payment)",
        "description": "Captures the PayPal order created by the Hosted Card Fields flow and provisions the purchased tier token.",
        "operationId": "checkoutFinalize",
        "tags": ["Billing"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["session_id", "order_id"],
                "properties": {
                  "session_id": {
                    "type": "string"
                  },
                  "order_id": {
                    "type": "string",
                    "description": "PayPal order ID from the Hosted Card Fields widget"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment captured — token provisioned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "type": "string",
                      "description": "Provisioned Bearer token for the purchased tier"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request or capture failed"
          }
        }
      }
    },
    "/v1/billing/subscribe": {
      "post": {
        "summary": "Initiate PayPal subscription",
        "description": "Starts a PayPal Subscriptions v1 flow for the given tier. Returns a PayPal approval URL to redirect the customer to.",
        "operationId": "subscribe",
        "tags": ["Billing"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscribeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription flow initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "approval_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "PayPal approval URL — redirect the customer here"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unknown tier or PayPal error"
          }
        }
      }
    },
    "/v1/billing/cancel": {
      "post": {
        "summary": "Cancel active subscription",
        "description": "Cancels the PayPal subscription associated with the authenticated token. Access is revoked at period end.",
        "operationId": "cancelSubscription",
        "tags": ["Billing"],
        "security": [{"bearerAuth": []}],
        "responses": {
          "200": {
            "description": "Subscription cancellation queued"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "No active subscription found"
          }
        }
      }
    },
    "/v1/billing/refunds": {
      "post": {
        "summary": "Request a refund",
        "description": "Submits a refund request within the 14-day money-back-guarantee window. Tears down active peers and revokes the token on success.",
        "operationId": "requestRefund",
        "tags": ["Billing"],
        "security": [{"bearerAuth": []}],
        "responses": {
          "200": {
            "description": "Refund issued"
          },
          "400": {
            "description": "Outside refund window or no eligible payment found"
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/billing/card/client-token": {
      "post": {
        "summary": "Get PayPal Hosted Card Fields client token",
        "description": "Issues a short-lived PayPal client token for initializing the Hosted Card Fields (HCF) widget.",
        "operationId": "hcfClientToken",
        "tags": ["Billing"],
        "responses": {
          "200": {
            "description": "Client token issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client_token": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/card/create-order": {
      "post": {
        "summary": "Create a PayPal order (HCF flow)",
        "description": "Creates a PayPal order for the Hosted Card Fields one-time purchase flow.",
        "operationId": "hcfCreateOrder",
        "tags": ["Billing"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tier"],
                "properties": {
                  "tier": {
                    "type": "string",
                    "enum": ["micro", "spark", "launch", "pulse", "pulse_ipv4", "relay"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "order_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/card/capture-order": {
      "post": {
        "summary": "Capture a PayPal order (HCF flow)",
        "description": "Captures the authorized PayPal HCF order and provisions the purchased tier token.",
        "operationId": "hcfCaptureOrder",
        "tags": ["Billing"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["order_id"],
                "properties": {
                  "order_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order captured — token provisioned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/altcha/challenge": {
      "get": {
        "summary": "Get Altcha proof-of-work challenge",
        "description": "Returns a self-hosted Altcha challenge for use with the <altcha-widget>. Required before calling /v1/signup/free or /v1/billing/checkout/create.",
        "operationId": "altchaChallenge",
        "tags": ["Public"],
        "responses": {
          "200": {
            "description": "Altcha challenge payload",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Altcha challenge object per the Altcha spec"
                }
              }
            }
          }
        }
      }
    },
    "/v1/forensics": {
      "post": {
        "summary": "Submit a forensics report",
        "description": "Submits a signed attestation report for the authenticated peer. Used by the agent for three-factor attestation.",
        "operationId": "submitForensics",
        "tags": ["Agent"],
        "security": [{"bearerAuth": []}],
        "responses": {
          "200": {
            "description": "Accepted"
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/forensics/revoke-self": {
      "post": {
        "summary": "Self-revoke via forensics report",
        "description": "Agent-initiated self-revocation when integrity checks fail.",
        "operationId": "forensicsRevokeSelf",
        "tags": ["Agent"],
        "security": [{"bearerAuth": []}],
        "responses": {
          "200": {
            "description": "Token revoked"
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/account/export": {
      "post": {
        "summary": "Request DSAR data export",
        "description": "Queues a GDPR/CCPA data subject access request export. The export is emailed to the account address.",
        "operationId": "accountExport",
        "tags": ["Account"],
        "responses": {
          "202": {
            "description": "Export queued"
          }
        }
      }
    },
    "/v1/account/delete": {
      "post": {
        "summary": "Request account deletion",
        "description": "Initiates an account deletion request (right to erasure). Cancels any active subscription and tears down all peers.",
        "operationId": "accountDelete",
        "tags": ["Account"],
        "responses": {
          "202": {
            "description": "Deletion queued"
          }
        }
      }
    },
    "/v1/support/contact": {
      "post": {
        "summary": "Submit a support contact form",
        "description": "Sends a support message. Rate-limited per source IP.",
        "operationId": "supportContact",
        "tags": ["Public"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "message"],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Message received"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Public",
      "description": "Unauthenticated endpoints"
    },
    {
      "name": "Auth",
      "description": "Account creation and authentication"
    },
    {
      "name": "Peers",
      "description": "WireGuard peer registration and management"
    },
    {
      "name": "Tokens",
      "description": "API token management"
    },
    {
      "name": "Billing",
      "description": "PayPal subscriptions, one-time purchases, and refunds"
    },
    {
      "name": "Agent",
      "description": "Agent-specific endpoints (attestation, forensics)"
    },
    {
      "name": "Account",
      "description": "GDPR/CCPA data subject rights"
    }
  ]
}
