Tickets
Tickets erstellen, aktualisieren, zuweisen und überführen -- die zentralen Arbeitsobjekte in Spedy.
Tickets sind die grundlegenden Arbeitsobjekte in Spedy. Jede Aufgabe, jeder Bug, jede Feature-Anfrage oder jedes Arbeitspaket lebt als Ticket auf einem Board. Tickets unterstützen Status, Prioritäten, Zuweisungen, Labels, Fälligkeitsdaten, Zeitschätzungen und mehr.
Tickets auflisten
GET /api/v1/boards/{boardId}/ticketsGibt eine paginierte Liste der Tickets auf dem Board zurück.
Query-Parameter
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| page | number | Nein | Seitennummer (Standard: 1) |
| limit | number | Nein | Einträge pro Seite (Standard: 20, max: 100) |
| statusId | string | Nein | Nach Status-ID filtern |
| assigneeId | string | Nein | Nach Verantwortlichem filtern |
| customerId | string | Nein | Nach Kunden-ID filtern |
| needsReassignment | boolean | Nein | Tickets filtern, die neu zugewiesen werden müssen |
| typeId | string | Nein | Nach Tickettyp-ID filtern (kommagetrennt für mehrere) |
| labelId | string | Nein | Nach Label-ID filtern (kommagetrennt für mehrere) |
| search | string | Nein | Suche in Titel und Beschreibung |
| includePlanning | boolean | Nein | Tickets in PLANNING-Status einschließen (Standard: false) |
| includeArchived | boolean | Nein | Archivierte/erledigte Tickets einschließen |
| overdue | boolean | Nein | Nur überfällige Tickets |
| noDueDate | boolean | Nein | Nur Tickets ohne Fälligkeitsdatum |
| dueBefore | string | Nein | Tickets fällig bis zu diesem Datum (ISO 8601) |
| dueAfter | string | Nein | Tickets fällig ab diesem Datum (ISO 8601) |
| impactLevel | string | Nein | Nach Auswirkungsstufe filtern (kommagetrennt) |
| externalReference | string | Nein | Nach externer Referenz filtern (Teilübereinstimmung) |
Beispiel-Response
{
"data": [
{
"id": "tkt_abc123",
"displayId": "WEB-42",
"title": "Login-Seite Styling fixen",
"status": {
"id": "sts_def456",
"name": "In Bearbeitung",
"category": "ACTIVE"
},
"priority": "high",
"assignee": {
"id": "usr_abc123",
"name": "Alex Smith"
},
"type": {
"id": "typ_abc123",
"name": "Bug"
},
"labels": [],
"dueDate": "2025-04-01T00:00:00Z",
"createdAt": "2025-03-15T10:00:00Z"
}
],
"total": 42,
"page": 1,
"pageSize": 20,
"totalPages": 3
}Ticket erstellen
POST /api/v1/boards/{boardId}/ticketsRequest Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| title | string | Ja | Ticket-Titel (max. 200 Zeichen) |
| description | string | Nein | Detaillierte Beschreibung (max. 50.000 Zeichen) |
| statusId | string | Nein | Initialer Status-ID (Standard: Backlog) |
| assigneeId | string | Nein | Verantwortlicher Nutzer-ID |
| customerId | string | Nein | Kunden-ID |
| priority | string | Nein | low, medium, high oder critical |
| typeId | string | Nein | Tickettyp-ID |
| labelIds | string[] | Nein | Label-IDs zum Anhängen |
| dueDate | string | Nein | Fälligkeitsdatum (ISO 8601) |
| startDate | string | Nein | Geplantes Startdatum (ISO 8601) |
| estimatedHours | number | Nein | Geschätzte Stunden (min. 0,1) |
| storyPoints | number | Nein | Story Points |
| externalReference | string | Nein | Externe Referenz-ID (max. 200 Zeichen) |
| impactLevel | string | Nein | low, medium, high oder critical |
Beispiel-Request
{
"title": "Login-Seite Styling fixen",
"description": "Der Login-Button ist auf mobilen Geräten falsch ausgerichtet.",
"priority": "high",
"typeId": "typ_bug123",
"assigneeId": "usr_abc123",
"labelIds": ["lbl_frontend"],
"dueDate": "2025-04-01T00:00:00Z"
}Ticket abrufen
GET /api/v1/boards/{boardId}/tickets/{ticketId}Gibt vollständige Ticket-Details einschließlich Beschreibung, Kommentaranzahl, Anhanganzahl und verknüpfter Daten zurück.
Ticket aktualisieren
PATCH /api/v1/boards/{boardId}/tickets/{ticketId}Alle Felder sind optional. Sende nur die Felder, die du ändern möchtest. Setze ein Feld auf null, um es zu leeren.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| title | string | Nein | Ticket-Titel |
| description | string | Nein | Detaillierte Beschreibung |
| assigneeId | string | null | Nein | Verantwortlicher (null zum Entfernen) |
| customerId | string | null | Nein | Kunde (null zum Entfernen) |
| priority | string | null | Nein | low, medium, high, critical (null zum Entfernen) |
| typeId | string | Nein | Tickettyp-ID |
| statusId | string | Nein | Status-ID |
| statusChangeReason | string | Nein | Grund für Statusänderung (für Explainable-Status-Logging, max. 500 Zeichen) |
| isArchived | boolean | Nein | Archivierungsstatus (true zum Archivieren, false zum Wiederherstellen) |
| labelIds | string[] | Nein | Label-IDs (ersetzt bestehende Labels) |
| dueDate | string | null | Nein | Fälligkeitsdatum (null zum Entfernen) |
| startDate | string | null | Nein | Startdatum (null zum Entfernen) |
| estimatedHours | number | null | Nein | Geschätzte Stunden (null zum Entfernen) |
| timeSpent | number | null | Nein | Aufgewendete Zeit in Stunden (null zum Entfernen) |
| storyPoints | number | null | Nein | Story Points (null zum Entfernen) |
| externalReference | string | null | Nein | Externe Referenz (null zum Entfernen) |
| impactLevel | string | null | Nein | low, medium, high, critical (null zum Entfernen) |
| milestoneId | string | null | Nein | Meilenstein-ID (null zum Entfernen) |
| resolution | string | null | Nein | Lösungsbeschreibung |
| resolutionType | string | null | Nein | fixed, wont_fix, duplicate, cannot_reproduce oder by_design |
Ticket löschen
DELETE /api/v1/boards/{boardId}/tickets/{ticketId}Führt ein Soft-Delete des Tickets durch (markiert als gelöscht, Daten bleiben erhalten). Gibt 204 No Content zurück.
Ticket-Status aktualisieren
PATCH /api/v1/boards/{boardId}/tickets/{ticketId}/statusÄndert den Workflow-Status des Tickets.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| statusId | string | Ja | Ziel-Status-ID |
| reason | string | Nein | Grund für Statusänderung (für Explainable-Status-Logging, max. 500 Zeichen) |
Ticket zuweisen
PATCH /api/v1/boards/{boardId}/tickets/{ticketId}/assignEinen Nutzer dem Ticket zuweisen oder die Zuweisung entfernen.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| assigneeId | string | null | Ja | Nutzer-ID zur Zuweisung, oder null zum Entfernen |
Ticket verschieben
POST /api/v1/boards/{boardId}/tickets/{ticketId}/moveVerschiebt ein Ticket auf ein anderes Board. Untertickets und Tickets mit Untertickets können nicht verschoben werden.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| targetBoardId | string | Ja | Ziel-Board-ID |
Beispiel-Response
{
"data": {
"id": "tkt_abc123",
"displayId": "NEW-1",
"title": "Login-Seite Styling fixen",
"boardId": "brd_newboard"
}
}Ticket überführen
POST /api/v1/boards/{boardId}/tickets/{ticketId}/transitionÜberführt ein Ticket in einen neuen Status mit Validierung der Übergangsregeln.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| toStatusId | string | Ja | Ziel-Status-ID |
| reason | string | Nein | Grund für den Übergang (erforderlich wenn Explainable-Status-Feature aktiviert ist) |
| blockerInfo | object | Nein | Blocker-Informationen (erforderlich beim Übergang zu BLOCKED-Status) |
| blockerInfo.reason | string | Ja* | Grund für die Blockierung (*erforderlich innerhalb von blockerInfo) |
| blockerInfo.blockedBy | string | Nein | Nutzer-ID, die das Ticket blockiert hat |
Beispiel-Request
{
"toStatusId": "sts_blocked123",
"reason": "Warte auf Design-Freigabe",
"blockerInfo": {
"reason": "Design-Team muss Mockups überprüfen",
"blockedBy": "usr_designer456"
}
}Ticket genehmigen
POST /api/v1/boards/{boardId}/tickets/{ticketId}/approveGenehmigt ein Ticket im Planungs-/Backlog-Status und verschiebt es in den aktiven Workflow.
Tickets mit Neuzuweisungsbedarf
GET /api/v1/boards/{boardId}/tickets/needing-reassignmentGibt Tickets zurück, die als neuzuweisungsbedürftig markiert wurden (z.B. nach Entfernung eines Teammitglieds vom Board).
Ticket neu ordnen
PATCH /api/v1/boards/{boardId}/tickets/reorderOrdnet ein Ticket innerhalb einer oder über Spalten (Status) auf einem Board neu.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| ticketId | string | Ja | Ticket-ID zum Neuordnen |
| position | number | Ja | Neue Position (Fließkommazahl) |
| statusId | string | Nein | Optionale neue Status-ID (für spaltenübergreifendes Ziehen) |
Inline-Ticket-Aktualisierung
PATCH /api/v1/boards/{boardId}/tickets/{ticketId}/inlineAktualisiert mehrere Ticket-Felder gleichzeitig mit optimistischer Sperrung zur Konflikterkennung.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| title | string | Nein | Ticket-Titel (max. 200 Zeichen) |
| description | string | Nein | Ticket-Beschreibung |
| statusId | string | Nein | Status-ID |
| assigneeId | string | null | Nein | Verantwortlicher Nutzer-ID (null zum Entfernen) |
| dueDate | string | null | Nein | Fälligkeitsdatum (null zum Entfernen) |
| expectedUpdatedAt | string | Nein | Erwarteter updatedAt-Zeitstempel zur Konflikterkennung |
Benutzerdefinierte Feldwerte setzen
PUT /api/v1/boards/{boardId}/tickets/{ticketId}/custom-fieldsBerechtigung erforderlich: custom-fields:manage
Setzt benutzerdefinierte Feldwerte für ein Ticket.
Request Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| values | array | Ja | Array von benutzerdefinierten Feldwert-Objekten |
| values[].customFieldId | string | Ja | Benutzerdefinierte Feld-ID |
| values[].value | string | null | Nein | Zu setzender Wert (null zum Leeren) |
Beispiel-Request
{
"values": [
{ "customFieldId": "cf_abc123", "value": "Enterprise" },
{ "customFieldId": "cf_def456", "value": null }
]
}Abschluss-Prüfung
GET /api/v1/boards/{boardId}/tickets/{ticketId}/completion-checkPrüft, ob ein Ticket bereit für den Abschluss ist. Gibt Blocker, Anforderungen und Unterticket-Status zurück.
Beispiel-Response
{
"data": {
"canComplete": false,
"hasOpenSubtickets": true,
"openSubtickets": [
{ "id": "tkt_sub1", "title": "Design-Review", "displayId": "WEB-43" }
],
"aggregation": {
"total": 3,
"completed": 1,
"summary": "in_progress"
},
"blockers": [],
"requirements": {
"hasDescription": true,
"hasAssignee": true,
"hasCustomer": false,
"hasNoActiveSubtickets": false
}
}
}Blocker-Info
GET /api/v1/boards/{boardId}/tickets/{ticketId}/blockerGibt Informationen darüber zurück, was dieses Ticket blockiert.
Beispiel-Response
{
"data": {
"isBlocked": true,
"reason": "Warte auf API-Änderungen",
"reasonText": "Warte auf API-Änderungen",
"blockingTickets": [
{
"id": "tkt_other123",
"ticketNumber": "API-15",
"title": "Auth-Modul refactoren",
"status": { "id": "sts_1", "name": "In Bearbeitung", "color": "#3B82F6" },
"createdAt": "2025-03-01T10:00:00Z"
}
],
"blockerCount": 1
}
}Pull Requests
GET /api/v1/boards/{boardId}/tickets/{ticketId}/pull-requestsGibt Pull Requests zurück, die über Branch-Name oder PR-Titel mit einem Ticket verknüpft sind.
Beispiel-Response
{
"data": [
{
"id": "pr_abc123",
"prNumber": 42,
"title": "Login-Styling fixen",
"url": "https://github.com/org/repo/pull/42",
"branchName": "fix/WEB-42-login-styling",
"state": "open",
"authorName": "alex",
"provider": "github",
"repoFullName": "org/repo",
"createdAt": "2025-03-20T10:00:00Z",
"updatedAt": "2025-03-20T14:00:00Z"
}
]
}