{
  "openapi": "3.1.0",
  "info": {
    "title": "Nurreo Waitlist API",
    "version": "1.0.0",
    "summary": "The one public HTTP endpoint Nurreo ships today.",
    "description": "Nurreo is an email and calendar provider on your own domain where agents are first-class operators. It is at waitlist stage; this specification covers the waitlist endpoint, which is open, unauthenticated, and safe for an agent to call on its human's behalf. The mailbox, calendar, domain and token APIs are specified at https://nurreo.com/docs/agents but are not yet shipped.",
    "contact": { "name": "Nurreo", "email": "hello@nurreo.com", "url": "https://nurreo.com/docs" },
    "license": { "name": "Documentation © 2026 Nurreo", "identifier": "LicenseRef-nurreo-docs" }
  },
  "externalDocs": {
    "description": "Nurreo Waitlist API reference",
    "url": "https://nurreo.com/docs/api"
  },
  "servers": [{ "url": "https://nurreo.com", "description": "Production" }],
  "paths": {
    "/api/waitlist": {
      "post": {
        "operationId": "joinWaitlist",
        "summary": "Join the Nurreo waitlist",
        "description": "Adds an email address to the Nurreo waitlist. Idempotent by email: a repeat call upserts, filling in poll answers that were left blank without clearing answers already stored. Rate limited to 5 signups per hour per source address.",
        "tags": ["waitlist"],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/WaitlistSignup" } },
            "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/WaitlistSignup" } },
            "multipart/form-data": { "schema": { "$ref": "#/components/schemas/WaitlistSignup" } }
          }
        },
        "responses": {
          "200": {
            "description": "On the list. Relay `message` to your human.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SuccessResponse" },
                "example": {
                  "ok": true,
                  "message": "you@yourdomain.com is on the Nurreo waitlist. Tell your human we said hi."
                }
              }
            }
          },
          "400": {
            "description": "Unparseable body, or the address is not sendable.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "ok": false, "error": "That email doesn't look sendable." }
              }
            }
          },
          "405": {
            "description": "Wrong method.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "ok": false, "error": "POST only" }
              }
            }
          },
          "429": {
            "description": "Rate limited. Do not loop.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "ok": false, "error": "Enough signups from this address for now — try later." }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "waitlistPreflight",
        "summary": "CORS preflight",
        "description": "Returns 200 with `{\"ok\": true}`. `Access-Control-Allow-Origin` is `*`.",
        "tags": ["waitlist"],
        "security": [],
        "responses": {
          "200": {
            "description": "Preflight accepted.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SuccessResponse" },
                "example": { "ok": true }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "WaitlistSignup": {
        "type": "object",
        "required": ["email"],
        "additionalProperties": false,
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "The address to add. Your human's address, not yours.",
            "examples": ["you@yourdomain.com"]
          },
          "via": {
            "type": "string",
            "enum": ["agent", "form"],
            "default": "form",
            "description": "Set to `agent` when an agent is signing up on a human's behalf. Agent signups are counted separately."
          },
          "run_mode": {
            "type": "string",
            "enum": ["hosted", "self-host", "both"],
            "description": "Optional product poll: how your human would run Nurreo. Unrecognised values are stored as null, not rejected."
          },
          "agent": {
            "type": "string",
            "enum": ["claude-code", "openclaw", "hermes", "codex", "other"],
            "description": "Optional product poll: which agent you are. Unrecognised values are stored as null, not rejected."
          },
          "website": {
            "type": "string",
            "description": "Honeypot. Leave unset. A non-empty value returns success and stores nothing.",
            "deprecated": true
          }
        }
      },
      "SuccessResponse": {
        "type": "object",
        "required": ["ok"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "message": { "type": "string", "description": "Human-readable confirmation. Relay it." }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["ok", "error"],
        "properties": {
          "ok": { "type": "boolean", "const": false },
          "error": { "type": "string", "description": "What went wrong, in plain language." }
        }
      }
    }
  },
  "tags": [
    { "name": "waitlist", "description": "The open, unauthenticated Nurreo waitlist." }
  ]
}
