{
  "openapi": "3.1.0",
  "info": {
    "title": "bygga. waitlist API",
    "version": "1.0.0",
    "summary": "Join the waitlist for new IKEA 3D assembly guides.",
    "description": "One public endpoint that adds an email address to the bygga. waitlist. Subscribers get one email when a new guide launches. No authentication. Guide content itself is available as Markdown by requesting any page with `Accept: text/markdown`.",
    "contact": { "name": "bygga.", "url": "https://ikeahelp.com/about/" }
  },
  "servers": [{ "url": "https://ikeahelp.com" }],
  "externalDocs": { "description": "API docs", "url": "https://ikeahelp.com/docs/" },
  "paths": {
    "/api/waitlist": {
      "post": {
        "operationId": "joinWaitlist",
        "summary": "Add an email address to the waitlist",
        "description": "Adds the email to the waitlist. Signing up twice is safe: the second call returns `already: true`. Send `Accept: application/json` to get JSON back; without it, the endpoint redirects (303) to a thank-you page, so it also works as a plain HTML form action.",
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Use `application/json` for a JSON response instead of a redirect.",
            "schema": { "type": "string", "example": "application/json" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/WaitlistRequest" } },
            "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/WaitlistRequest" } }
          }
        },
        "responses": {
          "200": {
            "description": "The email is on the waitlist.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WaitlistSuccess" },
                "example": { "ok": true, "already": false }
              }
            }
          },
          "303": { "description": "Redirect to /thanks/ (when Accept is not application/json)." },
          "400": {
            "description": "The email address is missing or invalid.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": {
                  "ok": false,
                  "code": "invalid_email",
                  "error": "That email doesn’t look right. Check it and try again.",
                  "hint": "Send a valid address in the `email` field."
                }
              }
            }
          },
          "405": {
            "description": "Only POST is allowed.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          },
          "500": {
            "description": "Server error. Safe to retry.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "WaitlistRequest": {
        "type": "object",
        "required": ["email"],
        "properties": {
          "email": { "type": "string", "format": "email", "maxLength": 254, "description": "Address to notify." },
          "source": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[a-zA-Z0-9-]*$",
            "description": "Optional label for where the signup came from, for example `home`."
          }
        }
      },
      "WaitlistSuccess": {
        "type": "object",
        "required": ["ok", "already"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "already": { "type": "boolean", "description": "True if the email was already on the list." }
        }
      },
      "Error": {
        "type": "object",
        "required": ["ok", "code", "error"],
        "properties": {
          "ok": { "type": "boolean", "const": false },
          "code": {
            "type": "string",
            "enum": ["invalid_email", "method_not_allowed", "not_found", "server_error"],
            "description": "Stable machine-readable error code."
          },
          "error": { "type": "string", "description": "Human-readable message." },
          "hint": { "type": "string", "description": "How to fix the request." }
        }
      }
    }
  }
}
