{"openapi":"3.1.0","info":{"title":"LitosFlow API","version":"v1","summary":"Programmatic access to your organization's tickets, comments, and boards.","description":"A versioned REST API for building integrations against your tickets, comments, and boards. Every endpoint returns JSON, is authenticated with a personal access token, and acts as the member that token belongs to \u2014 in one organization only. A token's scopes can never exceed what its member's role already allows, so restricting a role restricts every token it issued.","contact":{"name":"LitosFlow Support","url":"https:\/\/dev.litosflow.com\/developers"}},"servers":[{"url":"https:\/\/dev-api.litosflow.com\/api\/v1","description":"API v1"}],"security":[{"bearerAuth":[]}],"x-scopes":{"view_all_tickets":"Read every ticket, board, status, and comment in the organization.","view_own_tickets":"Read only tickets the member reported or is assigned to (and their comments).","create_tickets":"Create tickets and author comments.","edit_any_ticket":"Update any ticket in the organization.","edit_assigned_tickets":"Update only tickets assigned to the member."},"tags":[{"name":"Identity","description":"Confirm who a token acts as."},{"name":"Reference","description":"Read-only reference data (boards, statuses) needed to construct valid writes."},{"name":"Tickets","description":"Read and write tickets."},{"name":"Comments","description":"Read and write ticket comments."}],"paths":{"\/me":{"get":{"tags":["Identity"],"operationId":"getMe","summary":"Identify the token","description":"Returns the member, organization, and scopes this token operates as. Handy for verifying a credential.","responses":{"200":{"description":"The token's member, organization, and scopes.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Me"}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/boards":{"get":{"tags":["Reference"],"operationId":"listBoards","summary":"List boards","description":"Boards in the organization, with their ticket prefix and count.","x-required-scopes":["view_all_tickets","view_own_tickets"],"responses":{"200":{"description":"Boards in the organization.","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/Board"}}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/statuses":{"get":{"tags":["Reference"],"operationId":"listStatuses","summary":"List statuses","description":"Board columns (statuses) across the organization, including which column completes a ticket. Use these ids when creating or moving tickets.","x-required-scopes":["view_all_tickets","view_own_tickets"],"responses":{"200":{"description":"Statuses across the organization's boards.","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/Status"}}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/tickets":{"post":{"tags":["Tickets"],"operationId":"createTicket","summary":"Create a ticket","description":"Creates a ticket. The reporter is always the token's member \u2014 it is never taken from the body. `board` and `status` ids come from `GET \/boards` and `GET \/statuses`; the status must be a column of the chosen board.","x-required-scopes":["create_tickets"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["title","board","status","priority"],"properties":{"title":{"type":"string","maxLength":200},"description":{"type":["string","null"],"maxLength":50000},"board":{"type":"string","format":"uuid"},"status":{"type":"string","format":"uuid","description":"Must be a column of `board`."},"priority":{"type":"string","enum":["urgent","high","medium","low"]},"assignee":{"type":["string","null"],"format":"uuid"},"due":{"type":["string","null"],"format":"date"},"tags":{"type":"array","items":{"type":"string","format":"uuid"}}}},"example":{"title":"Printer on floor 2 is jammed","description":"Paper tray 3 keeps jamming.","board":"9b1f0c7a-0e2a-4c3d-8f1a-2b3c4d5e6f70","status":"3f2504e0-4f89-41d3-9a0c-0305e82c3301","priority":"high"}}}},"responses":{"201":{"description":"The created ticket.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Ticket"}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"422":{"description":"Validation failed.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidationError"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"get":{"tags":["Tickets"],"operationId":"listTickets","summary":"List tickets","description":"Paginated list of tickets. Supports search, board\/status\/priority\/assignee\/tag filters, date ranges, and sorting. A `view_own_tickets`-only token sees only tickets its member reported or is assigned to.","x-required-scopes":["view_all_tickets","view_own_tickets"],"parameters":[{"name":"search","in":"query","required":false,"description":"Full-text match on title\/description.","schema":{"type":"string"}},{"name":"board","in":"query","required":false,"description":"Filter to a board id.","schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"description":"Filter to a status (column) id.","schema":{"type":"string","format":"uuid"}},{"name":"priority","in":"query","required":false,"description":"Filter by priority.","schema":{"type":"string","enum":["urgent","high","medium","low"]}},{"name":"assignee","in":"query","required":false,"description":"Filter by assigned member id.","schema":{"type":"string"}},{"name":"tags","in":"query","required":false,"description":"Filter by tag ids (repeat the param).","schema":{"type":"array","items":{"type":"string","format":"uuid"}}},{"name":"createdFrom","in":"query","required":false,"description":"Created on\/after this date.","schema":{"type":"string","format":"date"}},{"name":"createdTo","in":"query","required":false,"description":"Created on\/before this date.","schema":{"type":"string","format":"date"}},{"name":"dueFrom","in":"query","required":false,"description":"Due on\/after this date.","schema":{"type":"string","format":"date"}},{"name":"dueTo","in":"query","required":false,"description":"Due on\/before this date.","schema":{"type":"string","format":"date"}},{"name":"updatedFrom","in":"query","required":false,"description":"Updated on\/after this date.","schema":{"type":"string","format":"date"}},{"name":"updatedTo","in":"query","required":false,"description":"Updated on\/before this date.","schema":{"type":"string","format":"date"}},{"name":"blocked","in":"query","required":false,"description":"Only tickets that are (or are not) blocked by a link.","schema":{"type":"boolean"}},{"name":"sort","in":"query","required":false,"description":"Sort field.","schema":{"type":"string","enum":["title","due","updated"],"default":"updated"}},{"name":"direction","in":"query","required":false,"description":"Sort direction.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"page","in":"query","required":false,"description":"Page number (1-based).","schema":{"type":"integer","minimum":1,"default":1}},{"name":"perPage","in":"query","required":false,"description":"Rows per page.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"A page of tickets plus pagination metadata.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TicketList"}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"422":{"description":"Validation failed.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidationError"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/tickets\/{ticket}":{"get":{"tags":["Tickets"],"operationId":"getTicket","summary":"Get a ticket","description":"A single ticket with its comments, tags, checklist, links, and attachment metadata.","x-required-scopes":["view_all_tickets","view_own_tickets"],"parameters":[{"name":"ticket","in":"path","required":true,"description":"Ticket id (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The ticket.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Ticket"}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Not found, or outside this token's organization or visibility.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"patch":{"tags":["Tickets"],"operationId":"updateTicket","summary":"Update a ticket","description":"Updates any subset of a ticket's fields. With only `edit_assigned_tickets`, the ticket must be assigned to the token's member. Omitted fields are left unchanged.","x-required-scopes":["edit_any_ticket","edit_assigned_tickets"],"parameters":[{"name":"ticket","in":"path","required":true,"description":"Ticket id (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"title":{"type":"string","maxLength":200},"description":{"type":["string","null"],"maxLength":50000},"status":{"type":"string","format":"uuid","description":"Must be a column of the ticket's board."},"priority":{"type":"string","enum":["urgent","high","medium","low"]},"assignee":{"type":["string","null"],"format":"uuid"},"due":{"type":["string","null"],"format":"date"},"tags":{"type":"array","items":{"type":"string","format":"uuid"}}}},"example":{"priority":"urgent","status":"3f2504e0-4f89-41d3-9a0c-0305e82c3301"}}}},"responses":{"200":{"description":"The updated ticket.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Ticket"}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Not found, or outside this token's organization or visibility.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"422":{"description":"Validation failed.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidationError"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/tickets\/{ticket}\/comments":{"post":{"tags":["Comments"],"operationId":"createComment","summary":"Add a comment","description":"Adds a comment authored by the token's member.","x-required-scopes":["create_tickets"],"parameters":[{"name":"ticket","in":"path","required":true,"description":"Ticket id (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":50000}}},"example":{"text":"Replacement part ordered, ETA Thursday."}}}},"responses":{"201":{"description":"The created comment.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Comment"}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Not found, or outside this token's organization or visibility.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"422":{"description":"Validation failed.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidationError"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"get":{"tags":["Comments"],"operationId":"listComments","summary":"List comments","description":"Comments on a ticket, oldest first.","x-required-scopes":["view_all_tickets","view_own_tickets"],"parameters":[{"name":"ticket","in":"path","required":true,"description":"Ticket id (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The ticket's comments.","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/Comment"}}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Not found, or outside this token's organization or visibility.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/tickets\/{ticket}\/comments\/{comment}":{"delete":{"tags":["Comments"],"operationId":"deleteComment","summary":"Delete a comment","description":"Deletes one of the token member's own comments.","x-required-scopes":["create_tickets"],"parameters":[{"name":"ticket","in":"path","required":true,"description":"Ticket id (UUID).","schema":{"type":"string","format":"uuid"}},{"name":"comment","in":"path","required":true,"description":"Comment id (UUID).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Deletion confirmed.","content":{"application\/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}}}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Not found, or outside this token's organization or visibility.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"patch":{"tags":["Comments"],"operationId":"updateComment","summary":"Edit a comment","description":"Edits one of the token member's own comments. Editing another member's comment is rejected.","x-required-scopes":["create_tickets"],"parameters":[{"name":"ticket","in":"path","required":true,"description":"Ticket id (UUID).","schema":{"type":"string","format":"uuid"}},{"name":"comment","in":"path","required":true,"description":"Comment id (UUID).","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":50000}}},"example":{"text":"Replacement part arrived \u2014 closing out."}}}},"responses":{"200":{"description":"The updated comment.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Comment"}}}},"401":{"description":"Missing, revoked, or expired token.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"The token lacks the required scope, or the member's role no longer grants it.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Not found, or outside this token's organization or visibility.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"422":{"description":"Validation failed.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidationError"}}}},"429":{"description":"Rate limit exceeded (60\/min per token). Includes a `Retry-After` header.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A personal access token (prefixed `ltf_`) sent as `Authorization: Bearer <token>`. Create one from your profile; the secret is shown only once."}},"schemas":{"Ticket":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string","description":"Human key, `{prefix}-{number}` (e.g. `GP-142`).","example":"GP-142"},"formerKeys":{"type":"array","items":{"type":"string"},"description":"Prior keys after a board transfer."},"title":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","format":"uuid","description":"Status (board column) id."},"priority":{"type":"string","enum":["urgent","high","medium","low"]},"assignee":{"type":["string","null"],"format":"uuid","description":"Assigned member id, or null."},"reporter":{"type":"string","format":"uuid","description":"Reporting member id."},"board":{"type":"string","format":"uuid"},"tags":{"type":"array","items":{"type":"string","format":"uuid"}},"watchers":{"type":"array","items":{"type":"string","format":"uuid"}},"due":{"type":"string","description":"Due date (`YYYY-MM-DD`) or empty string."},"created":{"type":"string","format":"date"},"updated":{"type":"string","format":"date"},"updatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"customFields":{"type":"object","description":"Values keyed by custom field definition id.","additionalProperties":true},"comments":{"type":"array","items":{"$ref":"#\/components\/schemas\/Comment"}},"checklist":{"type":"array","items":{"$ref":"#\/components\/schemas\/ChecklistItem"}},"attachments":{"type":"array","items":{"$ref":"#\/components\/schemas\/Attachment"}},"links":{"type":"array","items":{"$ref":"#\/components\/schemas\/TicketLink"}}}},"TicketList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Ticket"}},"meta":{"$ref":"#\/components\/schemas\/PaginationMeta"}}},"PaginationMeta":{"type":"object","properties":{"page":{"type":"integer","example":1},"perPage":{"type":"integer","example":25},"total":{"type":"integer","example":128},"totalPages":{"type":"integer","example":6}}},"Comment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"author":{"type":"string","format":"uuid","description":"Authoring member id."},"text":{"type":"string"},"time":{"type":"string","format":"date"},"reactions":{"type":"array","items":{"type":"object","properties":{"emoji":{"type":"string"},"count":{"type":"integer"},"members":{"type":"array","items":{"type":"string","format":"uuid"}}}}}}},"ChecklistItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"done":{"type":"boolean"}}},"Attachment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"size":{"type":"string","description":"Human-readable size (e.g. `2.4 MB`)."},"url":{"type":"string","description":"Download path (session-authenticated)."},"uploadedBy":{"type":["string","null"],"format":"uuid"}}},"TicketLink":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","description":"Relationship as seen from this ticket (e.g. `blocks`, `blocked_by`, `relates_to`)."},"ticketId":{"type":"string","format":"uuid","description":"The ticket on the other end of the link."}}},"Board":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"ticketPrefix":{"type":"string","example":"GP"},"ticketCount":{"type":"integer"},"isLocked":{"type":"boolean","description":"A board locked read-only by the org's plan can be read but not written."}}},"Status":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"boardId":{"type":"string","format":"uuid"},"name":{"type":"string"},"color":{"type":"string"},"isDone":{"type":"boolean","description":"Whether tickets in this column count as completed."},"sortOrder":{"type":"integer"},"ticketCount":{"type":"integer"}}},"Me":{"type":"object","properties":{"member":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"role":{"type":["string","null"]}}},"organization":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"}}},"token":{"type":"object","properties":{"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":["string","null"],"format":"date-time"}}}}},"Error":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"ValidationError":{"type":"object","properties":{"message":{"type":"string"},"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["message","errors"]}}}}