Files
task-stream/apps/api/openapi.json
Josep Piguillem 45a3dc1e16 feat: a roadmap of epics over time
Tickets get a start date next to their due date, both editable on the
ticket page. The Hoja de ruta tab lays the epics out over the months as
bars filled with their progress, with sprints and releases as landmarks
and a line for today.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 15:14:32 +02:00

10179 lines
260 KiB
JSON

{
"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>/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 <token>`.\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"
},
"wipLimit": {
"type": "number",
"nullable": true,
"description": "Work-in-progress limit (a warning, not a lock)"
}
},
"required": [
"id",
"name",
"category",
"color",
"requiresReason",
"archived",
"wipLimit"
]
},
"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
},
"wipLimit": {
"type": "number",
"nullable": true,
"minimum": 1,
"maximum": 999,
"description": "Work-in-progress limit (null: none)"
}
},
"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
},
"startDate": {
"type": "string",
"nullable": true,
"format": "date",
"description": "When work should start (roadmap)"
},
"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",
"startDate",
"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
},
"startDate": {
"type": "string",
"nullable": true,
"format": "date",
"description": "When work should start (roadmap)"
},
"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
},
"startDate": {
"type": "string",
"nullable": true,
"format": "date",
"description": "When work should start (roadmap)"
},
"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"
]
}
}
}
}