Integriere ProbeTailor in Minuten
REST-Endpunkte mit Bearer-Token-Auth + signierte Outbound-Webhooks. cURL-, JavaScript- und Python-Beispiele inklusive — und Live-Test direkt aus der Doku.
Quickstart
Drei Schritte vom Account zum ersten erfolgreichen Aufruf.
- 1API-Key erstellenUnter Einstellungen → API-Schlüssel einen neuen Schlüssel anlegen. Das Plaintext-Secret wird einmalig angezeigt.
- 2Request sendenAuthorization-Header setzen und einen GET-Request gegen /api/v1/me schießen.
- 3Webhooks abonnierenOptional: Webhook-URL eintragen und Events wählen. Wir signieren jeden Versand per HMAC-SHA256.
- 4Schnittstelle als OpenAPIAlle Adressen unter /api/v1 mit Scopes, Rümpfen und Webhook-Ereignissen stehen maschinenlesbar unter /api/v1/openapi.json — zum Erzeugen eines Clients oder für ein Werkzeug wie Postman.
# 1) Verifizieren, dass dein Key tickt
curl https://app.probetailor.com/api/v1/me \
-H "Authorization: Bearer sb_<dein_key>"
# 2) Templates auflisten
curl https://app.probetailor.com/api/v1/templates?limit=10 \
-H "Authorization: Bearer sb_<dein_key>"Authentifizierung
Alle Endpunkte erwarten einen Bearer-Token im Authorization-Header.
Beim Anlegen eines API-Keys bekommst du einen Plaintext-Token im Format sb_<prefix>_<secret>. Der Server speichert nur den SHA-256-Hash — du musst den Token sicher aufbewahren.
Authorization: Bearer sb_<prefix>_<secret>- read — GET auf Templates, Members, Workspace-Metadaten.
- write — Reserviert für zukünftige POST/PUT/DELETE-Endpunkte (Templates, Invites).
Endpunkte
Alle Endpunkte unter /api/v1. JSON-Responses, paginiert via limit-Parameter.
/api/v1/meGibt das aktive Tenant + Scope-Info des API-Keys zurück. Perfekt für eine 'API-Key gültig?'-Probe.
curl https://app.probetailor.com/api/v1/me \
-H "Authorization: Bearer sb_<key>"Beispiel-Response
{
"tenant": {
"id": "f9c8…",
"name": "Acme GmbH",
"slug": "acme",
"subscription_tier": "Trial",
"created_at": "2026-…"
},
"api_key": { "id": "8a2b…", "scopes": ["read"] }
}/api/v1/templatesListet alle Mail-Templates des Workspaces. Optional: ?limit=1-100 und ?category=Onboarding|Transactional|Marketing|System|Custom.
curl "https://app.probetailor.com/api/v1/templates?limit=50&category=Onboarding" \
-H "Authorization: Bearer sb_<key>"Beispiel-Response
{
"data": [
{
"id": "ab12…",
"name": "Willkommens-Mail",
"category": "Onboarding",
"default_locale": "de-DE",
"subject": "Willkommen bei {{workspace_name}}…",
"variables": [
{ "name": "first_name", "label": "Vorname", "example": "Anna" }
],
"is_default": true,
"updated_at": "2026-…"
}
],
"count": 1
}/api/v1/templates/{id}Detail-View eines einzelnen Templates inklusive aller Locale-Übersetzungen (Subject + Markdown-Body).
curl https://app.probetailor.com/api/v1/templates/ab12… \
-H "Authorization: Bearer sb_<key>"/api/v1/membersListet alle Workspace-Mitglieder mit Rolle, Beitrittsdatum, E-Mail und Anzeigename.
curl https://app.probetailor.com/api/v1/members \
-H "Authorization: Bearer sb_<key>"/api/v1/systeme/{system}/katalogTestkatalog eines geprüften Systems hochladen (tests.json je Vorhaben). Scope: test.katalog.sync. Gleicher Stand → 200 unveraendert, neuer Stand → 201 mit version_id, ungültige Datei → 422 mit vorhaben, pfad, meldung.
curl -X POST https://app.probetailor.com/api/v1/systeme/tailor-plattform/katalog \
-H "Authorization: Bearer sb_<key>" \
-H "Content-Type: application/json" \
--data '{"commit_sha":"1a4d14c","dateien":{"belegfluss":{…}}}'/api/v1/ci-laeufeErgebnisse automatischer Tests als CI-Läufe melden — je Welle ein abgeschlossener Lauf. Scope: test.ci. lauf_ref macht den Aufruf idempotent (gleicher lauf_ref → 200, nichts doppelt). Zwei Wege: JSON mit ergebnisse je Fall, oder der Testbericht selbst als Rumpf mit ?format=junit|pytest|cucumber|robot|testng|playwright|cypress|auto und system, lauf_ref in der Adresse (höchstens 4 MB). Zuordnung im Bericht über die Annotation pt:<fall_id> oder einen Testnamen, der mit der Fall-Kennung beginnt; Tests ohne Fall stehen in ohne_fall, unbekannte Fälle in unbekannt. Kommandozeile: npx @clouddna/probetailor upload.
curl -X POST https://app.probetailor.com/api/v1/ci-laeufe \
-H "Authorization: Bearer sb_<key>" \
-H "Content-Type: application/json" \
--data '{"system":"tailor-plattform","lauf_ref":"gh-123","commit_sha":"1a4d14c","ergebnisse":[{"fall_id":"BF4-T03","status":"failed","fehler":"…"}]}'
# oder den Testbericht selbst (Format am Inhalt erkannt)
curl -X POST "https://app.probetailor.com/api/v1/ci-laeufe?format=auto&system=tailor-plattform&lauf_ref=gh-123" \
-H "Authorization: Bearer sb_<key>" \
--data-binary @report.xml/api/v1/sap/calm/{system}/testcasesSAP Cloud ALM, Test Automation: Cloud ALM ruft ProbeTailor als Testwerkzeug auf. Scope: test.sap; Anmeldung Bearer oder Basic mit dem Schlüssel als Passwort. Die Fälle des aktiven Katalogs als Testfälle (testCaseId ist die Fall-ID, url führt zum Fall).
curl -u "calm:sb_<key>" "https://app.probetailor.com/api/v1/sap/calm/tailor-plattform/testcases"/api/v1/sap/calm/{system}/testdatavariantsSAP Cloud ALM, Test Automation. Scope: test.sap. Ein Testdatenvariant je Fall mit derselben Kennung; ?testCaseId= grenzt ein. ProbeTailor führt jeden Fall mit seinen eigenen Testdaten aus.
curl -u "calm:sb_<key>" "https://app.probetailor.com/api/v1/sap/calm/tailor-plattform/testdatavariants"/api/v1/sap/calm/{system}/testcases/executeSAP Cloud ALM, Test Automation. Scope: test.sap. Fälle starten. Rumpf: Liste mit testCaseId (oder { testCases: [...] }). Je Fall ein Job; er ist fertig, sobald der Fall nach dem Start in ProbeTailor ein Ergebnis hat.
curl -X POST -u "calm:sb_<key>" "https://app.probetailor.com/api/v1/sap/calm/tailor-plattform/testcases/execute" \
-H "Content-Type: application/json" --data '[{"testCaseId":"BF4-T03"}]'/api/v1/sap/calm/{system}/job/statusSAP Cloud ALM, Test Automation. Scope: test.sap. Stand der Jobs (?jobID=, mehrere mit Komma): running, finished oder unknown, mit percentage.
curl -u "calm:sb_<key>" "https://app.probetailor.com/api/v1/sap/calm/tailor-plattform/job/status"/api/v1/sap/calm/{system}/testcases/executionhistorySAP Cloud ALM, Test Automation. Scope: test.sap. Letztes Ergebnis je Fall: PASS als successful, FAIL und BLOCKED als failed, Message mit Zeit, Notiz und Link zum Lauf (höchstens 1000 Zeichen). ?testCaseId= oder ?jobID= grenzen ein.
curl -u "calm:sb_<key>" "https://app.probetailor.com/api/v1/sap/calm/tailor-plattform/testcases/executionhistory"/api/v1/sap/calm/{system}/scopechangedSAP Cloud ALM, Test Automation. Scope: test.sap. Cloud ALM meldet eine Änderung am Scope; die Antwort bestätigt nur — der nächste Abgleich holt die Testfälle.
curl -X POST -u "calm:sb_<key>" "https://app.probetailor.com/api/v1/sap/calm/tailor-plattform/scopechanged" \
-H "Content-Type: application/json" --data '{}'/api/v1/sap/calm/{system}/createtestcaseSAP Cloud ALM, Test Automation. Scope: test.sap. Neuen Fall im Vorhaben cloud-alm anlegen (name, description); die Review-Regel des Systems gilt. Antwort: id und url.
curl -X POST -u "calm:sb_<key>" "https://app.probetailor.com/api/v1/sap/calm/tailor-plattform/createtestcase" \
-H "Content-Type: application/json" --data '{"name":"Bestellung freigeben","description":"…"}'/api/v1/filesDatei hochladen (multipart/form-data, Feld file). Scope: write. Legt die Datei im documents-Bucket an und gibt id, path, sha256, bytes zurück.
curl -X POST https://app.probetailor.com/api/v1/files \
-H "Authorization: Bearer sb_<key>" \
-F "file=@beleg.pdf"/api/v1/files/{id}Metadaten/Status einer hochgeladenen Datei. Scope: read.
curl https://app.probetailor.com/api/v1/files/ab12… \
-H "Authorization: Bearer sb_<key>"/api/v1/service-desk/ticketsService Desk (Modul „Service-Desk-Schnittstelle“): Vorgänge lesen (Scope read; status, channel, limit, before) und mit POST anlegen (Scope write; title, description, kind, severity, impact_scope, customer_ref, reporter_email, external_ref — mit external_ref ohne Doppel). Interne Notizen nie. Felder: docs/SERVICE-DESK-API.md.
curl "https://app.probetailor.com/api/v1/service-desk/tickets?status=New&limit=20" \
-H "Authorization: Bearer sb_<key>"
curl -X POST "https://app.probetailor.com/api/v1/service-desk/tickets" \
-H "Authorization: Bearer sb_<key>" -H "Content-Type: application/json" \
-d '{"title":"Export bricht ab","severity":"High","external_ref":"crm-4711"}'/api/v1/service-desk/tickets/{nummer}Ein Vorgang mit seinem öffentlichen Gespräch (Antworten, Rückfragen, Antworten des Melders) — ohne interne Notizen, ohne Namen von Bearbeitern.
curl https://app.probetailor.com/api/v1/service-desk/tickets/ST-2026-0001 \
-H "Authorization: Bearer sb_<key>"/api/v1/usageKI-Kosten und Token, aggregiert über einen Zeitraum. Scope: read. Parameter: from/to (YYYY-MM-DD, Vorgabe laufender Monat), unit_id, document_id, group_by = feature | unit | day | none (Vorgabe feature). Beträge in cost_cents als US-Cent; die Preise stammen aus dem Vercel AI Gateway.
curl "https://app.probetailor.com/api/v1/usage?from=2026-09-01&group_by=feature" \
-H "Authorization: Bearer sb_<key>"Webhooks
Outbound POST-Requests an deinen Endpunkt bei wichtigen Workspace-Events.
Jeder Versand trägt eine HMAC-Signatur im X-SaaSBase-Signature Header, identisch zum Stripe-Format:
X-SaaSBase-Signature: t=<unixSeconds>,v1=<hmac-sha256-hex>Signierter Payload ist <unixSeconds>.<rawBody>
Verfügbare Events
Subscribe pro Webhook gezielt nur die Events, die dich interessieren — oder '*' für alle.
| Event | Wann? |
|---|---|
invite.created | Beim Anlegen einer neuen Einladung im Workspace. |
invite.accepted | Wenn jemand die Einladung annimmt und Member wird. |
invite.revoked | Wenn ein Owner/Admin die Einladung widerruft. |
member.role_changed | Wenn die Rolle eines Members geändert wird. |
template.created | Wenn ein neues Mail-Template angelegt wurde. |
template.updated | Wenn ein Template gespeichert wurde (Meta oder Inhalt). |
template.deleted | Wenn ein Template gelöscht wurde. |
service_desk.ticket.created | Service Desk: ein Vorgang ist neu (Portal, Mail, App, API). |
service_desk.ticket.replied | Service Desk: öffentliche Antwort, Rückfrage oder Antwort des Melders — nie interne Notizen. |
service_desk.ticket.status_changed | Service Desk: gelöst, zugewiesen oder zusammengeführt. |
pt.lauf.gestartet | Ein Testlauf beginnt (im Portal, im geprüften System oder über die MCP-Schnittstelle). |
pt.lauf.abgeschlossen | Ein Testlauf ist abgeschlossen, auch ein CI-Lauf. |
pt.ergebnis.bewertet | Ein Fall wurde bewertet: PASS, FAIL, BLOCKED oder NOT RUN, mit Lauf und Katalogstand. |
pt.befund.erfasst | Ein Fall steht auf FAIL oder BLOCKED — mit Notiz und Link zum Fall, für Teams-, Slack- oder Ticket-Automatik. |
pt.abnahme.entschieden | Die Abnahme einer Welle ist erteilt oder verweigert, mit Begründung. |
Signatur verifizieren
Im Receiver: Header parsen, HMAC neu berechnen, mit timingSafeEqual vergleichen. Timestamp-Drift > 5 Min verwerfen (Replay-Schutz).
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map(kv => kv.split("=")));
const t = parseInt(parts.t, 10);
if (Math.abs(Math.floor(Date.now() / 1000) - t) > 300) return false;
const expected = createHmac("sha256", secret)
.update(`${t}.${rawBody}`).digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(parts.v1, "hex");
return a.length === b.length && timingSafeEqual(a, b);
}Fehlercodes
Standard-HTTP-Codes. Body bei Fehlern: {"error": "<message>"}.
| Status | Meaning | Hint |
|---|---|---|
| 200 | OK | Request erfolgreich. |
| 400 | Bad Request | Ungültige Parameter oder Body. |
| 401 | Unauthorized | Bearer-Token fehlt, ungültig oder widerrufen. Auch: fehlender Scope. |
| 404 | Not Found | Ressource existiert nicht oder gehört nicht zu deinem Tenant. |
| 500 | Server Error | Unerwarteter Fehler. Hilf uns bitte mit Support-Ticket. |
Bereit zum Loslegen?
Hol dir deinen ersten API-Key in 30 Sekunden — und integriere ohne Discovery-Call.