Markus Michalski FAQ

API Endpoints: API-Dokumentation

REST-API-Referenz des osTicket-Plugins API Endpoints: alle 12 Endpunkte mit Pfaden, Methoden, Parametern, Berechtigungen, Statuscodes und Beispielen.

English Version

Zurück zur Übersicht

API Endpoints: API-Dokumentation

Diese Dokumentation bezieht sich immer auf die aktuellste veröffentlichte Version.

Diese Seite beschreibt alle 12 Endpunkte des Plugins: Pfade, Methoden, Parameter, nötige API-Key-Berechtigungen, Antworten und Fehlercodes. Installation und Webserver-Einrichtung stehen auf Installation, die Berechtigungen auf Konfiguration.

Überblick

# Methode Pfad Berechtigung
1 POST /api/tickets.json siehe POST Ticket erstellen
2 GET /api/tickets-get.php/{number}.{format} can_read_tickets
3 PATCH, PUT /api/tickets-update.php/{number}.{format} oder /api/tickets/{number}.{format} can_update_tickets
4 GET /api/tickets-search.php can_search_tickets oder can_read_tickets
5 DELETE /api/tickets-delete.php/{number}.{format} can_delete_tickets
6 GET /api/tickets-stats.php can_read_stats oder can_read_tickets
7 GET /api/tickets-statuses.php can_read_stats oder can_read_tickets
8 GET /api/tickets-subtickets-parent.php/{number}.{format} can_manage_subtickets
9 GET /api/tickets-subtickets-list.php/{number}.{format} can_manage_subtickets
10 POST /api/tickets-subtickets-create.php/{parentNumber}.{format} can_manage_subtickets
11 DELETE /api/tickets-subtickets-unlink.php/{number}.{format} can_manage_subtickets
12 GET /api/tickets-attachment-download.php/{file_id}.{format} can_read_tickets

{format} ist json oder xml. Die Berechtigungsnamen sind die Spalten der API-Key-Tabelle, siehe Konfiguration.

Authentifizierung

Jede Anfrage trägt den API-Key im Header X-API-Key.

X-API-Key: YOUR_API_KEY

Die eigenständigen Endpunkte (2 bis 12) lehnen einen fehlenden oder ungültigen Key mit 401 ab. Ein API-Key ohne die für den Endpunkt nötige Berechtigung erhält 401 mit einer Meldung wie API key not authorized to read tickets. Nur die Subticket-Endpunkte und der Attachment-Download antworten in bestimmten Fällen mit 403, siehe Statuscodes. Endpunkt 1 wird anders behandelt, siehe den zugehörigen Abschnitt.

can_read_tickets gewährt auch Suche, Statistiken und die Statusliste. Ein Key, der nur can_search_tickets oder can_read_stats hat, kann nur genau diesen einen Endpunkt nutzen. Alle anderen Berechtigungen haben keinen Fallback: Eine fehlende oder deaktivierte Berechtigung bedeutet verweigerten Zugriff.

Basis-URL

https://your-domain.com/api

Antwortformate

Endpunkt-Typ Erfolgsantwort
Erstellen (1), Aktualisieren (3), Löschen (5) Ticketnummer als Klartext (text/plain)
Endpunkte mit {number}.{format} (2, 8, 9, 10, 11, 12) JSON, oder XML wenn der Pfad auf .xml endet
Suche, Statistik, Statusliste (4, 6, 7) JSON. Die Pfadinfo hinter dem Skriptnamen ist optional und darf .json oder .xml sein, bei .xml ist die Antwort XML

XML-Antworten haben response als Wurzelelement, Listeneinträge heißen item. Fehler, die das Plugin selbst auslöst, sind immer JSON, auch bei .xml-Anfragen:

{
  "error": true,
  "message": "Description of what went wrong"
}

Fehler der API-Key-Prüfung (fehlender oder ungültiger Key, IP-Beschränkung) stammen aus dem osTicket-Core oder dem Plugin API Key Wildcard und haben deren Format.

Fehler der beiden über das Signal registrierten Routen (Erstellen und PATCH /api/tickets/{number}.{format}) kommen als Klartext, der nur die Meldung enthält.

Statuscodes

Code Bedeutung Wann
200 OK Anfrage erfolgreich
201 Created Ticket erstellt (Endpunkt 1)
400 Bad Request Ungültiges URL-Format, ungültige oder fehlende Parameter, Validierung fehlgeschlagen
401 Unauthorized Eigenständige Endpunkte und Update-Route: fehlender oder ungültiger API-Key, oder dem Key fehlt die nötige Berechtigung
403 Forbidden Subticket-Endpunkte: can_manage_subtickets fehlt, oder das API-Key-Objekt liefert Abteilungsbeschränkungen, die die Abteilung des Tickets ausschließen. Attachment-Download: kein Anhang-Eintrag zur Datei
404 Not Found Ticket, Abteilung, Status, Hilfethema, SLA, Mitarbeiter oder Datei nicht gefunden
405 Method Not Allowed Falsche HTTP-Methode für einen eigenständigen Endpunkt (Method Not Allowed. Use GET)
422 Unprocessable Entity Subticket-Verknüpfung existiert schon, oder das Kind hat bereits ein anderes Elternticket
500 Internal Server Error Vorgang auf dem Server fehlgeschlagen
501 Not Implemented Subticket plugin not available

Auflösung über Namen

departmentId, statusId, topicId und slaId akzeptieren einen Namen oder eine ID. Ein nicht numerischer Wert wird als Name gesucht (ohne Beachtung der Groß-/Kleinschreibung) und liefert 404, wenn nichts passt. Ein numerischer Wert, auch als String gesendet, wird immer als ID verwendet. staffId akzeptiert die Mitarbeiter-ID, den Benutzernamen oder die E-Mail-Adresse, nicht den Anzeigenamen.


1. POST Ticket erstellen

Erstellt ein Ticket. Das Plugin ergänzt die Erstellungsparameter von osTicket um format, departmentId und parentTicketNumber.

Endpunkt

POST /api/tickets.json

Berechtigung: Für diese Signal-Route prüft das Plugin selbst weder den API-Key noch die Berechtigung can_create_tickets. Ob der osTicket-Core den Key prüft, bevor er das Signal auslöst, lässt sich aus dem Code dieses Plugins nicht ableiten.

Sende den Body als JSON mit Content-Type: application/json.

Vom Plugin verarbeitete Parameter

Parameter Typ Beschreibung Beispiel
format string Nachrichtenformat: text, html oder markdown. Aliase: md für markdown, plain und txt für text "markdown"
departmentId string oder int Abteilungsname oder ID. Nur aktive Abteilungen, Unterabteilungen werden über ihren Namen gefunden "Support" oder 5
parentTicketNumber string oder int Nummer des Elterntickets (eine interne ID wird als Fallback akzeptiert). Das Elternticket muss existieren und darf selbst kein Kind sein "181752"

Von osTicket verarbeitete Parameter

Alle anderen Felder verarbeitet die Ticketerstellung von osTicket selbst, zum Beispiel name, email, subject, message, topicId und attachments. Welche davon Pflicht sind, hängt vom Ticketformular deiner osTicket-Installation ab.

Anhänge werden als Array von Objekten übergeben, jeweils mit dem Dateinamen als Schlüssel und einer Base64-Data-URI als Wert:

{
  "attachments": [
    {"screenshot.png": "data:image/png;base64,iVBORw0KGgo..."},
    {"report.pdf": "data:application/pdf;base64,JVBERi0xLjQ..."}
  ]
}

Antwort

201 Created: die Ticketnummer als Klartext.

781258

Beispiele

# Einfaches Ticket
curl -X POST "https://osticket.local/api/tickets.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "subject": "Login Issue",
    "message": "I cannot access my account"
  }'

# Markdown-Nachricht, in eine Abteilung geroutet
curl -X POST "https://osticket.local/api/tickets.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "email": "jane@example.com",
    "subject": "Bug Report: Payment Failed",
    "message": "## Problem\n\nPayment fails with error CARD_DECLINED.",
    "format": "markdown",
    "departmentId": "Billing"
  }'

# Als Subticket eines bestehenden Tickets erstellen
curl -X POST "https://osticket.local/api/tickets.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Developer",
    "email": "dev@example.com",
    "subject": "Subtask: Database Migration",
    "message": "Migrate the production database",
    "parentTicketNumber": "181752",
    "departmentId": "Development"
  }'

Hinweise


2. GET Ticket abrufen

Liefert ein Ticket samt Thread.

GET /api/tickets-get.php/{number}.{format}

Berechtigung: can_read_tickets

Parameter Typ Beschreibung
number string oder int Ticketnummer. Hat kein Ticket diese Nummer, wird der Wert als interne Ticket-ID versucht
format string json oder xml

Antwort

{
  "id": 123,
  "number": "781258",
  "subject": "Login Issue",
  "statusId": 1,
  "status": "Open",
  "priorityId": 2,
  "priority": "Normal",
  "departmentId": 5,
  "department": "IT Support",
  "topicId": 10,
  "topic": "Technical Support",
  "userId": 45,
  "user": {
    "name": "John Doe",
    "email": "john@example.com"
  },
  "staffId": 3,
  "staff": "Jane Smith",
  "teamId": 2,
  "team": "Level 1 Support",
  "slaId": 1,
  "sla": "Standard SLA",
  "created": "2025-11-08 10:30:00",
  "updated": "2025-11-08 14:20:00",
  "duedate": "2025-11-15 10:30:00",
  "closed": null,
  "isOverdue": false,
  "isAnswered": true,
  "source": "API",
  "ip": "192.168.1.100",
  "children": [124, 125],
  "thread": [
    {
      "id": 456,
      "type": "M",
      "poster": "John Doe",
      "timestamp": "2025-11-08 10:30:00",
      "body": "I cannot access my account",
      "userId": 45,
      "attachments": [
        {
          "id": 12,
          "file_id": 29,
          "filename": "screenshot.png",
          "size": 45320,
          "mime_type": "image/png",
          "inline": false
        }
      ],
      "attachment_count": 1
    }
  ]
}
Feld Beschreibung
thread[].type Thread-Eintragstyp, wie osTicket ihn speichert: M Nachricht, R Antwort, N interne Notiz
thread[].staffId, thread[].staff Nur bei Einträgen eines Mitarbeiters vorhanden
thread[].userId Nur bei Einträgen eines Benutzers vorhanden
thread[].attachments, thread[].attachment_count Nur vorhanden, wenn der Eintrag Anhänge hat. file_id ist der Wert für den Attachment-Download
children Interne IDs (nicht Nummern) der Kindtickets
closed Schließdatum, nur wenn das Ticket geschlossen ist, sonst null

Beispiel

curl "https://osticket.local/api/tickets-get.php/781258.json" \
  -H "X-API-Key: YOUR_API_KEY"

3. PATCH Ticket aktualisieren

Ändert Eigenschaften eines Tickets und fügt optional eine interne Notiz mit Anhängen hinzu.

PATCH /api/tickets-update.php/{number}.{format}
PUT   /api/tickets-update.php/{number}.{format}

Dasselbe Update steht über die Route PATCH /api/tickets/{number}.json zur Verfügung (auch PUT, .xml wird akzeptiert). Diese Route antwortet bei Fehlern mit Klartext statt JSON.

Berechtigung: can_update_tickets

Sende den Body als JSON mit Content-Type: application/json. Gib nur die Felder an, die sich ändern sollen.

Feld Typ Beschreibung
statusId string oder int Statusname oder ID
departmentId string oder int Abteilungsname oder ID
topicId string oder int Hilfethema-Name oder ID
slaId string oder int SLA-Plan-Name oder ID
staffId string oder int Mitarbeiter-ID, Benutzername oder E-Mail-Adresse
dueDate string oder null Fälligkeitsdatum in einem Format, das PHPs DateTime versteht, etwa 2025-12-31 oder 2025-12-31T17:30:00. null oder ein leerer String entfernt das Datum
parentTicketNumber string Ticketnummer des Elterntickets (macht das Ticket zum Subticket)
note string Interne Notiz. Wird als API gepostet und ist nur für Mitarbeiter sichtbar
noteTitle string Titel der Notiz, Standard API Update
noteFormat string Format der Notiz, Standard markdown
attachments array Anhänge der Notiz, gleiches Format wie beim Erstellen. Wird nur zusammen mit note verwendet, sonst stillschweigend ignoriert

Andere Felder, auch priority, werden ohne Fehlermeldung ignoriert.

Antwort

200 OK: die Ticketnummer als Klartext.

Beispiele

# Status ändern
curl -X PATCH "https://osticket.local/api/tickets-update.php/781258.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"statusId": "Resolved"}'

# Einem Mitarbeiter zuweisen, mit Notiz
curl -X PATCH "https://osticket.local/api/tickets-update.php/781258.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"staffId": "john.doe", "note": "Assigned to John for follow-up"}'

# Fälligkeitsdatum entfernen
curl -X PATCH "https://osticket.local/api/tickets-update.php/781258.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dueDate": null}'

Hinweise


4. GET Tickets suchen

GET /api/tickets-search.php

Berechtigung: can_search_tickets oder can_read_tickets

Parameter Typ Standard Beschreibung
query string Suche im Ticket-Betreff, ohne Beachtung der Groß-/Kleinschreibung
status string oder int Statusname oder ID
department string oder int Abteilungsname, ID oder Pfad wie Development / osTicket
limit int 20 Maximale Treffer. Werte unter 1 werden zu 20, Werte über 100 zu 100
offset int 0 Offset für die Paginierung
sort string created created (neueste zuerst), updated (zuletzt aktualisierte zuerst) oder number (aufsteigend). Andere Werte fallen auf created zurück

Ein status- oder department-Name, der nichts trifft, wird ignoriert und filtert nicht.

Antwort

Ein JSON-Array, nicht in ein Objekt verpackt. Die Einträge enthalten keinen Thread:

[
  {
    "id": 123,
    "number": "781258",
    "subject": "Login Issue",
    "statusId": 1,
    "status": "Open",
    "priorityId": 2,
    "priority": "Normal",
    "departmentId": 5,
    "department": "IT Support",
    "topicId": 10,
    "topic": "Technical Support",
    "created": "2025-11-08 10:00:00",
    "updated": "2025-11-08 14:30:00",
    "dueDate": "2025-11-15 10:00:00",
    "staffId": 3,
    "staff": "Jane Smith",
    "teamId": 2,
    "team": "Level 1 Support",
    "slaId": 1,
    "sla": "Standard SLA",
    "isOverdue": false,
    "isAnswered": true
  }
]

Beispiele

curl "https://osticket.local/api/tickets-search.php?query=login" \
  -H "X-API-Key: YOUR_API_KEY"

curl "https://osticket.local/api/tickets-search.php?query=payment&status=Open&department=Support&limit=50&offset=50" \
  -H "X-API-Key: YOUR_API_KEY"

5. DELETE Ticket löschen

Löscht ein Ticket endgültig.

Diese Aktion lässt sich nicht rückgängig machen. Das Ticket und sein Thread werden aus der Datenbank entfernt.

DELETE /api/tickets-delete.php/{number}.{format}

Berechtigung: can_delete_tickets, für jeden API-Key standardmäßig deaktiviert.

200 OK: die Nummer des gelöschten Tickets als Klartext.

curl -X DELETE "https://osticket.local/api/tickets-delete.php/781258.json" \
  -H "X-API-Key: YOUR_API_KEY"

Erwäge statt des Löschens ein PATCH auf einen geschlossenen Status.


6. GET Ticket-Statistiken

GET /api/tickets-stats.php

Berechtigung: can_read_stats oder can_read_tickets

{
  "total": 150,
  "open": 45,
  "closed": 105,
  "overdue": 3,
  "by_department": {
    "Billing": {"total": 70, "open": 25, "closed": 45, "overdue": 2},
    "Support": {"total": 80, "open": 20, "closed": 60, "overdue": 1}
  },
  "by_staff": [
    {
      "staff_id": 1,
      "staff_name": "John Smith",
      "total": 35,
      "departments": {
        "Support": {"open": 10, "closed": 20, "overdue": 0}
      }
    }
  ]
}

7. GET Statusliste

GET /api/tickets-statuses.php

Berechtigung: can_read_stats oder can_read_tickets

[
  {"id": 1, "name": "Open", "state": "open"},
  {"id": 3, "name": "Closed", "state": "closed"}
]

Die Liste ist nach der Status-Reihenfolge sortiert und enthält auch eigene Status. state ist der osTicket-Zustand des Status.


Subticket-Endpunkte

Die Endpunkte 8 bis 11 setzen das Plugin Subticket Manager (Klasse SubticketPlugin) und die Berechtigung can_manage_subtickets voraus. Sie prüfen in dieser Reihenfolge: zuerst die Eingabe (eine ungültige Ticketnummer liefert 400, Endpunkt 10 liefert zusätzlich 400 bei fehlendem childId und beim Verknüpfen eines Tickets mit sich selbst), dann die Berechtigung (403, API key not authorized for subticket operations), dann das Plugin (501, Subticket plugin not available), dann die Ticket-Suche. Die Endpunkte 10 und 11 prüfen zusätzlich die Abteilung des Tickets, aber nur, wenn das API-Key-Objekt Abteilungsbeschränkungen liefert. Standard-API-Keys von osTicket haben keine.

8. GET Elternticket abrufen

GET /api/tickets-subtickets-parent.php/{number}.{format}

number ist die Nummer des Kindtickets.

{
  "parent": {
    "ticket_id": 100,
    "number": "781200",
    "subject": "Parent Ticket",
    "status": "Open"
  }
}

Liefert {"parent": null}, wenn das Ticket kein Elternticket hat. 404 (Child ticket not found), wenn das Ticket nicht existiert.

9. GET Kindtickets abrufen

GET /api/tickets-subtickets-list.php/{number}.{format}

number ist die Nummer des Elterntickets.

{
  "children": [
    {"ticket_id": 124, "number": "781259", "subject": "Child Ticket 1", "status": "Open"},
    {"ticket_id": 125, "number": "781260", "subject": "Child Ticket 2", "status": "Closed"}
  ]
}

Liefert {"children": []}, wenn es keine gibt. 404 (Parent ticket not found), wenn das Ticket nicht existiert.

10. POST Subticket-Verknüpfung erstellen

Verknüpft zwei bestehende Tickets.

POST /api/tickets-subtickets-create.php/{parentNumber}.{format}
Body-Feld Typ Pflicht Beschreibung
childId string Ja Ticketnummer des Kindtickets
curl -X POST "https://osticket.local/api/tickets-subtickets-create.php/781200.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"childId": "781259"}'
{
  "success": true,
  "message": "Subticket relationship created successfully",
  "parent": {"ticket_id": 100, "number": "781200", "subject": "Parent Ticket", "status": "Open"},
  "child": {"ticket_id": 124, "number": "781259", "subject": "Child Ticket", "status": "Open"}
}
Code Meldung Ursache
400 Missing childId in request body childId fehlt
400 Cannot link ticket to itself Eltern- und Kindticket sind dasselbe Ticket
403 Access denied to parent ticket department oder ... child ticket department Nur wenn das API-Key-Objekt Abteilungsbeschränkungen liefert, die die Abteilung ausschließen
404 Parent ticket not found oder Child ticket not found Ticket existiert nicht
422 Subticket relationship already exists Die Verknüpfung besteht schon
422 Child ticket already has a different parent Das Kind hat ein anderes Elternticket

11. DELETE Subticket-Verknüpfung lösen

Entfernt die Eltern-Verknüpfung eines Kindtickets.

DELETE /api/tickets-subtickets-unlink.php/{number}.{format}

number ist die Nummer des Kindtickets.

{
  "success": true,
  "message": "Subticket relationship removed successfully",
  "child": {"ticket_id": 124, "number": "781259", "subject": "Child Ticket", "status": "Open"}
}
Code Meldung Ursache
403 Access denied to child ticket department Nur wenn das API-Key-Objekt Abteilungsbeschränkungen liefert, die die Abteilung ausschließen
404 Child ticket not found Ticket existiert nicht
404 Child has no parent to unlink Das Ticket hat kein Elternticket

Attachment-Endpunkt

12. GET Attachment herunterladen

Liefert eine Datei als Base64 zusammen mit ihren Metadaten.

GET /api/tickets-attachment-download.php/{file_id}.{format}

Berechtigung: can_read_tickets

Parameter Typ Beschreibung
file_id integer file_id aus den Anhang-Metadaten eines Thread-Eintrags, siehe GET Ticket abrufen
format string json oder xml
{
  "file_id": 29,
  "filename": "screenshot.png",
  "mime_type": "image/png",
  "size": 45320,
  "content": "iVBORw0KGgoAAAANSUhEUgAA..."
}
Code Meldung Ursache
400 Invalid file ID file_id kleiner als 1
403 Attachment not accessible In der Anhang-Tabelle existiert kein Eintrag mit dieser file_id
404 File not found Datei existiert nicht
500 Failed to read file content Dateiinhalt konnte nicht gelesen werden

Bevor der Endpunkt eine Datei ausliefert, prüft er, dass in der Anhang-Tabelle ein Eintrag mit dieser file_id existiert. Die Prüfung filtert nicht nach dem Typ des Objekts, zu dem der Anhang gehört.

curl -s "https://osticket.local/api/tickets-attachment-download.php/29.json" \
  -H "X-API-Key: YOUR_API_KEY" \
  | jq -r '.content' \
  | base64 -d > screenshot.png

Die ganze Datei wird in den Speicher gelesen und Base64-kodiert, wodurch die Antwort etwa ein Drittel größer ist als die Datei.

Rate Limiting

Das Plugin implementiert kein Rate Limiting. Wenn du es brauchst, richte es auf dem Webserver ein.