{
  "openapi": "3.1.0",
  "info": {"title": "Gathrr Registration and Free Ticket API", "version": "1.0.0", "description": "Node-owned dynamic registration and free-ticket issuance. Paid registration is unavailable until payment verification and reconciliation are configured."},
  "servers": [{"url": "/api/v1"}],
  "paths": {
    "/organizations/{organization_id}/events/{event_id}/registration-form": {
      "parameters": [{"$ref": "#/components/parameters/OrganizationId"}, {"$ref": "#/components/parameters/EventId"}],
      "get": {"operationId": "getRegistrationForm", "security": [{"BrowserSession": []}], "responses": {"200": {"description": "Current event registration form", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FormResponse"}}}}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}}},
      "put": {"operationId": "saveRegistrationForm", "security": [{"BrowserSession": [], "CsrfToken": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FormInput"}}}}, "responses": {"200": {"description": "Saved form revision"}, "409": {"$ref": "#/components/responses/Conflict"}, "422": {"$ref": "#/components/responses/Invalid"}}}
    },
    "/organizations/{organization_id}/events/{event_id}/registration-categories": {
      "parameters": [{"$ref": "#/components/parameters/OrganizationId"}, {"$ref": "#/components/parameters/EventId"}],
      "get": {"operationId": "listRegistrationCategories", "security": [{"BrowserSession": []}], "responses": {"200": {"description": "Event-specific attendee categories and inventory"}}},
      "post": {"operationId": "createRegistrationCategory", "security": [{"BrowserSession": [], "CsrfToken": []}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CategoryInput"}}}}, "responses": {"201": {"description": "Category created"}, "403": {"$ref": "#/components/responses/Forbidden"}, "409": {"$ref": "#/components/responses/Conflict"}, "422": {"$ref": "#/components/responses/Invalid"}}}
    },
    "/organizations/{organization_id}/events/{event_id}/registrations": {
      "parameters": [{"$ref": "#/components/parameters/OrganizationId"}, {"$ref": "#/components/parameters/EventId"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}}, {"name": "cursor", "in": "query", "schema": {"type": "string", "maxLength": 512}}],
      "get": {"operationId": "listAttendees", "security": [{"BrowserSession": []}], "responses": {"200": {"description": "Attendee records allowed to the authorized organizer or registration staff"}}}
    },
    "/organizations/{organization_id}/events/{event_id}/tickets/{ticket_id}/revoke": {
      "parameters": [{"$ref": "#/components/parameters/OrganizationId"}, {"$ref": "#/components/parameters/EventId"}, {"name": "ticket_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}],
      "post": {"operationId": "revokeTicket", "security": [{"BrowserSession": [], "CsrfToken": []}], "responses": {"200": {"description": "Ticket revoked idempotently and audit recorded"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"$ref": "#/components/responses/Conflict"}}}
    },
    "/public/events/{slug}/registration-categories": {
      "get": {"operationId": "listPublicRegistrationCategories", "security": [], "parameters": [{"$ref": "#/components/parameters/Slug"}], "responses": {"200": {"description": "Published event categories with remaining capacity"}, "404": {"$ref": "#/components/responses/NotFound"}}}
    },
    "/public/events/{slug}/registration-form": {
      "get": {"operationId": "getPublicRegistrationForm", "security": [], "parameters": [{"$ref": "#/components/parameters/Slug"}], "responses": {"200": {"description": "Current published registration form with conditional fields"}, "404": {"$ref": "#/components/responses/NotFound"}}}
    },
    "/public/events/{slug}/registrations": {
      "post": {"operationId": "registerAttendee", "security": [{"CsrfToken": []}, {"IntegrationApiKey": []}], "parameters": [{"$ref": "#/components/parameters/Slug"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegistrationInput"}}}}, "responses": {"201": {"description": "Confirmed free registration and signed QR credential"}, "401": {"description": "Integration key invalid, expired, revoked, or not scoped to this event"}, "409": {"$ref": "#/components/responses/Conflict"}, "422": {"$ref": "#/components/responses/Invalid"}, "503": {"description": "Paid registration or event service is unavailable"}}}
    }
  },
  "components": {
    "securitySchemes": {"BrowserSession": {"type": "apiKey", "in": "cookie", "name": "gathrr_access"}, "CsrfToken": {"type": "apiKey", "in": "header", "name": "X-CSRF-Token"}, "IntegrationApiKey": {"type": "apiKey", "in": "header", "name": "X-Gathrr-API-Key", "description": "Event-scoped server-side key with registration.write permission. Never expose in browser code."}},
    "parameters": {
      "OrganizationId": {"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}},
      "EventId": {"name": "event_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}},
      "Slug": {"name": "slug", "in": "path", "required": true, "schema": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"}},
      "IdempotencyKey": {"name": "Idempotency-Key", "in": "header", "required": true, "schema": {"type": "string", "minLength": 8, "maxLength": 128}}
    },
    "responses": {"Forbidden": {"description": "Permission or CSRF rejected"}, "NotFound": {"description": "Resource not found"}, "Conflict": {"description": "Inventory, duplicate registration or idempotency conflict"}, "Invalid": {"description": "Request validation failed"}},
    "schemas": {
      "FormField": {"type": "object", "additionalProperties": false, "required": ["key", "label", "type"], "properties": {"key": {"type": "string", "pattern": "^[a-z][a-z0-9_]{1,39}$"}, "label": {"type": "string", "maxLength": 100}, "type": {"enum": ["text", "email", "phone", "number", "select", "checkbox"]}, "required": {"type": "boolean", "default": false}, "options": {"type": "array", "items": {"type": "string"}, "maxItems": 100}, "max_length": {"type": "integer", "minimum": 1, "maximum": 2000}, "visible_when": {"type": "object", "additionalProperties": false, "required": ["field", "equals"], "properties": {"field": {"type": "string"}, "equals": {"oneOf": [{"type": "string"}, {"type": "number"}, {"type": "boolean"}]}}}}},
      "FormInput": {"type": "object", "additionalProperties": false, "required": ["fields"], "properties": {"version": {"type": "integer", "minimum": 0}, "fields": {"type": "array", "maxItems": 50, "items": {"$ref": "#/components/schemas/FormField"}}}},
      "FormResponse": {"type": "object", "required": ["data"], "properties": {"data": {"type": "object", "properties": {"id": {"type": "string", "format": "uuid"}, "event_id": {"type": "string", "format": "uuid"}, "organization_id": {"type": "string", "format": "uuid"}, "version": {"type": "integer"}, "fields": {"type": "array", "items": {"$ref": "#/components/schemas/FormField"}}}}}},
      "CategoryInput": {"type": "object", "additionalProperties": false, "required": ["code", "label", "price_minor", "capacity"], "properties": {"code": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"}, "label": {"type": "string", "minLength": 2, "maxLength": 100}, "description": {"type": "string", "maxLength": 1000}, "price_minor": {"type": "integer", "minimum": 0}, "currency": {"type": "string", "pattern": "^[A-Z]{3}$", "default": "INR"}, "capacity": {"type": "integer", "minimum": 1, "maximum": 1000000}}},
      "RegistrationInput": {"type": "object", "additionalProperties": false, "required": ["category_code", "name", "email"], "properties": {"category_code": {"type": "string"}, "name": {"type": "string", "minLength": 2, "maxLength": 120}, "email": {"type": "string", "format": "email"}, "phone": {"type": "string", "pattern": "^\\+?[1-9]\\d{7,14}$"}, "answers": {"type": "object", "additionalProperties": true}}}
    }
  }
}
