{
  "openapi": "3.1.0",
  "info": {
    "title": "Pixie site API",
    "description": "The two write endpoints behind pixie.sociofabric.com: join the waitlist, and the site's first-party telemetry beacon. Both are anonymous; no authentication exists (see /auth.md). Reading the site needs no API — every page has a markdown mirror (append .md, or send Accept: text/markdown). Errors are always JSON, including unknown /api/* paths. Rate limiting: none beyond Cloudflare's ordinary edge protections; the endpoints are small, be reasonable.",
    "version": "1.1.0"
  },
  "servers": [{ "url": "https://pixie.sociofabric.com" }],
  "paths": {
    "/api/waitlist": {
      "post": {
        "summary": "Request access — join the Pixie waitlist",
        "description": "Idempotent per email: repeat posts refresh the existing record and never error, so retries are always safe. An Idempotency-Key header is accepted but unnecessary. Agents: send an email only with the user's explicit consent.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": { "type": "string" },
            "description": "Accepted for client compatibility; the endpoint is naturally idempotent per email, so the key is not needed for safety."
          }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": {
            "type": "object", "required": ["email"],
            "properties": {
              "email": { "type": "string", "format": "email", "maxLength": 254 },
              "source": { "type": "string", "enum": ["home", "features", "tech", "philosophy", "thesis", "unknown"] }
            } } } }
        },
        "responses": {
          "200": { "description": "Recorded (repeat signups refresh, never error)" },
          "400": { "description": "Malformed email or body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/metric": {
      "post": {
        "summary": "First-party telemetry beacon (cookieless, ephemeral per-load id)",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": {
            "type": "object", "required": ["pid", "path"],
            "properties": {
              "pid": { "type": "string", "maxLength": 64 },
              "path": { "type": "string", "maxLength": 128 },
              "ref": { "type": "string", "maxLength": 256 },
              "dwell": { "type": "object", "additionalProperties": { "type": "integer" } },
              "cards": { "type": "array", "items": { "type": "string" } }
            } } } }
        },
        "responses": {
          "200": { "description": "Recorded" },
          "400": { "description": "Malformed body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["status", "message"],
            "properties": {
              "status": { "type": "integer", "description": "HTTP status code, mirrored in the body" },
              "message": { "type": "string" }
            }
          }
        },
        "description": "Every error under /api/* returns this JSON envelope — including 404s for endpoints that do not exist."
      }
    }
  }
}
