{ "openapi": "3.0.0", "paths": { "/api/health": { "get": { "operationId": "HealthController_check", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "example": { "status": "ok", "postgres": "up", "mongo": "up", "redis": "up" } } } } }, "503": { "description": "A database is down" } }, "summary": "API and databases status", "tags": [ "Health" ], "security": [] } }, "/api/auth/config": { "get": { "operationId": "AuthController_config", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthorizationConfigDto" } } } } }, "summary": "How to sign in with Pireon (null when not configured)", "tags": [ "Auth" ], "security": [] } }, "/api/auth/token": { "post": { "description": "For browsers (Pireon has no CORS) and Swagger UI: adds the client secret server-side. Apps with their own Pireon OAuth client can get tokens from Pireon directly; any valid Pireon access token is accepted by this API.", "operationId": "AuthController_token", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssueTokenDto" } }, "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/IssueTokenDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TokenResponseDto" } } } }, "401": { "description": "Pireon rejected the grant" } }, "summary": "Exchange a grant for Pireon tokens (proxy of Pireon /oauth/token)", "tags": [ "Auth" ], "security": [] } }, "/api/users/me": { "get": { "operationId": "UsersController_me", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "The user behind the access token", "tags": [ "Users" ] } }, "/api/users": { "get": { "description": "Needs the `users:read` scope in the access token.", "operationId": "UsersController_search", "parameters": [ { "name": "search", "required": false, "in": "query", "description": "Name or email", "schema": { "default": "", "type": "string" } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 100, "default": 20, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Search Pireon users (to assign tickets or add members)", "tags": [ "Users" ] } }, "/api/users/{id}": { "get": { "operationId": "UsersController_findOne", "parameters": [ { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "A Pireon user", "tags": [ "Users" ] } }, "/api/webhooks/pireon": { "post": { "description": "`user.deactivated` closes the user's sessions; `token.revoked` forgets the token. Disabled unless PIREON_WEBHOOK_SECRET is set.", "operationId": "PireonWebhookController_receive", "parameters": [ { "name": "x-webhook-signature", "required": true, "in": "header", "schema": { "type": "string" } }, { "name": "X-Webhook-Signature", "in": "header", "description": "HMAC-SHA256 of the raw body with PIREON_WEBHOOK_SECRET (hex)", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Processed" }, "401": { "description": "Missing or invalid signature" } }, "summary": "Pireon events (called by Pireon, not by apps)", "tags": [ "Webhooks" ], "security": [] } }, "/api/projects": { "get": { "operationId": "ProjectsController_mine", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Projects where I am a member", "tags": [ "Projects" ] }, "post": { "operationId": "ProjectsController_create", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Create a project (you become its owner)", "tags": [ "Projects" ] } }, "/api/projects/{project}": { "get": { "operationId": "ProjectsController_findOne", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "A project with its members and settings", "tags": [ "Projects" ] }, "patch": { "operationId": "ProjectsController_update", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateProjectDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Rename, describe or make public/private a project (owner/admin)", "tags": [ "Projects" ] }, "delete": { "description": "Deletes the project and, right after (asynchronously, through a saga), its tickets, comments and releases; links from tickets of other projects are removed and the key becomes free. Cannot be undone from the API. `confirm` must be the project key.", "operationId": "ProjectsController_remove", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } }, { "name": "confirm", "required": true, "in": "query", "description": "The project key, to confirm the deletion", "schema": { "example": "WEB", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Delete a project (owner only)", "tags": [ "Projects" ] } }, "/api/projects/{project}/settings": { "put": { "description": "Replaces the whole configuration (send what GET /projects/{project} returns, changed). Values can be added, renamed, reordered or archived, never removed: tickets and statistics keep referring to them.", "operationId": "ProjectsController_updateSettings", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectSettingsBodyDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Statuses, transitions, ticket types and areas (owner/admin)", "tags": [ "Projects" ] } }, "/api/projects/{project}/board": { "get": { "operationId": "ProjectsController_board", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } }, { "name": "releaseId", "required": false, "in": "query", "description": "Only this release", "schema": { "format": "uuid", "type": "string" } }, { "name": "assigneeId", "required": false, "in": "query", "description": "Only this person (Pireon user id)", "schema": { "type": "string" } }, { "name": "area", "required": false, "in": "query", "description": "An area id", "schema": { "example": "FRONTEND", "type": "string" } }, { "name": "type", "required": false, "in": "query", "description": "Ticket type ids", "schema": { "type": "array", "items": { "type": "string" } } }, { "name": "priority", "required": false, "in": "query", "schema": { "type": "array", "items": { "$ref": "#/components/schemas/IssuePriority" } } }, { "name": "label", "required": false, "in": "query", "schema": { "type": "array", "items": { "type": "string" } } }, { "name": "search", "required": false, "in": "query", "description": "Matches key, title or description", "schema": { "type": "string" } }, { "name": "unassigned", "required": false, "in": "query", "description": "Only tickets without assignee", "schema": { "type": "boolean" } }, { "name": "sprintId", "required": false, "in": "query", "description": "Only this sprint", "schema": { "format": "uuid", "type": "string" } }, { "name": "perColumn", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/BoardColumnDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Kanban board: one column per status", "tags": [ "Projects" ] } }, "/api/projects/{project}/stats": { "get": { "operationId": "ProjectsController_stats", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectStatsDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Tracking dashboard: counts by status, type, person…", "tags": [ "Projects" ] } }, "/api/projects/{project}/analytics": { "get": { "description": "Created vs resolved per week, cumulative flow per day, cycle and lead time, throughput per person and QA pass/fail.", "operationId": "ProjectsController_analytics", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } }, { "name": "days", "required": false, "in": "query", "schema": { "minimum": 7, "maximum": 365, "default": 90, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectAnalyticsDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Statistics of the last `days` days", "tags": [ "Projects" ] } }, "/api/projects/{project}/activity": { "get": { "operationId": "ProjectsController_activity", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } }, { "name": "issueId", "required": false, "in": "query", "description": "Only this ticket", "schema": { "format": "uuid", "type": "string" } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } }, { "name": "before", "required": false, "in": "query", "description": "Cursor: entries older than this date", "schema": { "format": "date-time", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ActivityDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Activity feed (newest first)", "tags": [ "Projects" ] } }, "/api/projects/{project}/members": { "post": { "description": "The user must exist and be active in Pireon.", "operationId": "ProjectsController_addMember", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddMemberDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Add a Pireon user to the project (owner/admin)", "tags": [ "Projects" ] } }, "/api/projects/{project}/members/{userId}": { "patch": { "operationId": "ProjectsController_changeMemberRole", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } }, { "name": "userId", "required": true, "in": "path", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeMemberRoleDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Change a member's role (owner/admin)", "tags": [ "Projects" ] }, "delete": { "operationId": "ProjectsController_removeMember", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } }, { "name": "userId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Remove a member (owner/admin, or yourself to leave)", "tags": [ "Projects" ] } }, "/api/issues/{issue}/watch": { "put": { "description": "Followers are told when it moves, is reassigned or gets a comment. Commenting follows it too.", "operationId": "IssuesController_watch", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Follow a ticket (members, viewers included)", "tags": [ "Issues" ] }, "delete": { "operationId": "IssuesController_unwatch", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Stop following a ticket", "tags": [ "Issues" ] } }, "/api/me/issues": { "get": { "description": "Assigned to me by default; with assignedToMe=false, any ticket of my projects (e.g. waiting for QA).", "operationId": "IssuesController_mine", "parameters": [ { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } }, { "name": "offset", "required": false, "in": "query", "schema": { "minimum": 0, "default": 0, "type": "number" } }, { "name": "assignedToMe", "required": false, "in": "query", "description": "true: tickets assigned to me. false: any ticket of my projects (e.g. ?assignedToMe=false&category=QA)", "schema": { "default": true, "type": "boolean" } }, { "name": "status", "required": false, "in": "query", "description": "Status ids. Repeat the parameter or separate with commas", "schema": { "type": "array", "items": { "type": "string" } } }, { "name": "category", "required": false, "in": "query", "description": "Whatever each project calls its statuses", "schema": { "type": "array", "items": { "$ref": "#/components/schemas/StatusCategory" } } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssuePageDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "My work: tickets across all my projects", "tags": [ "Issues" ] } }, "/api/projects/{project}/issues": { "get": { "operationId": "IssuesController_search", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } }, { "name": "offset", "required": false, "in": "query", "schema": { "minimum": 0, "default": 0, "type": "number" } }, { "name": "status", "required": false, "in": "query", "description": "Status ids. Repeat the parameter or separate with commas", "schema": { "type": "array", "items": { "type": "string" } } }, { "name": "category", "required": false, "in": "query", "schema": { "type": "array", "items": { "$ref": "#/components/schemas/StatusCategory" } } }, { "name": "type", "required": false, "in": "query", "description": "Ticket type ids", "schema": { "type": "array", "items": { "type": "string" } } }, { "name": "area", "required": false, "in": "query", "description": "Area ids", "schema": { "type": "array", "items": { "type": "string" } } }, { "name": "priority", "required": false, "in": "query", "schema": { "type": "array", "items": { "$ref": "#/components/schemas/IssuePriority" } } }, { "name": "assigneeId", "required": false, "in": "query", "description": "Pireon user id", "schema": { "type": "string" } }, { "name": "unassigned", "required": false, "in": "query", "description": "Only tickets without assignee", "schema": { "type": "boolean" } }, { "name": "releaseId", "required": false, "in": "query", "schema": { "format": "uuid", "type": "string" } }, { "name": "label", "required": false, "in": "query", "schema": { "type": "array", "items": { "type": "string" } } }, { "name": "parent", "required": false, "in": "query", "description": "Only the tickets hanging from this one (id or key)", "schema": { "example": "WEB-3", "type": "string" } }, { "name": "sprintId", "required": false, "in": "query", "description": "Only this sprint", "schema": { "format": "uuid", "type": "string" } }, { "name": "noSprint", "required": false, "in": "query", "description": "Only tickets in no sprint", "schema": { "type": "boolean" } }, { "name": "sort", "required": false, "in": "query", "description": "RECENT (default): last updated first. RANK: backlog order.", "schema": { "$ref": "#/components/schemas/IssueSort" } }, { "name": "search", "required": false, "in": "query", "description": "Matches key, title or description", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssuePageDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Search the tickets of a project", "tags": [ "Issues" ] }, "post": { "description": "Starts in the project's first active TODO-category status (BACKLOG by default). The response carries its key (e.g. WEB-13).", "operationId": "IssuesController_create", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateIssueDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Create a ticket", "tags": [ "Issues" ] } }, "/api/projects/{project}/epics": { "get": { "description": "With the progress of the tickets hanging from each one (done or cancelled, and story points).", "operationId": "IssuesController_epics", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/EpicDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Epics: top-level tickets that group others", "tags": [ "Issues" ] } }, "/api/issues/{issue}": { "get": { "operationId": "IssuesController_findOne", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssueDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "A ticket", "tags": [ "Issues" ] }, "patch": { "operationId": "IssuesController_update", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateIssueDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Edit title, description, type, priority, area, labels…", "tags": [ "Issues" ] } }, "/api/issues/{issue}/status": { "put": { "description": "Only the transitions in `allowedTransitions` are accepted (422 otherwise). QA_FAILED and CANCELLED need a reason.", "operationId": "IssuesController_changeStatus", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeStatusDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Move the ticket through the workflow (incl. QA)", "tags": [ "Issues" ] } }, "/api/issues/{issue}/assignee": { "put": { "operationId": "IssuesController_assign", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AssignIssueDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Assign to a project member (null to unassign)", "tags": [ "Issues" ] } }, "/api/issues/{issue}/release": { "put": { "operationId": "IssuesController_setRelease", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetIssueReleaseDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Put the ticket in a planned release (null takes it out)", "tags": [ "Issues" ] } }, "/api/issues/{issue}/parent": { "put": { "description": "Same project, three levels at most (epic → ticket → subtask), no loops. null takes it back to the top.", "operationId": "IssuesController_setParent", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetIssueParentDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Place the ticket under an epic or another ticket", "tags": [ "Issues" ] } }, "/api/issues/{issue}/rank": { "put": { "description": "Between the ticket that ends up above it and the one below (either may be left out for the top or the bottom). Board columns follow the same order.", "operationId": "IssuesController_rank", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RankIssueDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Move the ticket in the backlog", "tags": [ "Issues" ] } }, "/api/issues/{issue}/checklist": { "post": { "operationId": "IssuesController_addChecklistItem", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChecklistItemBodyDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Add a step to the ticket's checklist", "tags": [ "Issues" ] } }, "/api/issues/{issue}/checklist/{item}": { "patch": { "operationId": "IssuesController_updateChecklistItem", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } }, { "name": "item", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateChecklistItemDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Reword, tick or untick a checklist step", "tags": [ "Issues" ] }, "delete": { "operationId": "IssuesController_removeChecklistItem", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } }, { "name": "item", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Remove a checklist step", "tags": [ "Issues" ] } }, "/api/issues/{issue}/links": { "post": { "description": "e.g. WEB-3 DEPENDS_ON API-7, WEB-9 TESTS WEB-3. May cross projects.", "operationId": "IssuesController_link", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkIssueDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Relate tickets (FE ↔ BE ↔ QA)", "tags": [ "Issues" ] } }, "/api/issues/{issue}/links/{type}/{target}": { "delete": { "operationId": "IssuesController_unlink", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } }, { "name": "type", "required": true, "in": "path", "schema": { "$ref": "#/components/schemas/IssueLinkType" } }, { "name": "target", "required": true, "in": "path", "description": "Other ticket: id or key", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Remove a relation", "tags": [ "Issues" ] } }, "/api/issues/{issue}/comments": { "get": { "operationId": "IssuesController_listComments", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } }, { "name": "offset", "required": false, "in": "query", "schema": { "minimum": 0, "default": 0, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommentPageDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Comments of the ticket (oldest first)", "tags": [ "Issues" ] }, "post": { "operationId": "IssuesController_addComment", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommentBodyDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Comment on the ticket", "tags": [ "Issues" ] } }, "/api/issues/{issue}/history": { "get": { "operationId": "IssuesController_history", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } }, { "name": "offset", "required": false, "in": "query", "schema": { "minimum": 0, "default": 0, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ActivityDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "History of the ticket (newest first)", "tags": [ "Issues" ] } }, "/api/issues/{issue}/attachments": { "post": { "description": "Multipart with the file as `file` and, optionally, `commentId` to place it under a comment. Up to ATTACHMENTS_MAX_MB megabytes (25 by default) and 50 files per ticket.", "operationId": "AttachmentsController_attach", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/AttachFileDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Attach a file to a ticket (members)", "tags": [ "Issues" ] } }, "/api/issues/{issue}/attachments/{attachmentId}": { "get": { "operationId": "AttachmentsController_download", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } }, { "name": "attachmentId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "The file" }, "400": { "description": "Invalid input", "content": { "application/octet-stream": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/octet-stream": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/octet-stream": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/octet-stream": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Download one of a ticket's files", "tags": [ "Issues" ] }, "delete": { "operationId": "AttachmentsController_remove", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } }, { "name": "attachmentId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Remove a file (whoever uploaded it, or an owner/admin)", "tags": [ "Issues" ] } }, "/api/comments/{commentId}": { "patch": { "operationId": "CommentsController_edit", "parameters": [ { "name": "commentId", "required": true, "in": "path", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommentBodyDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Edit a comment (author only)", "tags": [ "Comments" ] }, "delete": { "operationId": "CommentsController_delete", "parameters": [ { "name": "commentId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Delete a comment (author or project admin)", "tags": [ "Comments" ] } }, "/api/me/releases": { "get": { "operationId": "ReleasesController_upcoming", "parameters": [ { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 50, "default": 10, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ReleaseDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Planned releases of all my projects, soonest target date first", "tags": [ "Releases" ] } }, "/api/projects/{project}/releases": { "get": { "operationId": "ReleasesController_list", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ReleaseDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Releases of a project", "tags": [ "Releases" ] }, "post": { "operationId": "ReleasesController_create", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateReleaseDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Plan a release (owner/admin)", "tags": [ "Releases" ] } }, "/api/releases/{releaseId}": { "get": { "operationId": "ReleasesController_findOne", "parameters": [ { "name": "releaseId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReleaseDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "A release", "tags": [ "Releases" ] }, "patch": { "operationId": "ReleasesController_update", "parameters": [ { "name": "releaseId", "required": true, "in": "path", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateReleaseDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Rename, describe or move the target date", "tags": [ "Releases" ] } }, "/api/releases/{releaseId}/progress": { "get": { "operationId": "ReleasesController_progress", "parameters": [ { "name": "releaseId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReleaseProgressDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Finished tickets out of the total", "tags": [ "Releases" ] } }, "/api/releases/{releaseId}/burnup": { "get": { "operationId": "ReleasesController_burnup", "parameters": [ { "name": "releaseId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReleaseBurnupDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Burnup: tickets in the release and finished ones, day by day", "tags": [ "Releases" ] } }, "/api/releases/{releaseId}/issues": { "get": { "operationId": "ReleasesController_issuesOf", "parameters": [ { "name": "releaseId", "required": true, "in": "path", "schema": { "type": "string" } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } }, { "name": "offset", "required": false, "in": "query", "schema": { "minimum": 0, "default": 0, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssuePageDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Tickets included in the release", "tags": [ "Releases" ] } }, "/api/releases/{releaseId}/publish": { "post": { "description": "Fails (422) while it has unfinished tickets unless `force` is true.", "operationId": "ReleasesController_publish", "parameters": [ { "name": "releaseId", "required": true, "in": "path", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublishReleaseDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Ship the release", "tags": [ "Releases" ] } }, "/api/releases/{releaseId}/archive": { "post": { "operationId": "ReleasesController_archive", "parameters": [ { "name": "releaseId", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Archive a planned release (its tickets leave it)", "tags": [ "Releases" ] } }, "/api/explore/projects": { "get": { "description": "Their board, tickets, comments, releases, activity and statistics can be read without a token too.", "operationId": "ExploreController_publicProjects", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectDto" } } } } } }, "summary": "Public projects (no token needed)", "tags": [ "Explore" ], "security": [] } }, "/api/me/notifications": { "get": { "operationId": "NotificationsController_mine", "parameters": [ { "name": "unreadOnly", "required": false, "in": "query", "description": "Only unread ones", "schema": { "default": false, "allOf": [ { "$ref": "#/components/schemas/Object" } ] } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 100, "default": 30, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MyNotificationsDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "My notifications, newest first", "tags": [ "Users" ] } }, "/api/me/notifications/read": { "post": { "operationId": "NotificationsController_markRead", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarkNotificationsReadDto" } } } }, "responses": { "200": { "description": "Done" }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Mark notifications as read (all of them without `ids`)", "tags": [ "Users" ] } }, "/api/me/notification-settings": { "get": { "operationId": "NotificationsController_settings", "parameters": [], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NotificationSettingsResponseDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Whether I get copies by e-mail", "tags": [ "Users" ] }, "put": { "operationId": "NotificationsController_updateSettings", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NotificationSettingsDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NotificationSettingsResponseDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Turn e-mail copies on or off", "tags": [ "Users" ] } }, "/api/projects/{project}/filters": { "get": { "operationId": "SavedFiltersController_list", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SavedFilterDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "My views of the project's board, then the shared ones", "tags": [ "Saved filters" ] }, "post": { "description": "Project members only. `shared` makes it visible to the whole project (not for viewers).", "operationId": "SavedFiltersController_save", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SaveFilterDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SavedFilterIdDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Save board filters under a name", "tags": [ "Saved filters" ] } }, "/api/filters/{id}": { "delete": { "operationId": "SavedFiltersController_delete", "parameters": [ { "name": "id", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "responses": { "204": { "description": "" }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Delete a saved view (whoever saved it, or an admin if shared)", "tags": [ "Saved filters" ] } }, "/api/projects/{project}/sprints": { "get": { "description": "The one under way, the planned ones, then the closed ones.", "operationId": "SprintsController_list", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SprintDto" } } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "A project's sprints", "tags": [ "Sprints" ] }, "post": { "operationId": "SprintsController_create", "parameters": [ { "name": "project", "required": true, "in": "path", "description": "Project id or key", "schema": { "example": "WEB", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSprintDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Plan a sprint (owners and admins)", "tags": [ "Sprints" ] } }, "/api/sprints/{sprint}": { "get": { "operationId": "SprintsController_findOne", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SprintDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "A sprint", "tags": [ "Sprints" ] }, "patch": { "operationId": "SprintsController_update", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSprintDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Rename, re-date or change the goal (not once closed)", "tags": [ "Sprints" ] }, "delete": { "description": "Its tickets go back to the backlog.", "operationId": "SprintsController_delete", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Delete a sprint that never started", "tags": [ "Sprints" ] } }, "/api/sprints/{sprint}/start": { "post": { "operationId": "SprintsController_start", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Start a planned sprint (only one under way per project)", "tags": [ "Sprints" ] } }, "/api/sprints/{sprint}/close": { "post": { "description": "Unfinished tickets move to `carryOverTo` (another open sprint) or back to the backlog; finished ones stay as its record.", "operationId": "SprintsController_close", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CloseSprintDto" } } } }, "responses": { "201": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Close the sprint under way", "tags": [ "Sprints" ] } }, "/api/sprints/{sprint}/progress": { "get": { "operationId": "SprintsController_progress", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SprintProgressDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Finished tickets and points", "tags": [ "Sprints" ] } }, "/api/sprints/{sprint}/burndown": { "get": { "operationId": "SprintsController_burndown", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SprintBurndownDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Open tickets and points, day by day, against the ideal line", "tags": [ "Sprints" ] } }, "/api/sprints/{sprint}/issues": { "get": { "operationId": "SprintsController_issuesOf", "parameters": [ { "name": "sprint", "required": true, "in": "path", "schema": { "format": "uuid", "type": "string" } }, { "name": "limit", "required": false, "in": "query", "schema": { "minimum": 1, "maximum": 200, "default": 50, "type": "number" } }, { "name": "offset", "required": false, "in": "query", "schema": { "minimum": 0, "default": 0, "type": "number" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssuePageDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] }, {} ], "summary": "Tickets in the sprint, in backlog order", "tags": [ "Sprints" ] } }, "/api/issues/{issue}/sprint": { "put": { "operationId": "SprintsController_setIssueSprint", "parameters": [ { "name": "issue", "required": true, "in": "path", "description": "Ticket id or key", "schema": { "example": "WEB-12", "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetIssueSprintDto" } } } }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommandResultDto" } } } }, "400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "401": { "description": "Missing or rejected Pireon token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "403": { "description": "Not a member of the project (or not allowed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "409": { "description": "Someone changed it at the same time: retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } }, "422": { "description": "Business rule (e.g. a transition the workflow forbids)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorDto" } } } } }, "security": [ { "pireon-oauth": [] }, { "pireon": [] } ], "summary": "Put the ticket in a sprint (null: the backlog)", "tags": [ "Sprints" ] } } }, "info": { "title": "Pireon TaskStream API", "description": "REST API of **Pireon TaskStream** for other apps: projects, tickets (bugs, features,\nUI changes, tasks and QA), workflow, comments, relations and releases.\n\n### Authentication\nEvery endpoint (except `/auth`, `/health` and the webhook) needs a **Pireon access\ntoken**, so any app or user that consumes it goes through Pireon's OAuth:\n\n- **Authorization Code + PKCE** against `oauth.pireon.dev/oauth/authorize`\n (the \"Authorize\" button here uses it; register `/api/docs/oauth2-redirect.html`\n as a redirect URI of the client).\n- An app with its own Pireon OAuth client can get tokens from Pireon directly and\n send them as `Authorization: Bearer `.\n\nWhat you can see and change depends on your role in each project.\n\n### Writes are eventually consistent\nCommands answer `{ id, key?, version }` as soon as the event is stored. Reads come from\na read model that catches up in milliseconds: a `GET` right after a write may still\nshow the previous version (or 404 right after a create).\n\n### Real time\nFor live updates use the GraphQL subscriptions at `/graphql` (graphql-ws).", "version": "1.0.0", "contact": {} }, "tags": [ { "name": "Projects", "description": "Projects, members, board, stats and activity" }, { "name": "Issues", "description": "Tickets: search, create, workflow, relations, comments" }, { "name": "Comments", "description": "Edit and delete comments" }, { "name": "Releases", "description": "Versions that group tickets" }, { "name": "Users", "description": "The signed-in user and the Pireon directory" }, { "name": "Auth", "description": "Pireon OAuth token proxy" }, { "name": "Health", "description": "Liveness of the API and its databases" }, { "name": "Webhooks", "description": "Called by Pireon" } ], "servers": [ { "url": "/", "description": "This server (the paths already include /api)" } ], "components": { "securitySchemes": { "pireon-oauth": { "type": "oauth2", "flows": { "authorizationCode": { "authorizationUrl": "https://oauth.pireon.dev/oauth/authorize", "tokenUrl": "/api/auth/token", "refreshUrl": "/api/auth/token", "scopes": { "users:read": "Search Pireon users" } }, "password": { "tokenUrl": "/api/auth/token", "refreshUrl": "/api/auth/token", "scopes": { "users:read": "Search Pireon users" } } }, "description": "Pireon OAuth2 (Laravel Passport)" }, "pireon": { "scheme": "bearer", "bearerFormat": "JWT", "type": "http", "description": "A Pireon access token obtained elsewhere" } }, "schemas": { "AuthorizationConfigDto": { "type": "object", "properties": { "authorizeUrl": { "type": "string", "example": "https://oauth.pireon.dev/oauth/authorize" }, "clientId": { "type": "string", "nullable": true, "description": "Public id of the authorization_code client (\"Sign in with Pireon\"); null when only email + password is configured" }, "scopes": { "example": [ "users:read" ], "type": "array", "items": { "type": "string" } }, "passwordGrant": { "type": "boolean", "description": "Whether email + password sign-in is allowed" } }, "required": [ "authorizeUrl", "clientId", "scopes", "passwordGrant" ] }, "IssueTokenDto": { "type": "object", "properties": { "grant_type": { "type": "string", "enum": [ "authorization_code", "password", "refresh_token" ] }, "code": { "type": "string", "description": "authorization_code: code returned by Pireon" }, "code_verifier": { "type": "string", "description": "authorization_code: PKCE verifier" }, "redirect_uri": { "type": "string", "description": "authorization_code: redirect URI used to authorize" }, "username": { "type": "string", "description": "password: Pireon email" }, "password": { "type": "string", "description": "password: Pireon password" }, "refresh_token": { "type": "string", "description": "refresh_token" } }, "required": [ "grant_type" ] }, "TokenResponseDto": { "type": "object", "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string", "nullable": true }, "expires_in": { "type": "number", "description": "Seconds" }, "token_type": { "type": "string", "example": "Bearer" } }, "required": [ "access_token", "refresh_token", "expires_in", "token_type" ] }, "MeDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Pireon user id" }, "name": { "type": "string" }, "email": { "type": "string" }, "isActive": { "type": "boolean" }, "roles": { "description": "Global roles in Pireon", "type": "array", "items": { "type": "string" } }, "appRoles": { "description": "Roles inside the task-stream OAuth client", "type": "array", "items": { "type": "string" } } }, "required": [ "id", "name", "email", "isActive", "roles", "appRoles" ] }, "ApiErrorDto": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 404 }, "code": { "type": "string", "description": "Domain error code", "enum": [ "NOT_FOUND", "FORBIDDEN", "VALIDATION", "CONFLICT", "BUSINESS_RULE" ] }, "message": { "description": "Human message (a list of messages for invalid input)", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } } ], "example": "Issue not found" } }, "required": [ "statusCode", "message" ] }, "UserDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Pireon user id" }, "name": { "type": "string" }, "email": { "type": "string" }, "isActive": { "type": "boolean" } }, "required": [ "id", "name", "email", "isActive" ] }, "UserRefDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Pireon user id" }, "name": { "type": "string" } }, "required": [ "id", "name" ] }, "ProjectRole": { "type": "string", "enum": [ "OWNER", "ADMIN", "MEMBER", "VIEWER" ] }, "ProjectMemberDto": { "type": "object", "properties": { "user": { "$ref": "#/components/schemas/UserRefDto" }, "role": { "allOf": [ { "$ref": "#/components/schemas/ProjectRole" } ] } }, "required": [ "user", "role" ] }, "StatusCategory": { "type": "string", "enum": [ "TODO", "IN_PROGRESS", "QA", "DONE", "CANCELLED" ] }, "SettingColor": { "type": "string", "enum": [ "slate", "stone", "violet", "blue", "sky", "teal", "green", "amber", "orange", "red", "pink" ] }, "WorkflowStatusDto": { "type": "object", "properties": { "id": { "type": "string", "example": "IN_REVIEW", "description": "Stable id on tickets" }, "name": { "type": "string", "example": "En revisión" }, "category": { "allOf": [ { "$ref": "#/components/schemas/StatusCategory" } ] }, "color": { "allOf": [ { "$ref": "#/components/schemas/SettingColor" } ] }, "requiresReason": { "type": "boolean", "description": "Entering it needs a reason" }, "archived": { "type": "boolean", "description": "No new tickets or transitions into it" } }, "required": [ "id", "name", "category", "color", "requiresReason", "archived" ] }, "StatusTransitionsDto": { "type": "object", "properties": { "from": { "type": "string", "example": "IN_QA" }, "to": { "example": [ "DONE", "QA_FAILED" ], "type": "array", "items": { "type": "string" } } }, "required": [ "from", "to" ] }, "TypeIcon": { "type": "string", "enum": [ "bug", "feature", "palette", "task", "qa", "flag", "star-fill", "rocket", "document", "light-bulb", "key", "support" ] }, "IssueTypeOptionDto": { "type": "object", "properties": { "id": { "type": "string", "example": "BUG" }, "name": { "type": "string", "example": "Bug" }, "icon": { "allOf": [ { "$ref": "#/components/schemas/TypeIcon" } ] }, "color": { "allOf": [ { "$ref": "#/components/schemas/SettingColor" } ] }, "archived": { "type": "boolean" } }, "required": [ "id", "name", "icon", "color", "archived" ] }, "AreaOptionDto": { "type": "object", "properties": { "id": { "type": "string", "example": "FRONTEND" }, "name": { "type": "string", "example": "Frontend" }, "archived": { "type": "boolean" } }, "required": [ "id", "name", "archived" ] }, "ProjectSettingsDto": { "type": "object", "properties": { "statuses": { "description": "In board order", "type": "array", "items": { "$ref": "#/components/schemas/WorkflowStatusDto" } }, "transitions": { "type": "array", "items": { "$ref": "#/components/schemas/StatusTransitionsDto" } }, "issueTypes": { "type": "array", "items": { "$ref": "#/components/schemas/IssueTypeOptionDto" } }, "areas": { "type": "array", "items": { "$ref": "#/components/schemas/AreaOptionDto" } } }, "required": [ "statuses", "transitions", "issueTypes", "areas" ] }, "ProjectDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "key": { "type": "string", "example": "WEB", "description": "Prefix of the ticket keys" }, "name": { "type": "string", "example": "Checkout revamp" }, "description": { "type": "string", "nullable": true }, "isPublic": { "type": "boolean", "description": "Readable by anyone, also without a token" }, "owner": { "$ref": "#/components/schemas/UserRefDto" }, "members": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectMemberDto" } }, "settings": { "$ref": "#/components/schemas/ProjectSettingsDto" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "version": { "type": "number", "description": "Version of the aggregate (event count)" } }, "required": [ "id", "key", "name", "description", "isPublic", "owner", "members", "settings", "createdAt", "updatedAt", "version" ] }, "CreateProjectDto": { "type": "object", "properties": { "key": { "type": "string", "example": "WEB", "description": "2-10 letters/digits starting with a letter → tickets WEB-1, WEB-2…" }, "name": { "type": "string", "example": "Checkout revamp", "maxLength": 120 }, "description": { "type": "string", "nullable": true, "maxLength": 5000 }, "isPublic": { "type": "boolean", "default": false, "description": "Anyone can read it without signing in (board, tickets, comments, releases, activity, statistics)" } }, "required": [ "key", "name" ] }, "CommandResultDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Id of the aggregate written" }, "key": { "type": "string", "description": "Human key when one was assigned (project or issue)", "example": "WEB-13" }, "version": { "type": "number", "description": "Version after the write. Writes are acknowledged at once and the read model catches up asynchronously: a GET may briefly return the previous version (or 404 right after a create)." } }, "required": [ "id", "version" ] }, "UpdateProjectDto": { "type": "object", "properties": { "name": { "type": "string", "example": "Checkout revamp", "maxLength": 120 }, "description": { "type": "string", "nullable": true, "maxLength": 5000 }, "isPublic": { "type": "boolean", "default": false, "description": "Anyone can read it without signing in (board, tickets, comments, releases, activity, statistics)" } } }, "WorkflowStatusBodyDto": { "type": "object", "properties": { "id": { "type": "string", "example": "IN_REVIEW", "description": "Never change an existing id" }, "name": { "type": "string", "example": "En revisión", "maxLength": 40 }, "category": { "allOf": [ { "$ref": "#/components/schemas/StatusCategory" } ] }, "color": { "allOf": [ { "$ref": "#/components/schemas/SettingColor" } ] }, "requiresReason": { "type": "boolean", "default": false }, "archived": { "type": "boolean", "default": false } }, "required": [ "id", "name", "category", "color" ] }, "StatusTransitionsBodyDto": { "type": "object", "properties": { "from": { "type": "string", "example": "IN_QA" }, "to": { "example": [ "DONE", "QA_FAILED" ], "type": "array", "items": { "type": "string" } } }, "required": [ "from", "to" ] }, "IssueTypeOptionBodyDto": { "type": "object", "properties": { "id": { "type": "string", "example": "SPIKE" }, "name": { "type": "string", "example": "Spike", "maxLength": 40 }, "icon": { "allOf": [ { "$ref": "#/components/schemas/TypeIcon" } ] }, "color": { "allOf": [ { "$ref": "#/components/schemas/SettingColor" } ] }, "archived": { "type": "boolean", "default": false } }, "required": [ "id", "name", "icon", "color" ] }, "AreaOptionBodyDto": { "type": "object", "properties": { "id": { "type": "string", "example": "DATA" }, "name": { "type": "string", "example": "Datos", "maxLength": 40 }, "archived": { "type": "boolean", "default": false } }, "required": [ "id", "name" ] }, "ProjectSettingsBodyDto": { "type": "object", "properties": { "statuses": { "description": "In board order. Values cannot be removed: archive them instead.", "type": "array", "items": { "$ref": "#/components/schemas/WorkflowStatusBodyDto" } }, "transitions": { "type": "array", "items": { "$ref": "#/components/schemas/StatusTransitionsBodyDto" } }, "issueTypes": { "type": "array", "items": { "$ref": "#/components/schemas/IssueTypeOptionBodyDto" } }, "areas": { "type": "array", "items": { "$ref": "#/components/schemas/AreaOptionBodyDto" } } }, "required": [ "statuses", "transitions", "issueTypes", "areas" ] }, "IssuePriority": { "type": "string", "enum": [ "LOWEST", "LOW", "MEDIUM", "HIGH", "CRITICAL" ] }, "ReleaseRefDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "name": { "type": "string", "example": "v1.4.0" } }, "required": [ "id", "name" ] }, "SprintRefDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "name": { "type": "string", "example": "Sprint 14" } }, "required": [ "id", "name" ] }, "IssueLinkType": { "type": "string", "enum": [ "BLOCKS", "DEPENDS_ON", "TESTS", "DUPLICATES", "RELATES_TO" ] }, "LinkDirection": { "type": "string", "enum": [ "OUTWARD", "INWARD" ], "description": "OUTWARD: this issue → other. INWARD: other → this issue." }, "IssueLinkDto": { "type": "object", "properties": { "type": { "allOf": [ { "$ref": "#/components/schemas/IssueLinkType" } ] }, "direction": { "description": "OUTWARD: this issue → other. INWARD: other → this issue.", "allOf": [ { "$ref": "#/components/schemas/LinkDirection" } ] }, "issueId": { "type": "string", "format": "uuid" }, "issueKey": { "type": "string", "example": "WEB-3" } }, "required": [ "type", "direction", "issueId", "issueKey" ] }, "AttachmentDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "fileName": { "type": "string", "example": "captura-login.png" }, "mimeType": { "type": "string", "example": "image/png" }, "size": { "type": "number", "description": "Bytes", "example": 48213 }, "uploadedBy": { "$ref": "#/components/schemas/UserRefDto" }, "uploadedAt": { "type": "string", "format": "date-time" }, "commentId": { "type": "string", "nullable": true, "format": "uuid", "description": "The comment it was attached to, if any" } }, "required": [ "id", "fileName", "mimeType", "size", "uploadedBy", "uploadedAt", "commentId" ] }, "IssueParentDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "key": { "type": "string", "example": "WEB-3" }, "title": { "type": "string", "example": "Pago con tarjeta" } }, "required": [ "id", "key", "title" ] }, "ChecklistItemDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "text": { "type": "string", "example": "Actualizar el changelog" }, "done": { "type": "boolean" } }, "required": [ "id", "text", "done" ] }, "IssueDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "projectId": { "type": "string", "format": "uuid" }, "projectKey": { "type": "string", "example": "WEB" }, "number": { "type": "number", "example": 12 }, "key": { "type": "string", "example": "WEB-12", "description": "Human key" }, "type": { "type": "string", "example": "BUG", "description": "A ticket type id" }, "area": { "type": "string", "nullable": true, "example": "FRONTEND" }, "title": { "type": "string" }, "description": { "type": "string", "nullable": true }, "status": { "type": "string", "example": "IN_PROGRESS", "description": "A status id" }, "statusCategory": { "allOf": [ { "$ref": "#/components/schemas/StatusCategory" } ] }, "allowedTransitions": { "description": "Statuses this ticket can move to next (project's workflow)", "type": "array", "items": { "type": "string" } }, "priority": { "allOf": [ { "$ref": "#/components/schemas/IssuePriority" } ] }, "reporter": { "$ref": "#/components/schemas/UserRefDto" }, "assignee": { "nullable": true, "type": "object", "allOf": [ { "$ref": "#/components/schemas/UserRefDto" } ] }, "release": { "nullable": true, "type": "object", "allOf": [ { "$ref": "#/components/schemas/ReleaseRefDto" } ] }, "sprint": { "nullable": true, "type": "object", "allOf": [ { "$ref": "#/components/schemas/SprintRefDto" } ] }, "labels": { "type": "array", "items": { "type": "string" } }, "figmaUrl": { "type": "string", "nullable": true, "description": "Figma frame" }, "storyPoints": { "type": "number", "nullable": true }, "dueDate": { "type": "string", "nullable": true, "format": "date" }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/IssueLinkDto" } }, "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/AttachmentDto" } }, "watchers": { "description": "People following it", "type": "array", "items": { "$ref": "#/components/schemas/UserRefDto" } }, "parent": { "nullable": true, "description": "The epic or ticket this one breaks down", "type": "object", "allOf": [ { "$ref": "#/components/schemas/IssueParentDto" } ] }, "rank": { "type": "string", "description": "Place in the backlog and its board column (ascending, as text)" }, "checklist": { "type": "array", "items": { "$ref": "#/components/schemas/ChecklistItemDto" } }, "commentCount": { "type": "number" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "version": { "type": "number" } }, "required": [ "id", "projectId", "projectKey", "number", "key", "type", "area", "title", "description", "status", "statusCategory", "allowedTransitions", "priority", "reporter", "assignee", "release", "sprint", "labels", "figmaUrl", "storyPoints", "dueDate", "links", "attachments", "watchers", "parent", "rank", "checklist", "commentCount", "createdAt", "updatedAt", "version" ] }, "BoardColumnDto": { "type": "object", "properties": { "status": { "type": "string", "example": "IN_PROGRESS" }, "issues": { "type": "array", "items": { "$ref": "#/components/schemas/IssueDto" } }, "total": { "type": "number", "description": "Tickets in the column (may exceed `issues`)" } }, "required": [ "status", "issues", "total" ] }, "CountByStatusDto": { "type": "object", "properties": { "key": { "type": "string", "example": "IN_PROGRESS", "description": "Status id" }, "count": { "type": "number" } }, "required": [ "key", "count" ] }, "CountByKeyDto": { "type": "object", "properties": { "key": { "type": "string", "description": "Type, priority or area (\"NONE\" = unset)" }, "count": { "type": "number" } }, "required": [ "key", "count" ] }, "CountByAssigneeDto": { "type": "object", "properties": { "user": { "nullable": true, "description": "Null = unassigned", "type": "object", "allOf": [ { "$ref": "#/components/schemas/UserRefDto" } ] }, "count": { "type": "number" } }, "required": [ "user", "count" ] }, "ProjectStatsDto": { "type": "object", "properties": { "total": { "type": "number" }, "open": { "type": "number", "description": "Not done nor cancelled" }, "byStatus": { "type": "array", "items": { "$ref": "#/components/schemas/CountByStatusDto" } }, "byType": { "type": "array", "items": { "$ref": "#/components/schemas/CountByKeyDto" } }, "byPriority": { "type": "array", "items": { "$ref": "#/components/schemas/CountByKeyDto" } }, "byArea": { "type": "array", "items": { "$ref": "#/components/schemas/CountByKeyDto" } }, "byAssignee": { "description": "Open tickets per person", "type": "array", "items": { "$ref": "#/components/schemas/CountByAssigneeDto" } } }, "required": [ "total", "open", "byStatus", "byType", "byPriority", "byArea", "byAssignee" ] }, "CreatedResolvedDto": { "type": "object", "properties": { "week": { "type": "string", "format": "date", "description": "Monday of the week" }, "created": { "type": "number" }, "resolved": { "type": "number" } }, "required": [ "week", "created", "resolved" ] }, "FlowSeriesDto": { "type": "object", "properties": { "status": { "type": "string", "example": "IN_PROGRESS" }, "counts": { "description": "One value per date", "type": "array", "items": { "type": "number" } } }, "required": [ "status", "counts" ] }, "CumulativeFlowDto": { "type": "object", "properties": { "dates": { "type": "array", "items": { "type": "string", "format": "date" } }, "series": { "type": "array", "items": { "$ref": "#/components/schemas/FlowSeriesDto" } } }, "required": [ "dates", "series" ] }, "DurationStatsDto": { "type": "object", "properties": { "count": { "type": "number" }, "averageDays": { "type": "number", "nullable": true }, "p85Days": { "type": "number", "nullable": true, "description": "85% of tickets take at most this long" } }, "required": [ "count", "averageDays", "p85Days" ] }, "ThroughputDto": { "type": "object", "properties": { "week": { "type": "string", "format": "date" }, "user": { "nullable": true, "type": "object", "allOf": [ { "$ref": "#/components/schemas/UserRefDto" } ] }, "count": { "type": "number" } }, "required": [ "week", "user", "count" ] }, "QaStatsDto": { "type": "object", "properties": { "passed": { "type": "number", "description": "Left QA to a done status" }, "failed": { "type": "number", "description": "Left QA back to work" }, "failureRate": { "type": "number", "nullable": true, "minimum": 0, "maximum": 1 } }, "required": [ "passed", "failed", "failureRate" ] }, "ProjectAnalyticsDto": { "type": "object", "properties": { "from": { "type": "string", "format": "date-time" }, "to": { "type": "string", "format": "date-time" }, "createdVsResolved": { "type": "array", "items": { "$ref": "#/components/schemas/CreatedResolvedDto" } }, "cumulativeFlow": { "description": "Tickets in each status at the end of every day", "allOf": [ { "$ref": "#/components/schemas/CumulativeFlowDto" } ] }, "cycleTime": { "description": "Start of work → done", "allOf": [ { "$ref": "#/components/schemas/DurationStatsDto" } ] }, "leadTime": { "description": "Creation → done", "allOf": [ { "$ref": "#/components/schemas/DurationStatsDto" } ] }, "throughput": { "type": "array", "items": { "$ref": "#/components/schemas/ThroughputDto" } }, "qa": { "$ref": "#/components/schemas/QaStatsDto" } }, "required": [ "from", "to", "createdVsResolved", "cumulativeFlow", "cycleTime", "leadTime", "throughput", "qa" ] }, "ActivityDto": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "type": "string", "example": "IssueStatusChanged" }, "projectId": { "type": "string", "format": "uuid" }, "issueId": { "type": "string", "nullable": true }, "issueKey": { "type": "string", "nullable": true, "example": "WEB-12" }, "actor": { "$ref": "#/components/schemas/UserRefDto" }, "summary": { "type": "string", "example": "Ana movió WEB-12 de En curso a En revisión" }, "occurredAt": { "type": "string", "format": "date-time" } }, "required": [ "id", "type", "projectId", "issueId", "issueKey", "actor", "summary", "occurredAt" ] }, "AddMemberDto": { "type": "object", "properties": { "userId": { "type": "string", "description": "Pireon user id (see GET /users)" }, "role": { "default": "MEMBER", "allOf": [ { "$ref": "#/components/schemas/ProjectRole" } ] } }, "required": [ "userId" ] }, "ChangeMemberRoleDto": { "type": "object", "properties": { "role": { "allOf": [ { "$ref": "#/components/schemas/ProjectRole" } ] } }, "required": [ "role" ] }, "IssuePageDto": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/IssueDto" } }, "total": { "type": "number", "description": "Total matches (for pagination)" } }, "required": [ "items", "total" ] }, "IssueSort": { "type": "string", "enum": [ "RECENT", "RANK" ] }, "CreateIssueDto": { "type": "object", "properties": { "description": { "type": "string", "nullable": true, "maxLength": 50000 }, "area": { "type": "string", "nullable": true, "example": "FRONTEND", "description": "An area id of the project's settings" }, "priority": { "allOf": [ { "$ref": "#/components/schemas/IssuePriority" } ] }, "labels": { "maxItems": 20, "type": "array", "items": { "type": "string" } }, "figmaUrl": { "type": "string", "nullable": true, "description": "Figma frame (https) for UI changes" }, "storyPoints": { "type": "number", "nullable": true, "minimum": 0, "maximum": 100 }, "dueDate": { "type": "string", "nullable": true, "format": "date" }, "type": { "type": "string", "example": "BUG", "description": "A ticket type id of the project's settings" }, "title": { "type": "string", "example": "El botón de pagar no responde en Safari", "maxLength": 255 }, "assigneeId": { "type": "string", "nullable": true, "description": "Pireon user id" }, "releaseId": { "type": "string", "nullable": true, "format": "uuid" }, "parent": { "type": "string", "nullable": true, "example": "WEB-3", "description": "Epic or ticket of the same project the new one breaks down (id or key)" } }, "required": [ "type", "title" ] }, "ChildProgressDto": { "type": "object", "properties": { "total": { "type": "number" }, "finished": { "type": "number", "description": "Done or cancelled" }, "percent": { "type": "number", "minimum": 0, "maximum": 100 }, "storyPoints": { "type": "number" }, "finishedStoryPoints": { "type": "number" } }, "required": [ "total", "finished", "percent", "storyPoints", "finishedStoryPoints" ] }, "EpicDto": { "type": "object", "properties": { "issue": { "$ref": "#/components/schemas/IssueDto" }, "progress": { "$ref": "#/components/schemas/ChildProgressDto" } }, "required": [ "issue", "progress" ] }, "UpdateIssueDto": { "type": "object", "properties": { "description": { "type": "string", "nullable": true, "maxLength": 50000 }, "area": { "type": "string", "nullable": true, "example": "FRONTEND", "description": "An area id of the project's settings" }, "priority": { "allOf": [ { "$ref": "#/components/schemas/IssuePriority" } ] }, "labels": { "maxItems": 20, "type": "array", "items": { "type": "string" } }, "figmaUrl": { "type": "string", "nullable": true, "description": "Figma frame (https) for UI changes" }, "storyPoints": { "type": "number", "nullable": true, "minimum": 0, "maximum": 100 }, "dueDate": { "type": "string", "nullable": true, "format": "date" }, "type": { "type": "string", "example": "FEATURE", "description": "A ticket type id" }, "title": { "type": "string", "maxLength": 255 } } }, "ChangeStatusDto": { "type": "object", "properties": { "status": { "type": "string", "example": "IN_REVIEW", "description": "A status id of the project's settings, among the ticket's allowedTransitions" }, "reason": { "type": "string", "nullable": true, "description": "Required by statuses with requiresReason (e.g. QA_FAILED)" } }, "required": [ "status" ] }, "AssignIssueDto": { "type": "object", "properties": { "assigneeId": { "type": "string", "nullable": true, "description": "Pireon user id of a project member, or null to unassign" } }, "required": [ "assigneeId" ] }, "SetIssueReleaseDto": { "type": "object", "properties": { "releaseId": { "type": "string", "nullable": true, "format": "uuid", "description": "Planned release, or null to take the ticket out" } }, "required": [ "releaseId" ] }, "SetIssueParentDto": { "type": "object", "properties": { "parent": { "type": "string", "nullable": true, "example": "WEB-3", "description": "Epic or ticket of the same project (id or key), or null to take it back to the top" } }, "required": [ "parent" ] }, "RankIssueDto": { "type": "object", "properties": { "above": { "type": "string", "nullable": true, "example": "WEB-4", "description": "The ticket that ends up right above (id or key; null: the top)" }, "below": { "type": "string", "nullable": true, "example": "WEB-9", "description": "The ticket that ends up right below (id or key; null: the bottom)" } } }, "ChecklistItemBodyDto": { "type": "object", "properties": { "text": { "type": "string", "example": "Actualizar el changelog", "maxLength": 300 } }, "required": [ "text" ] }, "UpdateChecklistItemDto": { "type": "object", "properties": { "text": { "type": "string", "maxLength": 300 }, "done": { "type": "boolean" } } }, "LinkIssueDto": { "type": "object", "properties": { "type": { "allOf": [ { "$ref": "#/components/schemas/IssueLinkType" } ] }, "targetIssue": { "type": "string", "example": "API-3", "description": "Other ticket: id or key" } }, "required": [ "type", "targetIssue" ] }, "CommentDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "issueId": { "type": "string", "format": "uuid" }, "author": { "$ref": "#/components/schemas/UserRefDto" }, "body": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "editedAt": { "type": "string", "nullable": true, "format": "date-time" }, "version": { "type": "number" } }, "required": [ "id", "issueId", "author", "body", "createdAt", "editedAt", "version" ] }, "CommentPageDto": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/CommentDto" } }, "total": { "type": "number" } }, "required": [ "items", "total" ] }, "CommentBodyDto": { "type": "object", "properties": { "body": { "type": "string", "example": "Reproducido en Safari 17.", "maxLength": 20000 } }, "required": [ "body" ] }, "AttachFileDto": { "type": "object", "properties": { "file": { "type": "string", "format": "binary", "description": "The file" }, "commentId": { "type": "string", "format": "uuid", "description": "One of the ticket's comments, to show the file under it" } }, "required": [ "file" ] }, "ReleaseStatus": { "type": "string", "enum": [ "PLANNED", "RELEASED", "ARCHIVED" ] }, "ReleaseDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "projectId": { "type": "string", "format": "uuid" }, "name": { "type": "string", "example": "v1.4.0" }, "description": { "type": "string", "nullable": true }, "targetDate": { "type": "string", "nullable": true, "format": "date" }, "status": { "allOf": [ { "$ref": "#/components/schemas/ReleaseStatus" } ] }, "releasedAt": { "type": "string", "nullable": true, "format": "date-time" }, "createdAt": { "type": "string", "format": "date-time" }, "version": { "type": "number" } }, "required": [ "id", "projectId", "name", "description", "targetDate", "status", "releasedAt", "createdAt", "version" ] }, "CreateReleaseDto": { "type": "object", "properties": { "name": { "type": "string", "example": "v1.4.0", "maxLength": 60 }, "description": { "type": "string", "nullable": true, "maxLength": 5000 }, "targetDate": { "type": "string", "nullable": true, "format": "date", "example": "2026-11-14" } }, "required": [ "name" ] }, "UpdateReleaseDto": { "type": "object", "properties": { "name": { "type": "string", "example": "v1.4.0", "maxLength": 60 }, "description": { "type": "string", "nullable": true, "maxLength": 5000 }, "targetDate": { "type": "string", "nullable": true, "format": "date", "example": "2026-11-14" } } }, "ReleaseProgressDto": { "type": "object", "properties": { "total": { "type": "number" }, "finished": { "type": "number" }, "percent": { "type": "number", "minimum": 0, "maximum": 100 }, "byStatus": { "type": "array", "items": { "$ref": "#/components/schemas/CountByStatusDto" } } }, "required": [ "total", "finished", "percent", "byStatus" ] }, "ReleaseBurnupDto": { "type": "object", "properties": { "releaseId": { "type": "string", "format": "uuid" }, "targetDate": { "type": "string", "nullable": true, "format": "date" }, "dates": { "type": "array", "items": { "type": "string", "format": "date" } }, "scope": { "description": "Tickets in the release (not cancelled)", "type": "array", "items": { "type": "number" } }, "done": { "type": "array", "items": { "type": "number" } } }, "required": [ "releaseId", "targetDate", "dates", "scope", "done" ] }, "PublishReleaseDto": { "type": "object", "properties": { "force": { "type": "boolean", "default": false, "description": "Publish even with unfinished tickets" } } }, "Object": { "type": "object", "properties": {} }, "NotificationKind": { "type": "string", "enum": [ "ASSIGNED", "STATUS_CHANGED", "QA_FAILED", "COMMENTED", "MENTIONED", "WATCHED", "ADDED_TO_PROJECT", "REMINDER" ] }, "NotificationDto": { "type": "object", "properties": { "id": { "type": "string" }, "kind": { "allOf": [ { "$ref": "#/components/schemas/NotificationKind" } ] }, "projectId": { "type": "string", "format": "uuid" }, "projectKey": { "type": "string", "example": "WEB" }, "issueId": { "type": "string", "nullable": true, "format": "uuid" }, "issueKey": { "type": "string", "nullable": true, "example": "WEB-12" }, "actor": { "$ref": "#/components/schemas/UserRefDto" }, "summary": { "type": "string", "example": "Ana te asignó WEB-12: Login roto en Safari" }, "readAt": { "type": "string", "nullable": true, "format": "date-time", "description": "Null: unread" }, "createdAt": { "type": "string", "format": "date-time" } }, "required": [ "id", "kind", "projectId", "projectKey", "issueId", "issueKey", "actor", "summary", "readAt", "createdAt" ] }, "MyNotificationsDto": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/NotificationDto" } }, "unread": { "type": "number", "description": "All my unread ones, not just these" } }, "required": [ "items", "unread" ] }, "MarkNotificationsReadDto": { "type": "object", "properties": { "ids": { "description": "Omit to mark all of them", "type": "array", "items": { "type": "string" } } } }, "NotificationSettingsResponseDto": { "type": "object", "properties": { "email": { "type": "boolean", "description": "Copies by e-mail" }, "emailAvailable": { "type": "boolean", "description": "Whether this installation can send e-mail" } }, "required": [ "email", "emailAvailable" ] }, "NotificationSettingsDto": { "type": "object", "properties": { "email": { "type": "boolean", "description": "Copies by e-mail" } }, "required": [ "email" ] }, "SavedFilterCriteriaResponseDto": { "type": "object", "properties": { "types": { "type": "array", "items": { "type": "string" } }, "areas": { "type": "array", "items": { "type": "string" } }, "priorities": { "type": "array", "items": { "$ref": "#/components/schemas/IssuePriority" } }, "assigneeId": { "type": "string", "nullable": true }, "unassigned": { "type": "boolean" }, "releaseId": { "type": "string", "nullable": true, "format": "uuid" }, "labels": { "type": "array", "items": { "type": "string" } }, "search": { "type": "string", "nullable": true } } }, "SavedFilterDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "projectId": { "type": "string", "format": "uuid" }, "owner": { "$ref": "#/components/schemas/UserRefDto" }, "name": { "type": "string", "example": "Bugs críticos de frontend" }, "shared": { "type": "boolean", "description": "Visible to the whole project" }, "criteria": { "$ref": "#/components/schemas/SavedFilterCriteriaResponseDto" }, "createdAt": { "type": "string", "format": "date-time" } }, "required": [ "id", "projectId", "owner", "name", "shared", "criteria", "createdAt" ] }, "SavedFilterCriteriaDto": { "type": "object", "properties": { "types": { "description": "Ticket type ids", "type": "array", "items": { "type": "string" } }, "areas": { "description": "Area ids", "type": "array", "items": { "type": "string" } }, "priorities": { "type": "array", "items": { "$ref": "#/components/schemas/IssuePriority" } }, "assigneeId": { "type": "string", "nullable": true, "description": "Pireon user id" }, "unassigned": { "type": "boolean" }, "releaseId": { "type": "string", "nullable": true, "format": "uuid" }, "labels": { "type": "array", "items": { "type": "string" } }, "search": { "type": "string", "nullable": true, "maxLength": 200 } } }, "SaveFilterDto": { "type": "object", "properties": { "name": { "type": "string", "example": "Bugs críticos de frontend", "maxLength": 60 }, "shared": { "type": "object", "default": false, "description": "Visible to the whole project (members, not viewers, share)" }, "criteria": { "$ref": "#/components/schemas/SavedFilterCriteriaDto" } }, "required": [ "name", "criteria" ] }, "SavedFilterIdDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" } }, "required": [ "id" ] }, "SprintStatus": { "type": "string", "enum": [ "PLANNED", "ACTIVE", "CLOSED" ] }, "SprintDto": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "projectId": { "type": "string", "format": "uuid" }, "name": { "type": "string", "example": "Sprint 14" }, "goal": { "type": "string", "nullable": true }, "startDate": { "type": "string", "format": "date" }, "endDate": { "type": "string", "format": "date", "description": "Last day, included" }, "status": { "allOf": [ { "$ref": "#/components/schemas/SprintStatus" } ] }, "startedAt": { "type": "string", "nullable": true, "format": "date-time" }, "closedAt": { "type": "string", "nullable": true, "format": "date-time" }, "createdAt": { "type": "string", "format": "date-time" }, "version": { "type": "number" } }, "required": [ "id", "projectId", "name", "goal", "startDate", "endDate", "status", "startedAt", "closedAt", "createdAt", "version" ] }, "CreateSprintDto": { "type": "object", "properties": { "name": { "type": "string", "example": "Sprint 14", "maxLength": 80 }, "goal": { "type": "string", "nullable": true, "maxLength": 500, "example": "Pagos con tarjeta en producción" }, "startDate": { "type": "string", "format": "date", "example": "2026-10-12" }, "endDate": { "type": "string", "format": "date", "example": "2026-10-23", "description": "Last day, included" } }, "required": [ "name", "startDate", "endDate" ] }, "UpdateSprintDto": { "type": "object", "properties": { "name": { "type": "string", "example": "Sprint 14", "maxLength": 80 }, "goal": { "type": "string", "nullable": true, "maxLength": 500, "example": "Pagos con tarjeta en producción" }, "startDate": { "type": "string", "format": "date", "example": "2026-10-12" }, "endDate": { "type": "string", "format": "date", "example": "2026-10-23", "description": "Last day, included" } } }, "CloseSprintDto": { "type": "object", "properties": { "carryOverTo": { "type": "string", "nullable": true, "format": "uuid", "description": "Open sprint of the same project that takes the unfinished tickets; null or absent: back to the backlog" } } }, "SprintProgressDto": { "type": "object", "properties": { "total": { "type": "number" }, "finished": { "type": "number", "description": "Done or cancelled" }, "percent": { "type": "number", "minimum": 0, "maximum": 100 }, "storyPoints": { "type": "number" }, "finishedStoryPoints": { "type": "number" } }, "required": [ "total", "finished", "percent", "storyPoints", "finishedStoryPoints" ] }, "SprintBurndownDto": { "type": "object", "properties": { "sprintId": { "type": "string", "format": "uuid" }, "dates": { "type": "array", "items": { "type": "string", "format": "date" } }, "scope": { "nullable": true, "description": "Tickets in the sprint (null: days to come)", "type": "array", "items": { "type": "number" } }, "remaining": { "nullable": true, "type": "array", "items": { "type": "number" } }, "remainingPoints": { "nullable": true, "type": "array", "items": { "type": "number" } }, "ideal": { "type": "array", "items": { "type": "number" } } }, "required": [ "sprintId", "dates", "scope", "remaining", "remainingPoints", "ideal" ] }, "SetIssueSprintDto": { "type": "object", "properties": { "sprintId": { "type": "string", "nullable": true, "format": "uuid", "description": "Open sprint of the project, or null for the backlog" } }, "required": [ "sprintId" ] } } } }