{
  "openapi": "3.1.0",
  "info": {
    "title": "InviteWaale AI API",
    "version": "1.0.0",
    "description": "AI-friendly REST API for creating invites, RSVP forms, fetching event analytics, and sending reminders. Authenticate using an API key (recommended) or Supabase JWT in the Authorization header. Also available as an MCP server at /api/mcp for native AI assistant integration."
  },
  "servers": [
    {
      "url": "https://invitewaale.com",
      "description": "Production"
    },
    {
      "url": "http://localhost:3000",
      "description": "Local development"
    }
  ],
  "paths": {
    "/api/ai/create-event": {
      "post": {
        "operationId": "createEvent",
        "summary": "Create a new invite event",
        "description": "Creates a new event with a public invite page and RSVP link. The event is published immediately.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["title", "host_name", "event_date"],
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Event title, e.g. \"Misha's 5th Birthday\""
                  },
                  "host_name": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Name of the host, e.g. \"Priya Sharma\""
                  },
                  "event_date": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                    "description": "Date in YYYY-MM-DD format"
                  },
                  "event_time": {
                    "type": "string",
                    "nullable": true,
                    "description": "Time string, e.g. \"18:00\" or \"6 PM\""
                  },
                  "location": {
                    "type": "string",
                    "nullable": true,
                    "description": "Venue or address"
                  },
                  "description": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 2000,
                    "description": "Short event description"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "const": true },
                    "event_id": { "type": "string", "format": "uuid" },
                    "invite_url": { "type": "string", "format": "uri" },
                    "rsvp_url": { "type": "string", "format": "uri" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/ai/create-rsvp-form": {
      "post": {
        "operationId": "createRsvpForm",
        "summary": "Create a standalone RSVP form for an event",
        "description": "Creates an embeddable RSVP form linked to an existing event. Returns a shareable URL and iframe embed code.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["event_id"],
                "properties": {
                  "event_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID of the invite event"
                  },
                  "collect_phone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Whether to collect phone numbers"
                  },
                  "collect_email": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether to collect email addresses"
                  },
                  "max_guests": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "default": 100,
                    "description": "Maximum number of guests"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "RSVP form created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "const": true },
                    "rsvp_url": { "type": "string", "format": "uri" },
                    "embed_code": { "type": "string", "description": "HTML iframe snippet" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/ai/event-summary": {
      "get": {
        "operationId": "getEventSummary",
        "summary": "Get RSVP analytics for an event",
        "description": "Returns guest counts grouped by RSVP status. Works with both invite-based and standalone RSVP events.",
        "security": [{ "bearerAuth": [] }],
        "parameters": [
          {
            "name": "event_id",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "UUID of the event"
          }
        ],
        "responses": {
          "200": {
            "description": "Event summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "const": true },
                    "event_id": { "type": "string", "format": "uuid" },
                    "title": { "type": "string" },
                    "event_date": { "type": "string" },
                    "total_guests": { "type": "integer" },
                    "rsvp_yes": { "type": "integer" },
                    "rsvp_no": { "type": "integer" },
                    "rsvp_maybe": { "type": "integer" },
                    "pending": { "type": "integer" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/ai/send-reminders": {
      "post": {
        "operationId": "sendReminders",
        "summary": "Send reminder emails to pending guests",
        "description": "Triggers reminder emails to all guests who haven't RSVPed yet (status = pending) and have an email address on file.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["event_id"],
                "properties": {
                  "event_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID of the event"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reminders sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "const": true },
                    "reminders_sent": { "type": "integer" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/ai/keys": {
      "get": {
        "operationId": "listApiKeys",
        "summary": "List your active API keys",
        "description": "Returns all active (non-revoked) API keys for the authenticated user. Requires cookie-based session auth (dashboard).",
        "security": [{ "bearerAuth": [] }],
        "responses": {
          "200": {
            "description": "Keys listed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "const": true },
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string", "format": "uuid" },
                          "name": { "type": "string" },
                          "key_prefix": { "type": "string", "description": "First 10 chars, e.g. iwk_a3f8b2" },
                          "last_used_at": { "type": "string", "format": "date-time", "nullable": true },
                          "expires_at": { "type": "string", "format": "date-time", "nullable": true },
                          "created_at": { "type": "string", "format": "date-time" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "post": {
        "operationId": "createApiKey",
        "summary": "Generate a new API key",
        "description": "Creates a new API key. The plaintext key is returned ONLY in this response — save it immediately. Max 5 active keys per user.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": { "type": "string", "maxLength": 100, "description": "Human-readable label, e.g. 'ChatGPT Plugin'" },
                  "expires_in_days": { "type": "integer", "nullable": true, "description": "Days until expiry. null = never expires." }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Key created — plaintext shown once",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "const": true },
                    "key": {
                      "type": "object",
                      "properties": {
                        "id": { "type": "string", "format": "uuid" },
                        "name": { "type": "string" },
                        "plaintext": { "type": "string", "description": "Full API key — save immediately! Starts with iwk_" },
                        "key_prefix": { "type": "string" },
                        "expires_at": { "type": "string", "format": "date-time", "nullable": true },
                        "created_at": { "type": "string", "format": "date-time" }
                      }
                    },
                    "warning": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "delete": {
        "operationId": "revokeApiKey",
        "summary": "Revoke an API key",
        "description": "Soft-deletes a key so it can no longer be used for authentication. Pass key_id as query param or in the JSON body.",
        "security": [{ "bearerAuth": [] }],
        "parameters": [
          {
            "name": "key_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "The ID of the key to revoke. Can also be sent in the request body."
          }
        ],
        "responses": {
          "200": {
            "description": "Key revoked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "const": true },
                    "revoked": { "type": "string", "format": "uuid" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT or API Key",
        "description": "Pass either an InviteWaale API key (starts with 'iwk_') or a Supabase JWT access token. API keys are recommended — generate one at /api/ai/keys."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Validation error",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": { "type": "boolean", "const": false },
                "error": { "type": "string" }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid JWT",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": { "type": "boolean", "const": false },
                "error": { "type": "string" }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Event not found or access denied",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": { "type": "boolean", "const": false },
                "error": { "type": "string" }
              }
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": { "type": "string" }
              }
            }
          }
        }
      },
      "InternalError": {
        "description": "Server error",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": { "type": "boolean", "const": false },
                "error": { "type": "string" }
              }
            }
          }
        }
      }
    }
  }
}
