{
  "openapi": "3.1.0",
  "info": {
    "title": "spire API",
    "version": "0.1.0",
    "description": "Official REST API reference for spire — an AI-powered project management platform built for Hungarian SMBs.\n\n**Authentication.** Most endpoints require a JWT access token, sent either as `Authorization: Bearer <token>` or via the `spire-token` HttpOnly cookie (used internally for Next.js SSR; clients should use the bearer header). Public endpoints (register / login / refresh / health / invitation preview) have empty `security` arrays.\n\n**Workspace scoping.** Routes under `/api/v/*` are automatically scoped to the active workspace derived from the JWT — there is no `workspaceId` path or query parameter. Switch workspaces via `POST /api/workspaces/:id/switch` (returns a fresh token pair).\n\n**API tokens** are generated under `Settings → API Tokens` (owner or admin role required). Tokens scope to a single workspace and inherit the issuing user's permissions."
  },
  "servers": [
    {
      "url": "https://spire.hu",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "AI"
    },
    {
      "name": "API Tokens"
    },
    {
      "name": "Attachments"
    },
    {
      "name": "Audit Logs"
    },
    {
      "name": "Auth"
    },
    {
      "name": "Custom Fields"
    },
    {
      "name": "Cycles"
    },
    {
      "name": "Favorites"
    },
    {
      "name": "Feedback"
    },
    {
      "name": "GDPR"
    },
    {
      "name": "Health"
    },
    {
      "name": "Home"
    },
    {
      "name": "Import/Export"
    },
    {
      "name": "Invitations"
    },
    {
      "name": "Issues"
    },
    {
      "name": "Labels"
    },
    {
      "name": "Lookup"
    },
    {
      "name": "Members"
    },
    {
      "name": "Notifications"
    },
    {
      "name": "Profile"
    },
    {
      "name": "Projects"
    },
    {
      "name": "Search"
    },
    {
      "name": "Sections"
    },
    {
      "name": "Teams"
    },
    {
      "name": "Webhooks"
    },
    {
      "name": "Workspace invoices"
    },
    {
      "name": "Workspaces"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT access token (15 min) issued by `POST /auth/login`."
      },
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "spire-token",
        "description": "HttpOnly cookie mirror of the access token (set by login). Used by Next.js SSR."
      }
    },
    "schemas": {
      "AddDependencyInput": {
        "type": "object",
        "properties": {
          "dependsOnId": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "blocks",
              "blocked_by",
              "related"
            ]
          }
        },
        "required": [
          "dependsOnId",
          "type"
        ],
        "additionalProperties": false
      },
      "AddProjectMemberInput": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "userId"
        ],
        "additionalProperties": false
      },
      "AddProjectTeamInput": {
        "type": "object",
        "properties": {
          "teamId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "teamId"
        ],
        "additionalProperties": false
      },
      "AiSubtasksInput": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "description": {
            "type": "string",
            "maxLength": 10000
          },
          "existing": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 500
            },
            "maxItems": 30
          }
        },
        "required": [
          "title"
        ],
        "additionalProperties": false
      },
      "AiSummaryInput": {
        "type": "object",
        "properties": {
          "entityType": {
            "type": "string",
            "enum": [
              "project",
              "issue",
              "cycle",
              "workspace",
              "team"
            ]
          },
          "data": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "entityType",
          "data"
        ],
        "additionalProperties": false
      },
      "AiTriageInput": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50000
          }
        },
        "required": [
          "text"
        ],
        "additionalProperties": false
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "name": {
                "type": "string",
                "nullable": true
              },
              "avatarUrl": {
                "type": "string",
                "format": "uri",
                "nullable": true
              },
              "workspaceId": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "workspaceRole": {
                "type": "string",
                "enum": [
                  "owner",
                  "admin",
                  "member",
                  "guest"
                ],
                "nullable": true
              }
            },
            "required": [
              "id",
              "email",
              "name",
              "avatarUrl",
              "workspaceId",
              "workspaceRole"
            ],
            "additionalProperties": false
          },
          "accessToken": {
            "type": "string",
            "description": "JWT access token (15 min TTL)."
          },
          "refreshToken": {
            "type": "string",
            "description": "Refresh token (7 day TTL, single-use, rotated on each refresh)."
          }
        },
        "required": [
          "user",
          "accessToken",
          "refreshToken"
        ],
        "additionalProperties": false
      },
      "BulkInviteInput": {
        "type": "object",
        "properties": {
          "invites": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "email": {
                  "type": "string",
                  "format": "email"
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "admin",
                    "member",
                    "guest"
                  ]
                }
              },
              "required": [
                "email",
                "role"
              ],
              "additionalProperties": false
            },
            "minItems": 1,
            "maxItems": 50
          }
        },
        "required": [
          "invites"
        ],
        "additionalProperties": false
      },
      "BulkIssueInput": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "update_status",
              "update_priority",
              "update_assignee",
              "add_label",
              "delete"
            ]
          },
          "issueIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "minItems": 1
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "action",
          "issueIds"
        ],
        "additionalProperties": false
      },
      "ChangePasswordInput": {
        "type": "object",
        "properties": {
          "currentPassword": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "newPassword": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          }
        },
        "required": [
          "currentPassword",
          "newPassword"
        ],
        "additionalProperties": false
      },
      "CommentInput": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50000
          }
        },
        "required": [
          "body"
        ],
        "additionalProperties": false
      },
      "CommentReactionInput": {
        "type": "object",
        "properties": {
          "emoji": {
            "type": "string",
            "minLength": 1,
            "maxLength": 32
          }
        },
        "required": [
          "emoji"
        ],
        "additionalProperties": false
      },
      "ConnectGoogleInput": {
        "type": "object",
        "properties": {
          "googleId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 255
          },
          "avatarUrl": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048
          }
        },
        "required": [
          "googleId"
        ],
        "additionalProperties": false
      },
      "CreateApiTokenInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "maxItems": 50
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "CreateCustomFieldInput": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "number",
              "select",
              "multi_select",
              "date",
              "checkbox",
              "url",
              "email"
            ]
          },
          "options": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "value": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "color": {
                  "type": "string",
                  "pattern": "^#[0-9a-fA-F]{6}$"
                }
              },
              "required": [
                "label",
                "value"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "projectId",
          "name",
          "type"
        ],
        "additionalProperties": false
      },
      "CreateCycleInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "startDate": {
            "type": "string"
          },
          "endDate": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "CreateIssueInput": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "sectionId": {
            "type": "string",
            "format": "uuid"
          },
          "parentId": {
            "type": "string",
            "format": "uuid"
          },
          "cycleId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "status": {
            "type": "string",
            "enum": [
              "backlog",
              "todo",
              "in_progress",
              "in_review",
              "done",
              "cancelled"
            ],
            "default": "backlog"
          },
          "priority": {
            "type": "string",
            "enum": [
              "urgent",
              "high",
              "medium",
              "low",
              "none"
            ],
            "default": "none"
          },
          "type": {
            "type": "string",
            "enum": [
              "task",
              "bug",
              "request",
              "idea"
            ],
            "default": "task"
          },
          "assigneeId": {
            "type": "string",
            "format": "uuid"
          },
          "estimate": {
            "type": "number",
            "minimum": 0
          },
          "dueDate": {
            "type": "string",
            "maxLength": 32
          },
          "labelIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "default": []
          }
        },
        "required": [
          "projectId",
          "title"
        ],
        "additionalProperties": false
      },
      "CreateLabelInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          }
        },
        "required": [
          "name",
          "color"
        ],
        "additionalProperties": false
      },
      "CreateProjectInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "key": {
            "type": "string",
            "minLength": 2,
            "maxLength": 10
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          },
          "icon": {
            "type": "string",
            "maxLength": 50
          },
          "isPrivate": {
            "type": "boolean",
            "default": true
          },
          "leadId": {
            "type": "string",
            "format": "uuid"
          },
          "startDate": {
            "type": "string"
          },
          "targetDate": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "color"
        ],
        "additionalProperties": false
      },
      "CreateRecurringIssueInput": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "status": {
            "type": "string",
            "enum": [
              "backlog",
              "todo",
              "in_progress",
              "in_review",
              "done",
              "cancelled"
            ],
            "default": "backlog"
          },
          "priority": {
            "type": "string",
            "enum": [
              "urgent",
              "high",
              "medium",
              "low",
              "none"
            ],
            "default": "none"
          },
          "type": {
            "type": "string",
            "enum": [
              "task",
              "bug",
              "request",
              "idea"
            ],
            "default": "task"
          },
          "assigneeId": {
            "type": "string",
            "format": "uuid"
          },
          "frequency": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "biweekly",
              "monthly",
              "quarterly"
            ]
          },
          "cronExpression": {
            "type": "string",
            "maxLength": 100
          },
          "nextRunAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "projectId",
          "title",
          "frequency"
        ],
        "additionalProperties": false
      },
      "CreateSectionInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "CreateTeamInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "identifier": {
            "type": "string",
            "minLength": 2,
            "maxLength": 10
          },
          "description": {
            "type": "string",
            "maxLength": 5000
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          }
        },
        "required": [
          "name",
          "identifier",
          "color"
        ],
        "additionalProperties": false
      },
      "CreateWebhookInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "issue.created",
                "issue.updated",
                "issue.deleted",
                "issue.status_changed",
                "project.created",
                "project.updated",
                "cycle.started",
                "cycle.completed",
                "member.invited",
                "member.removed"
              ]
            },
            "minItems": 1,
            "maxItems": 10
          }
        },
        "required": [
          "name",
          "url",
          "events"
        ],
        "additionalProperties": false
      },
      "CreateWorkspaceInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "slug": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100,
            "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
          },
          "timezone": {
            "type": "string",
            "maxLength": 100,
            "default": "Europe/Budapest"
          },
          "currency": {
            "type": "string",
            "enum": [
              "HUF",
              "EUR",
              "USD"
            ],
            "default": "HUF"
          }
        },
        "required": [
          "name",
          "slug"
        ],
        "additionalProperties": false
      },
      "Disable2faInput": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^\\d{6}$"
          },
          "currentPassword": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "required": [
          "code",
          "currentPassword"
        ],
        "additionalProperties": false
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine code (e.g. `NOT_FOUND`, `VALIDATION_ERROR`)."
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "ForgotPasswordInput": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          }
        },
        "required": [
          "email"
        ],
        "additionalProperties": false
      },
      "GoogleAuthInput": {
        "type": "object",
        "properties": {
          "credential": {
            "type": "string",
            "description": "Google ID token from One Tap / popup flow."
          },
          "userInfo": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "name": {
                "type": "string"
              },
              "picture": {
                "type": "string",
                "format": "uri"
              },
              "googleId": {
                "type": "string"
              }
            },
            "required": [
              "email",
              "name",
              "googleId"
            ],
            "additionalProperties": false,
            "description": "Pre-validated Google profile (FedCM flow alternative to `credential`)."
          }
        },
        "additionalProperties": false
      },
      "ImportApplyInput": {
        "type": "object",
        "properties": {
          "data": {
            "description": "Workspace export JSON document (`workspaceExportSchema`)."
          },
          "options": {
            "type": "object",
            "properties": {
              "mergeStrategy": {
                "type": "string",
                "enum": [
                  "skip",
                  "overwrite"
                ],
                "default": "skip"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "ImportPreviewInput": {
        "type": "object",
        "properties": {
          "data": {
            "description": "Workspace export JSON document (`workspaceExportSchema`)."
          }
        },
        "additionalProperties": false
      },
      "InviteInput": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "member",
              "guest"
            ]
          }
        },
        "required": [
          "email",
          "role"
        ],
        "additionalProperties": false
      },
      "LoginInput": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "minLength": 1
          }
        },
        "required": [
          "email",
          "password"
        ],
        "additionalProperties": false
      },
      "LookupQuery": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "project",
              "issue",
              "cycle"
            ]
          },
          "key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          }
        },
        "required": [
          "type",
          "key"
        ],
        "additionalProperties": false
      },
      "NotificationPreferences": {
        "type": "object",
        "required": [
          "inapp_assignment",
          "inapp_status_change",
          "inapp_comment",
          "inapp_mention",
          "inapp_invitations",
          "inapp_due_date",
          "email_assignment",
          "email_status_change",
          "email_comment",
          "email_mention",
          "email_invitations",
          "email_due_date"
        ],
        "properties": {
          "inapp_assignment": {
            "type": "boolean"
          },
          "inapp_status_change": {
            "type": "boolean"
          },
          "inapp_comment": {
            "type": "boolean"
          },
          "inapp_mention": {
            "type": "boolean"
          },
          "inapp_invitations": {
            "type": "boolean"
          },
          "inapp_due_date": {
            "type": "boolean"
          },
          "email_assignment": {
            "type": "boolean"
          },
          "email_status_change": {
            "type": "boolean"
          },
          "email_comment": {
            "type": "boolean"
          },
          "email_mention": {
            "type": "boolean"
          },
          "email_invitations": {
            "type": "boolean"
          },
          "email_due_date": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "OkResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "ok"
        ],
        "additionalProperties": false
      },
      "ProfilePreferences": {
        "type": "object",
        "properties": {
          "theme": {
            "type": "string",
            "enum": [
              "light",
              "dark",
              "system"
            ]
          },
          "language": {
            "type": "string",
            "enum": [
              "hu",
              "en"
            ]
          },
          "timezone": {
            "type": "string",
            "maxLength": 100
          }
        },
        "additionalProperties": false
      },
      "RefreshInput": {
        "type": "object",
        "properties": {
          "refreshToken": {
            "type": "string",
            "minLength": 1
          }
        },
        "required": [
          "refreshToken"
        ],
        "additionalProperties": false
      },
      "RegisterInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 255
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          }
        },
        "required": [
          "name",
          "email",
          "password"
        ],
        "additionalProperties": false
      },
      "ReorderFavoritesInput": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "required": [
                "id",
                "sortOrder"
              ],
              "additionalProperties": false
            },
            "minItems": 1
          }
        },
        "required": [
          "items"
        ],
        "additionalProperties": false
      },
      "ReorderSectionsInput": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "required": [
                "id",
                "sortOrder"
              ],
              "additionalProperties": false
            },
            "minItems": 1
          }
        },
        "required": [
          "items"
        ],
        "additionalProperties": false
      },
      "ResetPasswordInput": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "minLength": 1
          },
          "password": {
            "type": "string",
            "minLength": 8
          }
        },
        "required": [
          "token",
          "password"
        ],
        "additionalProperties": false
      },
      "SetCustomFieldValueInput": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "maxLength": 10000,
            "nullable": true
          }
        },
        "required": [
          "value"
        ],
        "additionalProperties": false
      },
      "SetPasswordInput": {
        "type": "object",
        "properties": {
          "newPassword": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          }
        },
        "required": [
          "newPassword"
        ],
        "additionalProperties": false
      },
      "SubmitFeedbackInput": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "enum": [
              "bug",
              "idea",
              "question",
              "other"
            ]
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 5000
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048
          }
        },
        "required": [
          "category",
          "body"
        ],
        "additionalProperties": false
      },
      "TeamMemberAddInput": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "userId"
        ],
        "additionalProperties": false
      },
      "ToggleFavoriteInput": {
        "type": "object",
        "properties": {
          "favorableType": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "favorableId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "favorableType",
          "favorableId"
        ],
        "additionalProperties": false
      },
      "TransferOwnershipInput": {
        "type": "object",
        "properties": {
          "newOwnerId": {
            "type": "string",
            "format": "uuid"
          },
          "password": {
            "type": "string"
          }
        },
        "required": [
          "newOwnerId"
        ],
        "additionalProperties": false
      },
      "UpdateApiTokenInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "maxItems": 50
          }
        },
        "additionalProperties": false
      },
      "UpdateCustomFieldInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "options": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "value": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "color": {
                  "type": "string",
                  "pattern": "^#[0-9a-fA-F]{6}$"
                }
              },
              "required": [
                "label",
                "value"
              ],
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "UpdateCycleInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "status": {
            "type": "string",
            "enum": [
              "planned",
              "active",
              "completed"
            ]
          },
          "startDate": {
            "type": "string",
            "nullable": true
          },
          "endDate": {
            "type": "string",
            "nullable": true
          },
          "retrospective": {
            "type": "object",
            "properties": {
              "wentWell": {
                "type": "string",
                "maxLength": 500
              },
              "didntGoWell": {
                "type": "string",
                "maxLength": 500
              },
              "improvements": {
                "type": "string",
                "maxLength": 500
              }
            },
            "additionalProperties": false,
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateIssueInput": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "status": {
            "type": "string",
            "enum": [
              "backlog",
              "todo",
              "in_progress",
              "in_review",
              "done",
              "cancelled"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "urgent",
              "high",
              "medium",
              "low",
              "none"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "task",
              "bug",
              "request",
              "idea"
            ]
          },
          "assigneeId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "sectionId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "cycleId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "estimate": {
            "type": "number",
            "minimum": 0,
            "nullable": true
          },
          "dueDate": {
            "type": "string",
            "maxLength": 32,
            "nullable": true
          },
          "sortOrder": {
            "type": "number"
          },
          "labelIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "additionalProperties": false
      },
      "UpdateLabelInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          }
        },
        "additionalProperties": false
      },
      "UpdateMemberInput": {
        "type": "object",
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "member",
              "guest"
            ]
          }
        },
        "required": [
          "role"
        ],
        "additionalProperties": false
      },
      "UpdateProfileInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "jobTitle": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "preferences": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "additionalProperties": false
      },
      "UpdateProjectInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          },
          "icon": {
            "type": "string",
            "maxLength": 50,
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "planned",
              "active",
              "paused",
              "completed",
              "archived"
            ]
          },
          "isPrivate": {
            "type": "boolean"
          },
          "leadId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "startDate": {
            "type": "string",
            "nullable": true
          },
          "targetDate": {
            "type": "string",
            "nullable": true
          },
          "columnConfig": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 100
            }
          }
        },
        "additionalProperties": false
      },
      "UpdateRecurringIssueInput": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "description": {
            "type": "string",
            "maxLength": 50000
          },
          "status": {
            "type": "string",
            "enum": [
              "backlog",
              "todo",
              "in_progress",
              "in_review",
              "done",
              "cancelled"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "urgent",
              "high",
              "medium",
              "low",
              "none"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "task",
              "bug",
              "request",
              "idea"
            ]
          },
          "assigneeId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "frequency": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "biweekly",
              "monthly",
              "quarterly"
            ]
          },
          "cronExpression": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "nextRunAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateSectionInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "additionalProperties": false
      },
      "UpdateTeamInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "maxLength": 5000
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          }
        },
        "additionalProperties": false
      },
      "UpdateWebhookInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "issue.created",
                "issue.updated",
                "issue.deleted",
                "issue.status_changed",
                "project.created",
                "project.updated",
                "cycle.started",
                "cycle.completed",
                "member.invited",
                "member.removed"
              ]
            },
            "minItems": 1,
            "maxItems": 10
          },
          "isActive": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "UpdateWorkspaceInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "slug": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100,
            "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
          },
          "timezone": {
            "type": "string",
            "maxLength": 100
          },
          "currency": {
            "type": "string",
            "enum": [
              "HUF",
              "EUR",
              "USD"
            ]
          }
        },
        "additionalProperties": false
      },
      "UserPublic": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "avatarUrl": {
            "type": "string",
            "format": "uri",
            "nullable": true
          }
        },
        "required": [
          "id",
          "email",
          "name",
          "avatarUrl"
        ],
        "additionalProperties": false
      },
      "Verify2faInput": {
        "type": "object",
        "properties": {
          "secret": {
            "type": "string",
            "minLength": 1
          },
          "code": {
            "type": "string",
            "pattern": "^\\d{6}$"
          }
        },
        "required": [
          "secret",
          "code"
        ],
        "additionalProperties": false
      },
      "WebhookEvent": {
        "type": "string",
        "enum": [
          "issue.created",
          "issue.updated",
          "issue.deleted",
          "issue.status_changed",
          "project.created",
          "project.updated",
          "cycle.started",
          "cycle.completed",
          "member.invited",
          "member.removed"
        ]
      }
    }
  },
  "paths": {
    "/auth/register": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Register a new user",
        "description": "Creates a user account, signs them in, and sets the `spire-token` cookie. Rate limit: 5/hour/IP.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 255
                  },
                  "password": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "name",
                  "email",
                  "password"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Email already in use",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Login with email + password",
        "description": "Returns access + refresh tokens and sets the `spire-token` cookie. Rate limit: 10/15min/IP.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "password": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "email",
                  "password"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/google": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Login or register via Google",
        "description": "Accepts either a Google ID token (`credential`, One Tap / popup) or a pre-validated `userInfo` object (FedCM). Auto-creates the user on first sign-in. Rate limit: 20/15min/IP.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "credential": {
                    "type": "string",
                    "description": "Google ID token from One Tap / popup flow."
                  },
                  "userInfo": {
                    "type": "object",
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "name": {
                        "type": "string"
                      },
                      "picture": {
                        "type": "string",
                        "format": "uri"
                      },
                      "googleId": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "email",
                      "name",
                      "googleId"
                    ],
                    "additionalProperties": false,
                    "description": "Pre-validated Google profile (FedCM flow alternative to `credential`)."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/forgot-password": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Request a password reset email",
        "description": "Always returns 200, even for unknown emails (anti-enumeration). Rate limit: 5/hour/IP.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                },
                "required": [
                  "email"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/reset-password": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Reset password with token from email",
        "description": "Token is single-use and expires after 1 hour. Rate limit: 5/hour/IP.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "minLength": 1
                  },
                  "password": {
                    "type": "string",
                    "minLength": 8
                  }
                },
                "required": [
                  "token",
                  "password"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/refresh": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Rotate refresh token, mint new access token",
        "description": "Refresh tokens are single-use; old token is invalidated on success. Rate limit: 60/15min/IP.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "refreshToken": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "refreshToken"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or revoked refresh token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Blacklist current access token, clear cookie",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile": {
      "get": {
        "tags": [
          "Profile"
        ],
        "summary": "Get the current user profile",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Profile"
        ],
        "summary": "Update display name, locale, theme, etc.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "jobTitle": {
                    "type": "string",
                    "maxLength": 100,
                    "nullable": true
                  },
                  "preferences": {
                    "type": "object",
                    "additionalProperties": {}
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/onboarding/complete": {
      "post": {
        "tags": [
          "Profile"
        ],
        "summary": "Mark the guided tour as completed",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/profile/avatar": {
      "post": {
        "tags": [
          "Profile"
        ],
        "summary": "Upload avatar image",
        "description": "JPEG / PNG / GIF / WebP. Max 5 MB. Server-validates MIME type.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Avatar image file."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Missing or invalid file",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Profile"
        ],
        "summary": "Remove the current avatar",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/change-password": {
      "post": {
        "tags": [
          "Profile"
        ],
        "summary": "Change password (current password required)",
        "description": "Blacklists the current access token. Rate limit: 10/hour/IP.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currentPassword": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  },
                  "newPassword": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "currentPassword",
                  "newPassword"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Current password incorrect",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/password/set": {
      "post": {
        "tags": [
          "Profile"
        ],
        "summary": "First-time password set (Google-only accounts)",
        "description": "Refuses with 409 if the account already has a password. Rate limit: 10/hour/IP.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "newPassword": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 128
                  }
                },
                "required": [
                  "newPassword"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Account already has a password — use change-password",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/google/connect": {
      "post": {
        "tags": [
          "Profile"
        ],
        "summary": "Link a Google account to the current user",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "googleId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 255
                  },
                  "avatarUrl": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  }
                },
                "required": [
                  "googleId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Google account already linked elsewhere",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/google": {
      "delete": {
        "tags": [
          "Profile"
        ],
        "summary": "Unlink Google account",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/2fa/setup": {
      "post": {
        "tags": [
          "Profile"
        ],
        "summary": "Generate TOTP secret + provisioning URI",
        "description": "Setup is not enabled until the user verifies a code. Rate limit: 20/hour/IP.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK — `secret` and `uri` returned"
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/2fa/verify": {
      "post": {
        "tags": [
          "Profile"
        ],
        "summary": "Verify 2FA code and enable TOTP",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "secret": {
                    "type": "string",
                    "minLength": 1
                  },
                  "code": {
                    "type": "string",
                    "pattern": "^\\d{6}$"
                  }
                },
                "required": [
                  "secret",
                  "code"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK — recovery codes returned"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many failed attempts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/profile/2fa": {
      "delete": {
        "tags": [
          "Profile"
        ],
        "summary": "Disable TOTP (password or recovery code required)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "pattern": "^\\d{6}$"
                  },
                  "currentPassword": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  }
                },
                "required": [
                  "code",
                  "currentPassword"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many failed attempts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/workspaces": {
      "get": {
        "tags": [
          "Workspaces"
        ],
        "summary": "List workspaces the current user belongs to",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Create a new workspace",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "slug": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100,
                    "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
                  },
                  "timezone": {
                    "type": "string",
                    "maxLength": 100,
                    "default": "Europe/Budapest"
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "HUF",
                      "EUR",
                      "USD"
                    ],
                    "default": "HUF"
                  }
                },
                "required": [
                  "name",
                  "slug"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/workspaces/{id}": {
      "get": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Get a single workspace",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Update workspace name / settings",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "slug": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100,
                    "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
                  },
                  "timezone": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "HUF",
                      "EUR",
                      "USD"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Delete a workspace",
        "description": "Owner-only. Cascades to projects, issues, members.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/workspaces/{id}/logo": {
      "post": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Upload workspace logo",
        "description": "JPEG / PNG / GIF / WebP. Max 5 MB.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Logo image file."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Remove the workspace logo",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/workspaces/{id}/transfer-ownership": {
      "post": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Transfer ownership to another member",
        "description": "Owner-only. Owner with a password must re-confirm it.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "newOwnerId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "password": {
                    "type": "string"
                  }
                },
                "required": [
                  "newOwnerId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Password required or incorrect",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/workspaces/{id}/switch": {
      "post": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Set the active workspace for the current user",
        "description": "Mints a new access token with `tenantId` set to the target workspace.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/gdpr/export": {
      "post": {
        "tags": [
          "GDPR"
        ],
        "summary": "Request user data export (Art. 15 / 20)",
        "description": "Generates a JSON export and emails the download link.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/gdpr/delete-account": {
      "post": {
        "tags": [
          "GDPR"
        ],
        "summary": "Request account deletion (Art. 17)",
        "description": "Soft-deletes the account, schedules permanent deletion after 30 days.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/gdpr/sessions": {
      "get": {
        "tags": [
          "GDPR"
        ],
        "summary": "List active sessions (refresh tokens)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/gdpr/activity": {
      "get": {
        "tags": [
          "GDPR"
        ],
        "summary": "List recent account-level audit events",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/lookup": {
      "get": {
        "tags": [
          "Lookup"
        ],
        "summary": "Find which workspace owns a project / issue / cycle",
        "description": "Returns the workspace ID that contains the given resource. Used by the frontend to recover from a 404 when the resource exists in another workspace the user is a member of.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": true,
            "description": "Resource type to look up.",
            "schema": {
              "type": "string",
              "enum": [
                "project",
                "issue",
                "cycle"
              ]
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": true,
            "description": "For `project` → project key. For `issue` → identifier (e.g. SPIRE-42). For `cycle` → UUID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/invitations/token/{token}": {
      "get": {
        "tags": [
          "Invitations"
        ],
        "summary": "Preview an invitation by token",
        "description": "Public endpoint — used by the landing page to show workspace name / invited email before sign-in.",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Invalid or expired invitation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/invitations/token/{token}/accept": {
      "post": {
        "tags": [
          "Invitations"
        ],
        "summary": "Accept an invitation as the current user",
        "description": "Joins the caller to the workspace referenced by the token.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Email mismatch or already a member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Invalid or expired invitation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "List projects in the active workspace",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Create a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "key": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 10
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 50000
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  },
                  "icon": {
                    "type": "string",
                    "maxLength": 50
                  },
                  "isPrivate": {
                    "type": "boolean",
                    "default": true
                  },
                  "leadId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "startDate": {
                    "type": "string"
                  },
                  "targetDate": {
                    "type": "string"
                  }
                },
                "required": [
                  "name",
                  "color"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/projects/{key}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get a project by key (e.g. `SPIRE`)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Projects"
        ],
        "summary": "Update a project",
        "description": "`isPrivate` may only be modified by owner / admin.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 50000
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  },
                  "icon": {
                    "type": "string",
                    "maxLength": 50,
                    "nullable": true
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "planned",
                      "active",
                      "paused",
                      "completed",
                      "archived"
                    ]
                  },
                  "isPrivate": {
                    "type": "boolean"
                  },
                  "leadId": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "startDate": {
                    "type": "string",
                    "nullable": true
                  },
                  "targetDate": {
                    "type": "string",
                    "nullable": true
                  },
                  "columnConfig": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 100
                    }
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Soft-delete a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/projects/{key}/members": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "List project members",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Add a single member to a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "userId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/projects/{key}/members/{userId}": {
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Remove a member from a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/projects/{key}/members/team": {
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Add an entire team to a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "teamId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "teamId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/issues": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "List issues with filters",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 25
          },
          {
            "name": "projectId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "cycleId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "assigneeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "labelId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Create an issue",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sectionId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "parentId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "cycleId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 50000
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "backlog",
                      "todo",
                      "in_progress",
                      "in_review",
                      "done",
                      "cancelled"
                    ],
                    "default": "backlog"
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "urgent",
                      "high",
                      "medium",
                      "low",
                      "none"
                    ],
                    "default": "none"
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "task",
                      "bug",
                      "request",
                      "idea"
                    ],
                    "default": "task"
                  },
                  "assigneeId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "estimate": {
                    "type": "number",
                    "minimum": 0
                  },
                  "dueDate": {
                    "type": "string",
                    "maxLength": 32
                  },
                  "labelIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "default": []
                  }
                },
                "required": [
                  "projectId",
                  "title"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/issues/{identifier}": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "Get an issue by identifier (e.g. `SPIRE-42`)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Issues"
        ],
        "summary": "Update an issue",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 50000
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "backlog",
                      "todo",
                      "in_progress",
                      "in_review",
                      "done",
                      "cancelled"
                    ]
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "urgent",
                      "high",
                      "medium",
                      "low",
                      "none"
                    ]
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "task",
                      "bug",
                      "request",
                      "idea"
                    ]
                  },
                  "assigneeId": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "projectId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sectionId": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "cycleId": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "estimate": {
                    "type": "number",
                    "minimum": 0,
                    "nullable": true
                  },
                  "dueDate": {
                    "type": "string",
                    "maxLength": 32,
                    "nullable": true
                  },
                  "sortOrder": {
                    "type": "number"
                  },
                  "labelIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Issues"
        ],
        "summary": "Soft-delete an issue",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/issues/{id}/restore": {
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Restore a soft-deleted issue (by UUID)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/issues/bulk": {
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Bulk update / delete issues",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "update_status",
                      "update_priority",
                      "update_assignee",
                      "add_label",
                      "delete"
                    ]
                  },
                  "issueIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  },
                  "value": {
                    "type": "string"
                  }
                },
                "required": [
                  "action",
                  "issueIds"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/issues/{identifier}/comments": {
      "get": {
        "tags": [
          "Issues"
        ],
        "summary": "List comments on an issue",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Post a comment",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50000
                  }
                },
                "required": [
                  "body"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/issues/{identifier}/comments/{commentId}": {
      "patch": {
        "tags": [
          "Issues"
        ],
        "summary": "Edit a comment",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50000
                  }
                },
                "required": [
                  "body"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Issues"
        ],
        "summary": "Delete a comment",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/issues/{identifier}/comments/{commentId}/reactions": {
      "post": {
        "tags": [
          "Issues"
        ],
        "summary": "Toggle an emoji reaction on a comment",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "emoji": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32
                  }
                },
                "required": [
                  "emoji"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/cycles": {
      "get": {
        "tags": [
          "Cycles"
        ],
        "summary": "List cycles",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Cycles"
        ],
        "summary": "Create a cycle",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 50000
                  },
                  "startDate": {
                    "type": "string"
                  },
                  "endDate": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/cycles/{id}": {
      "get": {
        "tags": [
          "Cycles"
        ],
        "summary": "Get a cycle",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Cycles"
        ],
        "summary": "Update a cycle",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 50000
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "planned",
                      "active",
                      "completed"
                    ]
                  },
                  "startDate": {
                    "type": "string",
                    "nullable": true
                  },
                  "endDate": {
                    "type": "string",
                    "nullable": true
                  },
                  "retrospective": {
                    "type": "object",
                    "properties": {
                      "wentWell": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "didntGoWell": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "improvements": {
                        "type": "string",
                        "maxLength": 500
                      }
                    },
                    "additionalProperties": false,
                    "nullable": true
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Cycles"
        ],
        "summary": "Delete a cycle",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/cycles/{id}/burndown": {
      "get": {
        "tags": [
          "Cycles"
        ],
        "summary": "Burndown chart datapoints",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/cycles/{id}/ai-summary": {
      "post": {
        "tags": [
          "Cycles"
        ],
        "summary": "Generate AI retrospective summary",
        "description": "Counts toward the AI usage quota.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "402": {
            "description": "Quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/labels": {
      "get": {
        "tags": [
          "Labels"
        ],
        "summary": "List labels",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Create a label",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  }
                },
                "required": [
                  "name",
                  "color"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/labels/{id}": {
      "patch": {
        "tags": [
          "Labels"
        ],
        "summary": "Update a label",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Labels"
        ],
        "summary": "Delete a label",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/teams": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "List teams",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Teams"
        ],
        "summary": "Create a team",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "identifier": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 10
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  }
                },
                "required": [
                  "name",
                  "identifier",
                  "color"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/teams/{id}": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "Get a team",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Teams"
        ],
        "summary": "Update a team",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Teams"
        ],
        "summary": "Delete a team",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/teams/{id}/members": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "List team members",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Teams"
        ],
        "summary": "Add a member to a team",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "userId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/teams/{id}/members/{userId}": {
      "delete": {
        "tags": [
          "Teams"
        ],
        "summary": "Remove a member from a team",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/members": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "List workspace members",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/members/invite": {
      "post": {
        "tags": [
          "Members"
        ],
        "summary": "Invite a user by email",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "member",
                      "guest"
                    ]
                  }
                },
                "required": [
                  "email",
                  "role"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/members/invitations": {
      "get": {
        "tags": [
          "Members"
        ],
        "summary": "List pending invitations",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/members/invitations/{id}": {
      "delete": {
        "tags": [
          "Members"
        ],
        "summary": "Revoke a pending invitation",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/members/invitations/{id}/resend": {
      "post": {
        "tags": [
          "Members"
        ],
        "summary": "Resend an invitation email",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/members/bulk-invite": {
      "post": {
        "tags": [
          "Members"
        ],
        "summary": "Invite up to 50 users at once",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "invites": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "email": {
                          "type": "string",
                          "format": "email"
                        },
                        "role": {
                          "type": "string",
                          "enum": [
                            "admin",
                            "member",
                            "guest"
                          ]
                        }
                      },
                      "required": [
                        "email",
                        "role"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 50
                  }
                },
                "required": [
                  "invites"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/members/{id}": {
      "patch": {
        "tags": [
          "Members"
        ],
        "summary": "Change a member's role",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "member",
                      "guest"
                    ]
                  }
                },
                "required": [
                  "role"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Members"
        ],
        "summary": "Remove a member from the workspace",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/notifications": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "List notifications for the current user",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 25
          },
          {
            "name": "unread",
            "in": "query",
            "description": "Filter to only unread.",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "archived",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/notifications/unread-count": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "Unread notification badge count",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/notifications/{id}/read": {
      "patch": {
        "tags": [
          "Notifications"
        ],
        "summary": "Mark a notification as read",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/notifications/{id}/archive": {
      "patch": {
        "tags": [
          "Notifications"
        ],
        "summary": "Archive a notification",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/notifications/{id}/unarchive": {
      "patch": {
        "tags": [
          "Notifications"
        ],
        "summary": "Unarchive a notification",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/notifications/{id}": {
      "delete": {
        "tags": [
          "Notifications"
        ],
        "summary": "Delete a notification",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/notifications/read-all": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Mark all notifications as read",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/notifications/preferences": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "Get per-channel notification preferences",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationPreferences"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Notifications"
        ],
        "summary": "Update per-channel notification preferences",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "inapp_assignment",
                  "inapp_status_change",
                  "inapp_comment",
                  "inapp_mention",
                  "inapp_invitations",
                  "inapp_due_date",
                  "email_assignment",
                  "email_status_change",
                  "email_comment",
                  "email_mention",
                  "email_invitations",
                  "email_due_date"
                ],
                "properties": {
                  "inapp_assignment": {
                    "type": "boolean"
                  },
                  "inapp_status_change": {
                    "type": "boolean"
                  },
                  "inapp_comment": {
                    "type": "boolean"
                  },
                  "inapp_mention": {
                    "type": "boolean"
                  },
                  "inapp_invitations": {
                    "type": "boolean"
                  },
                  "inapp_due_date": {
                    "type": "boolean"
                  },
                  "email_assignment": {
                    "type": "boolean"
                  },
                  "email_status_change": {
                    "type": "boolean"
                  },
                  "email_comment": {
                    "type": "boolean"
                  },
                  "email_mention": {
                    "type": "boolean"
                  },
                  "email_invitations": {
                    "type": "boolean"
                  },
                  "email_due_date": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/search": {
      "get": {
        "tags": [
          "Search"
        ],
        "summary": "Full-text search across projects + issues + cycles",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search query.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Restrict to one type.",
            "schema": {
              "type": "string",
              "enum": [
                "project",
                "issue",
                "cycle"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/ai/usage": {
      "get": {
        "tags": [
          "AI"
        ],
        "summary": "Current AI usage quota / consumption",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/ai/triage": {
      "post": {
        "tags": [
          "AI"
        ],
        "summary": "Triage free-form text into structured issue draft",
        "description": "Counts toward AI usage quota. Rate limit: 15/minute/IP.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50000
                  }
                },
                "required": [
                  "text"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/ai/subtasks": {
      "post": {
        "tags": [
          "AI"
        ],
        "summary": "Generate subtask suggestions from an issue title + body",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 10000
                  },
                  "existing": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 500
                    },
                    "maxItems": 30
                  }
                },
                "required": [
                  "title"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/ai/summary": {
      "post": {
        "tags": [
          "AI"
        ],
        "summary": "Summarize an entity (project / issue / cycle / workspace / team)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "entityType": {
                    "type": "string",
                    "enum": [
                      "project",
                      "issue",
                      "cycle",
                      "workspace",
                      "team"
                    ]
                  },
                  "data": {
                    "type": "object",
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "entityType",
                  "data"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/custom-fields/project/{projectId}": {
      "get": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "List custom field definitions for a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/custom-fields": {
      "post": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Create a custom field definition",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "text",
                      "number",
                      "select",
                      "multi_select",
                      "date",
                      "checkbox",
                      "url",
                      "email"
                    ]
                  },
                  "options": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "value": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "color": {
                          "type": "string",
                          "pattern": "^#[0-9a-fA-F]{6}$"
                        }
                      },
                      "required": [
                        "label",
                        "value"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "projectId",
                  "name",
                  "type"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/custom-fields/{id}": {
      "patch": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Update a custom field definition",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "options": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "value": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "color": {
                          "type": "string",
                          "pattern": "^#[0-9a-fA-F]{6}$"
                        }
                      },
                      "required": [
                        "label",
                        "value"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Delete a custom field definition",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/custom-fields/project/{projectId}/values": {
      "get": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Aggregated custom field values for all issues in a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/custom-fields/issues/{issueId}/fields/{fieldId}": {
      "put": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Set a custom field value on an issue",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "value": {
                    "type": "string",
                    "maxLength": 10000,
                    "nullable": true
                  }
                },
                "required": [
                  "value"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/custom-fields/issues/{issueId}/values": {
      "get": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "List custom field values for an issue",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/favorites": {
      "get": {
        "tags": [
          "Favorites"
        ],
        "summary": "List the current user's favorites",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/favorites/toggle": {
      "post": {
        "tags": [
          "Favorites"
        ],
        "summary": "Toggle favorite status for a project / cycle / view",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "favorableType": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50
                  },
                  "favorableId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "favorableType",
                  "favorableId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/favorites/reorder": {
      "post": {
        "tags": [
          "Favorites"
        ],
        "summary": "Reorder favorites in the sidebar",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "sortOrder": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "id",
                        "sortOrder"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 1
                  }
                },
                "required": [
                  "items"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/sections/projects/{projectId}/sections": {
      "get": {
        "tags": [
          "Sections"
        ],
        "summary": "List sections (groupings of issues) within a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Sections"
        ],
        "summary": "Create a section in a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/sections/{id}": {
      "patch": {
        "tags": [
          "Sections"
        ],
        "summary": "Update a section",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Sections"
        ],
        "summary": "Delete a section",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/sections/reorder": {
      "post": {
        "tags": [
          "Sections"
        ],
        "summary": "Reorder sections in a project",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "sortOrder": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "id",
                        "sortOrder"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 1
                  }
                },
                "required": [
                  "items"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/home/stats": {
      "get": {
        "tags": [
          "Home"
        ],
        "summary": "Aggregated stats for the home page widgets",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/attachments": {
      "get": {
        "tags": [
          "Attachments"
        ],
        "summary": "List attachments for an entity",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "entityType",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "issue",
                "comment"
              ]
            }
          },
          {
            "name": "entityId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Attachments"
        ],
        "summary": "Upload an attachment",
        "description": "Per-file 25 MB limit, MIME-type allowlist enforced server-side.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Attachment file."
                  },
                  "entityType": {
                    "type": "string",
                    "description": "`issue` or `comment`."
                  },
                  "entityId": {
                    "type": "string",
                    "description": "UUID of the parent entity."
                  }
                },
                "required": [
                  "file",
                  "entityType",
                  "entityId"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "File too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/attachments/{id}": {
      "get": {
        "tags": [
          "Attachments"
        ],
        "summary": "Get a single attachment by ID",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Attachments"
        ],
        "summary": "Delete an attachment",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/data/export/summary": {
      "get": {
        "tags": [
          "Import/Export"
        ],
        "summary": "Counts of exportable entities",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/data/export/workspace": {
      "get": {
        "tags": [
          "Import/Export"
        ],
        "summary": "Download the workspace as a JSON document",
        "description": "Returns the workspace export envelope (matches `workspaceExportSchema`).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/data/template/workspace.json": {
      "get": {
        "tags": [
          "Import/Export"
        ],
        "summary": "Empty template export for manual editing",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v/data/import/preview": {
      "post": {
        "tags": [
          "Import/Export"
        ],
        "summary": "Validate an import payload without applying",
        "description": "Returns warnings, conflicts, and counts of entities that would be created / merged / skipped.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "data": {
                    "description": "Workspace export JSON document (`workspaceExportSchema`)."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/data/import": {
      "post": {
        "tags": [
          "Import/Export"
        ],
        "summary": "Apply a workspace import",
        "description": "Owner / admin only.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "data": {
                    "description": "Workspace export JSON document (`workspaceExportSchema`)."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "mergeStrategy": {
                        "type": "string",
                        "enum": [
                          "skip",
                          "overwrite"
                        ],
                        "default": "skip"
                      }
                    },
                    "additionalProperties": false
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/audit-logs": {
      "get": {
        "tags": [
          "Audit Logs"
        ],
        "summary": "List workspace audit log entries",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 25
          },
          {
            "name": "actorId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "action",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "entityType",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/audit-logs/entity/{type}/{id}": {
      "get": {
        "tags": [
          "Audit Logs"
        ],
        "summary": "Audit log entries for a specific entity",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/audit-logs/export": {
      "get": {
        "tags": [
          "Audit Logs"
        ],
        "summary": "Export the audit log as CSV",
        "description": "Returns `text/csv`. Owner / admin only.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/api-tokens": {
      "get": {
        "tags": [
          "API Tokens"
        ],
        "summary": "List API tokens for the current user",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "API Tokens"
        ],
        "summary": "Create an API token",
        "description": "The plaintext token is returned once on creation and never again.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 100
                    },
                    "maxItems": 50
                  },
                  "expiresAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/api-tokens/{id}": {
      "patch": {
        "tags": [
          "API Tokens"
        ],
        "summary": "Update an API token (name, scopes)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 100
                    },
                    "maxItems": 50
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "API Tokens"
        ],
        "summary": "Revoke an API token",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhooks",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Create a webhook",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "issue.created",
                        "issue.updated",
                        "issue.deleted",
                        "issue.status_changed",
                        "project.created",
                        "project.updated",
                        "cycle.started",
                        "cycle.completed",
                        "member.invited",
                        "member.removed"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 10
                  }
                },
                "required": [
                  "name",
                  "url",
                  "events"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/webhooks/{id}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get a webhook",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Update a webhook",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "issue.created",
                        "issue.updated",
                        "issue.deleted",
                        "issue.status_changed",
                        "project.created",
                        "project.updated",
                        "cycle.started",
                        "cycle.completed",
                        "member.invited",
                        "member.removed"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 10
                  },
                  "isActive": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete a webhook",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/webhooks/{id}/test": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test event to the webhook URL",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List recent delivery attempts",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "1-indexed page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page (max 100).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/workspace-invoices": {
      "get": {
        "tags": [
          "Workspace invoices"
        ],
        "summary": "List issued/paid invoices for the active workspace",
        "description": "Owner-only. Member / admin / guest get 403.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/workspace-invoices/{id}/pdf": {
      "get": {
        "tags": [
          "Workspace invoices"
        ],
        "summary": "Download invoice PDF",
        "description": "Owner-only. Streams the PDF as Content-Disposition: attachment.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/workspace-invoices/plan": {
      "get": {
        "tags": [
          "Workspace invoices"
        ],
        "summary": "Get the active billing plan for the current workspace",
        "description": "Owner-only. Returns cycle / kind / unitPriceHuf / effectiveFrom — used by /settings/billing to render the cycle switcher.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v/workspace-invoices/cycle": {
      "post": {
        "tags": [
          "Workspace invoices"
        ],
        "summary": "Switch billing cycle (monthly ↔ annual)",
        "description": "Owner-only. Inserts a new SCD2 plan version with effectiveFrom = first of the next calendar month. Rate-limited to one switch per 30 days.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cycle": {
                    "type": "string",
                    "enum": [
                      "monthly",
                      "annual"
                    ]
                  }
                },
                "required": [
                  "cycle"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (already switched in the last 30 days)"
          }
        }
      }
    },
    "/api/v/feedback": {
      "post": {
        "tags": [
          "Feedback"
        ],
        "summary": "Submit a feedback report",
        "description": "Bug / idea / question / other. Rate limit: 10/hour/IP.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "category": {
                    "type": "string",
                    "enum": [
                      "bug",
                      "idea",
                      "question",
                      "other"
                    ]
                  },
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  }
                },
                "required": [
                  "category",
                  "body"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Liveness probe",
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}
