Files
task-stream/apps/api/openapi.json
Josep Piguillem c91df110f8 feat: steadier live updates and notices for public proposals
- The web pings the live connection, reconnects when it goes quiet and
  reloads what each screen shows after reconnecting.
- Dropping a card on a column it cannot go to puts it back.
- Owners and admins get a notice when a proposal arrives.
- The proposal limit lives in Redis, so it holds across instances.
- REST tells whether I voted; pasted images leave the attachment list.
- Deleting a project removes its Git integration; no lint warnings left.
- Reactions and the blocked badge are components of their own.
- Docs: what is done and what is left (chapter 10), Word and PDF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 19:57:21 +02:00

13520 lines
347 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 or PIREON_PASSWORD_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 the secret of the Pireon client that registered the webhook (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": "watching",
"required": false,
"in": "query",
"description": "Only the tickets I follow (with assignedToMe=false, whoever they are assigned to)",
"schema": {
"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"
}
}
},
{
"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": "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": "watching",
"required": false,
"in": "query",
"description": "Only the tickets I follow (none without a token)",
"schema": {
"type": "boolean"
}
},
{
"name": "dueFrom",
"required": false,
"in": "query",
"description": "Due on or after this day",
"schema": {
"format": "date",
"type": "string"
}
},
{
"name": "dueTo",
"required": false,
"in": "query",
"description": "Due on or before this day",
"schema": {
"format": "date",
"type": "string"
}
},
{
"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"
]
},
"delete": {
"description": "Whoever opened it, or an owner/admin. Hidden everywhere; restore it within 30 days or it is deleted for good.",
"operationId": "IssuesController_trash",
"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": "Move the ticket to the trash",
"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}/restore": {
"post": {
"operationId": "IssuesController_restore",
"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": "Bring the ticket back from the trash",
"tags": [
"Issues"
]
}
},
"/api/issues/{issue}/vote": {
"put": {
"description": "Anyone signed in, on a public project (that is the point: the people it is for say what they want); members on a private one. Voting twice changes nothing.",
"operationId": "IssuesController_vote",
"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": "Vote for the ticket",
"tags": [
"Issues"
]
},
"delete": {
"operationId": "IssuesController_unvote",
"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": "Take back my vote for the ticket",
"tags": [
"Issues"
]
}
},
"/api/issues/{issue}/duplicate": {
"post": {
"description": "Copies what it says (type, title, description, area, priority, labels, Figma, estimate, dates, parent and checklist steps, unticked), not where it stands: the copy starts in the first status, unassigned, out of sprints and releases, without comments or files. The result carries its key.",
"operationId": "IssuesController_duplicate",
"parameters": [
{
"name": "issue",
"required": true,
"in": "path",
"description": "Ticket id or key",
"schema": {
"example": "WEB-12",
"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": "Duplicate the ticket",
"tags": [
"Issues"
]
}
},
"/api/projects/{project}/trash": {
"get": {
"operationId": "IssuesController_trashed",
"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/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": "The project's tickets in the trash, newest first",
"tags": [
"Issues"
]
}
},
"/api/issues/bulk": {
"post": {
"description": "Each ticket goes through the normal rules (permissions, workflow, open sprints and releases) and may refuse on its own; the answer says which.",
"operationId": "IssuesController_bulkUpdate",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkUpdateIssuesDto"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkResultDto"
}
}
}
},
"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": "The same change on up to 100 tickets",
"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/AddCommentDto"
}
}
}
},
"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, or answer a comment (replyTo)",
"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/AttachmentResultDto"
}
}
}
},
"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/comments/{commentId}/reactions": {
"post": {
"description": "One of 👍 👎 😄 🎉 😕 ❤️ 🚀 👀; repeating it changes nothing.",
"operationId": "CommentsController_react",
"parameters": [
{
"name": "commentId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReactToCommentDto"
}
}
}
},
"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": "React to a comment, or take the reaction back (members)",
"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}/notes": {
"put": {
"description": "Also after the release ships; not once archived.",
"operationId": "ReleasesController_writeNotes",
"parameters": [
{
"name": "releaseId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReleaseNotesDto"
}
}
}
},
"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": "Write the release notes (Markdown)",
"tags": [
"Releases"
]
}
},
"/api/releases/{releaseId}/notes/draft": {
"get": {
"description": "Grouped by type; nothing is saved.",
"operationId": "ReleasesController_notesDraft",
"parameters": [
{
"name": "releaseId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReleaseNotesDraftDto"
}
}
}
},
"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 Markdown draft of the notes from the finished tickets",
"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/explore/projects/{project}/showcase": {
"get": {
"description": "For public websites: epics with their dates and progress, the latest releases (with the notes of shipped ones), the sprint under way and open tickets labelled good-first-issue. Paths point into the web app.",
"operationId": "ExploreController_showcase",
"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/ShowcaseDto"
}
}
}
},
"404": {
"description": "Not a public project"
}
},
"summary": "A public project's showcase (no token needed)",
"tags": [
"Explore"
],
"security": []
}
},
"/api/explore/projects/{project}/proposals": {
"post": {
"description": "For public projects that take proposals. It becomes a ticket labelled `propuesta`, opened by TaskStream in the first status (Bug or Feature), signed with `author` if given. Five per address every 15 minutes.",
"operationId": "ExploreController_propose",
"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/ProposalDto"
}
}
}
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProposalResultDto"
}
}
}
},
"403": {
"description": "It does not take proposals"
},
"404": {
"description": "Not a public project"
},
"429": {
"description": "Too many from this address"
}
},
"summary": "Report a bug or propose an idea (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,
"type": "boolean"
}
},
{
"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"
]
}
},
"/api/projects/{project}/git-integration": {
"get": {
"operationId": "GitController_integration",
"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/GitIntegrationDto"
}
}
}
},
"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 project's repositories and the webhook URL they share (secrets, for admins)",
"tags": [
"Git"
]
}
},
"/api/projects/{project}/git-integration/repositories": {
"post": {
"description": "Turns the integration on with the first one. Every repository uses the same webhook URL; its secret tells them apart.",
"operationId": "GitController_addRepository",
"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/AddGitRepositoryDto"
}
}
}
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GitRepositoryDto"
}
}
}
},
"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 repository, with its own secret (owners and admins)",
"tags": [
"Git"
]
}
},
"/api/projects/{project}/git-integration/repositories/{repository}/secret": {
"post": {
"operationId": "GitController_rotateSecret",
"parameters": [
{
"name": "project",
"required": true,
"in": "path",
"description": "Project id or key",
"schema": {
"example": "WEB",
"type": "string"
}
},
{
"name": "repository",
"required": true,
"in": "path",
"description": "Repository id",
"schema": {
"type": "string"
}
}
],
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GitRepositoryDto"
}
}
}
},
"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": "Give a repository a new secret (the old one stops working)",
"tags": [
"Git"
]
}
},
"/api/projects/{project}/git-integration/repositories/{repository}": {
"delete": {
"operationId": "GitController_removeRepository",
"parameters": [
{
"name": "project",
"required": true,
"in": "path",
"description": "Project id or key",
"schema": {
"example": "WEB",
"type": "string"
}
},
{
"name": "repository",
"required": true,
"in": "path",
"description": "Repository id",
"schema": {
"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": "Remove a repository: its webhooks are refused, what it linked stays",
"tags": [
"Git"
]
}
},
"/api/webhooks/git/{project}": {
"post": {
"description": "Push and pull/merge request events from any repository of the project; the secret it signs with says which (GitHub and Gitea: HMAC-SHA256 of the body; GitLab: X-Gitlab-Token). Other events are acknowledged and ignored.",
"operationId": "GitController_receive",
"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/GitDeliveryResultDto"
}
}
}
},
"403": {
"description": "Unknown project, integration off or bad signature"
}
},
"summary": "Webhook for GitHub, Gitea or GitLab (called by the Git host)",
"tags": [
"Git"
],
"security": []
}
},
"/api/webhook-events": {
"get": {
"operationId": "WebhooksController_events",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"security": [
{
"pireon-oauth": []
},
{
"pireon": []
}
],
"summary": "Event names a webhook can subscribe to",
"tags": [
"Webhooks"
]
}
},
"/api/projects/{project}/webhooks": {
"get": {
"operationId": "WebhooksController_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/WebhookDto"
}
}
}
}
},
"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 project's webhooks (owners and admins)",
"tags": [
"Webhooks"
]
},
"post": {
"description": "The answer carries the secret, the only time it is shown.",
"operationId": "WebhooksController_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/CreateWebhookDto"
}
}
}
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookCreatedDto"
}
}
}
},
"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 webhook",
"tags": [
"Webhooks"
]
}
},
"/api/outgoing-webhooks/{webhook}": {
"patch": {
"operationId": "WebhooksController_update",
"parameters": [
{
"name": "webhook",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateWebhookDto"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookDto"
}
}
}
},
"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 the URL or the events, pause or resume",
"tags": [
"Webhooks"
]
},
"delete": {
"operationId": "WebhooksController_delete",
"parameters": [
{
"name": "webhook",
"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 webhook",
"tags": [
"Webhooks"
]
}
},
"/api/outgoing-webhooks/{webhook}/test": {
"post": {
"operationId": "WebhooksController_test",
"parameters": [
{
"name": "webhook",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookDeliveryDto"
}
}
}
},
"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": "Send a ping now and tell how it went",
"tags": [
"Webhooks"
]
}
},
"/api/projects/{project}/export.csv": {
"get": {
"description": "UTF-8 with BOM. Cells that a spreadsheet would run as a formula start with a quote mark.",
"operationId": "TransferController_exportCsv",
"parameters": [
{
"name": "project",
"required": true,
"in": "path",
"description": "Project id or key",
"schema": {
"example": "WEB",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The CSV file"
},
"400": {
"description": "Invalid input",
"content": {
"text/csv": {
"schema": {
"$ref": "#/components/schemas/ApiErrorDto"
}
}
}
},
"401": {
"description": "Missing or rejected Pireon token",
"content": {
"text/csv": {
"schema": {
"$ref": "#/components/schemas/ApiErrorDto"
}
}
}
},
"403": {
"description": "Not a member of the project (or not allowed)",
"content": {
"text/csv": {
"schema": {
"$ref": "#/components/schemas/ApiErrorDto"
}
}
}
},
"404": {
"description": "Not found",
"content": {
"text/csv": {
"schema": {
"$ref": "#/components/schemas/ApiErrorDto"
}
}
}
}
},
"security": [
{
"pireon-oauth": []
},
{
"pireon": []
},
{}
],
"summary": "Every ticket of the project as CSV",
"tags": [
"Import and export"
]
}
},
"/api/projects/{project}/import": {
"post": {
"description": "TaskStream export or Jira CSV export, up to 5 MB and 2000 rows. Types, statuses and people are matched by id or name; the rest falls back with a warning. With dryRun=true nothing is created.",
"operationId": "TransferController_importCsv",
"parameters": [
{
"name": "project",
"required": true,
"in": "path",
"description": "Project id or key",
"schema": {
"example": "WEB",
"type": "string"
}
},
{
"name": "dryRun",
"required": false,
"in": "query",
"description": "Only tell what would be created",
"schema": {
"default": false,
"type": "boolean"
}
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"file": {
"type": "string",
"format": "binary"
}
},
"required": [
"file"
]
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ImportReportDto"
}
}
}
},
"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 tickets from a CSV (owners and admins)",
"tags": [
"Import and export"
]
}
}
},
"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"
]
},
"IssueTemplateDto": {
"type": "object",
"properties": {
"description": {
"type": "string",
"nullable": true
},
"checklist": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"description",
"checklist"
]
},
"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"
},
"template": {
"description": "What a new ticket of the type starts with",
"allOf": [
{
"$ref": "#/components/schemas/IssueTemplateDto"
}
]
}
},
"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"
},
"acceptsProposals": {
"type": "boolean",
"description": "Takes bug reports and ideas from anyone (POST /api/explore/projects/{project}/proposals) while public"
},
"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",
"acceptsProposals",
"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)"
},
"acceptsProposals": {
"type": "boolean",
"description": "Take bug reports and ideas from anyone through the public form (while public)"
}
}
},
"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"
]
},
"IssueTemplateBodyDto": {
"type": "object",
"properties": {
"description": {
"type": "string",
"nullable": true,
"maxLength": 5000
},
"checklist": {
"maxItems": 20,
"type": "array",
"items": {
"type": "string"
}
}
}
},
"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
},
"template": {
"nullable": true,
"description": "What a new ticket of the type starts with",
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/IssueTemplateBodyDto"
}
]
}
},
"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"
]
},
"DevLinkKind": {
"type": "string",
"enum": [
"COMMIT",
"BRANCH",
"PULL_REQUEST"
]
},
"DevLinkState": {
"type": "string",
"enum": [
"OPEN",
"MERGED",
"CLOSED"
]
},
"DevLinkDto": {
"type": "object",
"properties": {
"kind": {
"allOf": [
{
"$ref": "#/components/schemas/DevLinkKind"
}
]
},
"url": {
"type": "string"
},
"title": {
"type": "string"
},
"ref": {
"type": "string",
"description": "Short SHA, branch or PR number"
},
"state": {
"nullable": true,
"allOf": [
{
"$ref": "#/components/schemas/DevLinkState"
}
]
},
"provider": {
"type": "string",
"example": "gitea"
},
"repository": {
"type": "string",
"nullable": true,
"example": "api",
"description": "The project's name for the repository it came from"
},
"author": {
"type": "string",
"nullable": true
},
"at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"kind",
"url",
"title",
"ref",
"state",
"provider",
"repository",
"author",
"at"
]
},
"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"
}
]
},
"blockedBy": {
"description": "Open tickets it waits for: the ones that block it and the ones it depends on",
"type": "array",
"items": {
"$ref": "#/components/schemas/IssueParentDto"
}
},
"votes": {
"type": "number",
"description": "How many want it done"
},
"voted": {
"type": "boolean",
"description": "Whether I voted for it (false without a token)"
},
"rank": {
"type": "string",
"description": "Place in the backlog and its board column (ascending, as text)"
},
"checklist": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ChecklistItemDto"
}
},
"trashedAt": {
"type": "string",
"nullable": true,
"format": "date-time",
"description": "In the trash since then; null when it is not"
},
"devLinks": {
"description": "Commits, branches and pull requests that mention it",
"type": "array",
"items": {
"$ref": "#/components/schemas/DevLinkDto"
}
},
"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",
"blockedBy",
"votes",
"voted",
"rank",
"checklist",
"trashedAt",
"devLinks",
"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"
]
},
"BulkUpdateIssuesDto": {
"type": "object",
"properties": {
"issueIds": {
"maxItems": 100,
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"status": {
"type": "string",
"example": "IN_PROGRESS"
},
"unassign": {
"type": "boolean",
"description": "Unassign everything"
},
"assigneeId": {
"type": "string",
"description": "Pireon user id of a member"
},
"noSprint": {
"type": "boolean",
"description": "Back to the backlog"
},
"sprintId": {
"type": "string",
"format": "uuid"
},
"noRelease": {
"type": "boolean",
"description": "Out of their release"
},
"releaseId": {
"type": "string",
"format": "uuid"
},
"priority": {
"allOf": [
{
"$ref": "#/components/schemas/IssuePriority"
}
]
},
"addLabels": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"issueIds"
]
},
"BulkIssueResultDto": {
"type": "object",
"properties": {
"issueId": {
"type": "string",
"format": "uuid"
},
"ok": {
"type": "boolean"
},
"error": {
"type": "string",
"nullable": true
}
},
"required": [
"issueId",
"ok",
"error"
]
},
"BulkResultDto": {
"type": "object",
"properties": {
"updated": {
"type": "number"
},
"results": {
"type": "array",
"items": {
"$ref": "#/components/schemas/BulkIssueResultDto"
}
}
},
"required": [
"updated",
"results"
]
},
"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"
]
},
"CommentReactionDto": {
"type": "object",
"properties": {
"emoji": {
"type": "string",
"example": "👍"
},
"users": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UserRefDto"
}
}
},
"required": [
"emoji",
"users"
]
},
"CommentDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"issueId": {
"type": "string",
"format": "uuid"
},
"author": {
"$ref": "#/components/schemas/UserRefDto"
},
"body": {
"type": "string",
"description": "Empty on a deleted comment kept for its replies"
},
"replyTo": {
"type": "string",
"nullable": true,
"format": "uuid",
"description": "The top-level comment it answers; null for a top-level one"
},
"deleted": {
"type": "boolean",
"description": "Deleted, but kept (without its text) while it has replies"
},
"reactions": {
"description": "In the order they are offered; only the ones somebody chose",
"type": "array",
"items": {
"$ref": "#/components/schemas/CommentReactionDto"
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"editedAt": {
"type": "string",
"nullable": true,
"format": "date-time"
},
"version": {
"type": "number"
}
},
"required": [
"id",
"issueId",
"author",
"body",
"replyTo",
"deleted",
"reactions",
"createdAt",
"editedAt",
"version"
]
},
"CommentPageDto": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CommentDto"
}
},
"total": {
"type": "number"
}
},
"required": [
"items",
"total"
]
},
"AddCommentDto": {
"type": "object",
"properties": {
"body": {
"type": "string",
"example": "Reproducido en Safari 17.",
"maxLength": 20000
},
"replyTo": {
"type": "string",
"format": "uuid",
"description": "Comment it answers (one level: answering a reply joins its thread)"
}
},
"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"
]
},
"AttachmentResultDto": {
"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)."
},
"attachmentId": {
"type": "string",
"format": "uuid",
"description": "The new file; `![name](attachment:<id>)` shows an image inside a description or comment"
}
},
"required": [
"id",
"version",
"attachmentId"
]
},
"CommentBodyDto": {
"type": "object",
"properties": {
"body": {
"type": "string",
"example": "Reproducido en Safari 17.",
"maxLength": 20000
}
},
"required": [
"body"
]
},
"ReactToCommentDto": {
"type": "object",
"properties": {
"emoji": {
"type": "string",
"enum": [
"👍",
"👎",
"😄",
"🎉",
"😕",
"❤️",
"🚀",
"👀"
],
"example": "👍"
},
"on": {
"type": "boolean",
"description": "true adds the reaction, false takes it back"
}
},
"required": [
"emoji",
"on"
]
},
"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"
},
"notes": {
"type": "string",
"nullable": true,
"description": "What shipped, told for people (Markdown)"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"version": {
"type": "number"
}
},
"required": [
"id",
"projectId",
"name",
"description",
"targetDate",
"status",
"releasedAt",
"notes",
"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"
}
}
},
"ReleaseNotesDto": {
"type": "object",
"properties": {
"notes": {
"type": "string",
"nullable": true,
"maxLength": 20000,
"description": "Markdown; null removes the notes"
}
},
"required": [
"notes"
]
},
"ReleaseNotesDraftDto": {
"type": "object",
"properties": {
"markdown": {
"type": "string",
"example": "## v1.4.0\n\n### Novedades\n\n- Pago con tarjeta (WEB-1)\n"
}
},
"required": [
"markdown"
]
},
"ShowcaseProjectDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"key": {
"type": "string",
"example": "WEB"
},
"name": {
"type": "string"
},
"description": {
"type": "string",
"nullable": true
}
},
"required": [
"id",
"key",
"name",
"description"
]
},
"ShowcaseSprintDto": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"goal": {
"type": "string",
"nullable": true
},
"startDate": {
"type": "string",
"format": "date"
},
"endDate": {
"type": "string",
"format": "date"
},
"percent": {
"type": "number"
}
},
"required": [
"name",
"goal",
"startDate",
"endDate",
"percent"
]
},
"ShowcaseEpicDto": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"title": {
"type": "string"
},
"startDate": {
"type": "string",
"nullable": true,
"format": "date"
},
"dueDate": {
"type": "string",
"nullable": true,
"format": "date"
},
"percent": {
"type": "number"
},
"done": {
"type": "boolean"
},
"votes": {
"type": "number",
"description": "How many want it"
},
"path": {
"type": "string",
"example": "/p/WEB/issues/WEB-3",
"description": "In the web app"
}
},
"required": [
"key",
"title",
"startDate",
"dueDate",
"percent",
"done",
"votes",
"path"
]
},
"ShowcaseReleaseDto": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"status": {
"allOf": [
{
"$ref": "#/components/schemas/ReleaseStatus"
}
]
},
"targetDate": {
"type": "string",
"nullable": true
},
"releasedAt": {
"type": "string",
"nullable": true
},
"percent": {
"type": "number"
},
"notes": {
"type": "string",
"nullable": true,
"description": "Shipped ones only"
}
},
"required": [
"name",
"status",
"targetDate",
"releasedAt",
"percent",
"notes"
]
},
"ShowcaseIssueDto": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"title": {
"type": "string"
},
"type": {
"type": "string",
"description": "A ticket type id"
},
"path": {
"type": "string",
"example": "/p/WEB/issues/WEB-9"
}
},
"required": [
"key",
"title",
"type",
"path"
]
},
"ShowcaseProposalDto": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"title": {
"type": "string"
},
"type": {
"type": "string",
"description": "A ticket type id"
},
"path": {
"type": "string",
"example": "/p/WEB/issues/WEB-9"
},
"votes": {
"type": "number",
"description": "How many want it"
}
},
"required": [
"key",
"title",
"type",
"path",
"votes"
]
},
"ShowcaseProposalsDto": {
"type": "object",
"properties": {
"open": {
"type": "boolean",
"description": "Whether it takes bug reports and ideas now"
},
"path": {
"type": "string",
"nullable": true,
"example": "/p/WEB/proponer",
"description": "The form in the web app, while it takes them"
},
"top": {
"description": "Open proposals, most voted first",
"type": "array",
"items": {
"$ref": "#/components/schemas/ShowcaseProposalDto"
}
}
},
"required": [
"open",
"path",
"top"
]
},
"ShowcaseDto": {
"type": "object",
"properties": {
"project": {
"$ref": "#/components/schemas/ShowcaseProjectDto"
},
"activeSprint": {
"nullable": true,
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/ShowcaseSprintDto"
}
]
},
"roadmap": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ShowcaseEpicDto"
}
},
"releases": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ShowcaseReleaseDto"
}
},
"goodFirst": {
"description": "Open tickets labelled good-first-issue",
"type": "array",
"items": {
"$ref": "#/components/schemas/ShowcaseIssueDto"
}
},
"proposals": {
"$ref": "#/components/schemas/ShowcaseProposalsDto"
}
},
"required": [
"project",
"activeSprint",
"roadmap",
"releases",
"goodFirst",
"proposals"
]
},
"ProposalDto": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"BUG",
"IDEA"
],
"description": "A bug report or an idea"
},
"title": {
"type": "string",
"minLength": 3,
"maxLength": 150
},
"description": {
"type": "string",
"maxLength": 5000,
"description": "What happens, or what they would like (Markdown)"
},
"author": {
"type": "string",
"maxLength": 80,
"description": "How they sign it; shown in the ticket (no e-mail: it would be public)"
},
"website": {
"type": "string",
"description": "Leave empty: a field only bots fill in"
}
},
"required": [
"kind",
"title"
]
},
"ProposalResultDto": {
"type": "object",
"properties": {
"key": {
"type": "string",
"nullable": true,
"example": "WEB-42",
"description": "The ticket it became"
},
"path": {
"type": "string",
"nullable": true,
"example": "/p/WEB/issues/WEB-42",
"description": "Where to see it in the web app"
}
},
"required": [
"key",
"path"
]
},
"NotificationKind": {
"type": "string",
"enum": [
"ASSIGNED",
"STATUS_CHANGED",
"QA_FAILED",
"COMMENTED",
"MENTIONED",
"REPLIED",
"PROPOSED",
"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"
]
},
"GitRepositoryDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"example": "api"
},
"secret": {
"type": "string",
"nullable": true,
"description": "Webhook secret of this repository; only owners and admins see it"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
},
"required": [
"id",
"name",
"secret",
"createdAt"
]
},
"GitIntegrationDto": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"description": "On while there is at least one repository"
},
"webhookPath": {
"type": "string",
"example": "/api/webhooks/git/3f2c…",
"description": "The same for every repository of the project"
},
"repositories": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GitRepositoryDto"
}
}
},
"required": [
"enabled",
"webhookPath",
"repositories"
]
},
"AddGitRepositoryDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "api",
"maxLength": 40,
"description": "The project's name for it (api, web, admin…); unique"
}
},
"required": [
"name"
]
},
"GitDeliveryResultDto": {
"type": "object",
"properties": {
"recorded": {
"type": "number",
"description": "Tickets that got something new"
}
},
"required": [
"recorded"
]
},
"WebhookDeliveryDto": {
"type": "object",
"properties": {
"at": {
"type": "string",
"format": "date-time"
},
"event": {
"type": "string",
"example": "issue.created"
},
"status": {
"type": "number",
"nullable": true,
"description": "HTTP status"
},
"ok": {
"type": "boolean"
},
"error": {
"type": "string",
"nullable": true
}
},
"required": [
"at",
"event",
"status",
"ok",
"error"
]
},
"WebhookDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"projectId": {
"type": "string",
"format": "uuid"
},
"url": {
"type": "string"
},
"events": {
"type": "array",
"items": {
"type": "string"
}
},
"active": {
"type": "boolean"
},
"createdBy": {
"$ref": "#/components/schemas/UserRefDto"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"lastDelivery": {
"nullable": true,
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/WebhookDeliveryDto"
}
]
}
},
"required": [
"id",
"projectId",
"url",
"events",
"active",
"createdBy",
"createdAt",
"lastDelivery"
]
},
"CreateWebhookDto": {
"type": "object",
"properties": {
"url": {
"type": "string",
"example": "https://chat.example.org/hooks/taskstream"
},
"events": {
"example": [
"issue.status_changed",
"release.*"
],
"description": "Event names (GET /api/webhook-events), family.* or *",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"url",
"events"
]
},
"WebhookCreatedDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"secret": {
"type": "string",
"description": "Signs every delivery. Shown only now."
}
},
"required": [
"id",
"secret"
]
},
"UpdateWebhookDto": {
"type": "object",
"properties": {
"url": {
"type": "string",
"example": "https://chat.example.org/hooks/taskstream"
},
"events": {
"example": [
"issue.status_changed",
"release.*"
],
"description": "Event names (GET /api/webhook-events), family.* or *",
"type": "array",
"items": {
"type": "string"
}
},
"active": {
"type": "boolean",
"description": "Paused webhooks get nothing"
}
}
},
"ImportLineDto": {
"type": "object",
"properties": {
"line": {
"type": "number",
"description": "Line of the file (the header is 1)"
},
"reason": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"line"
]
},
"ImportReportDto": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"taskstream",
"jira"
]
},
"dryRun": {
"type": "boolean",
"description": "Nothing was created: a preview"
},
"rows": {
"type": "number",
"description": "Rows that become tickets"
},
"created": {
"type": "number"
},
"keys": {
"example": [
"WEB-41",
"WEB-42"
],
"type": "array",
"items": {
"type": "string"
}
},
"skipped": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportLineDto"
}
},
"warnings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportLineDto"
}
}
},
"required": [
"format",
"dryRun",
"rows",
"created",
"keys",
"skipped",
"warnings"
]
}
}
}
}