Kapitel: API-Referenz

Entwickler

API-Referenz

Alle öffentlichen Endpunkte der VentionDesk-API. Die Liste entsteht aus den registrierten Routen des Servers; die Zugriffsregel je Endpunkt stammt aus den Prüfungen an der Route, die Tabellen aus den Zod-Verträgen, mit denen VentionDesk Anfragen prüft und Antworten formt. Was hier steht, ist also das, was der Server tatsächlich tut.

Adressen beginnen mit https://api.ventiondesk.com. Anmeldung, Scopes, Fehlerform und Rate Limits erklärt API-Grundlagen. Pflichtfelder sind mit * markiert; ein Endpunkt ohne Tabelle prüft seinen Rumpf mit einem Vertrag, der nicht veröffentlicht ist, oder hat keinen.

Zugriff liest sich so: „Inhaber" und „Inhaber und Mitarbeitende" heißt eine angemeldete Person in der Weboberfläche; mit einem API-Schlüssel antworten solche Endpunkte mit 403. Endpunkte mit Scope erreichen auch Agenten-Schlüssel, die diesen Scope tragen.

Aufgaben

GET/v1/tasks

Aufgaben lesen, gefiltert nach Projekt, Status, Zuständigkeit oder Suchtext.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope tasks:read

Abfrageparameter

FeldTypHinweis
projectUUID
projectSlugText
status"hold" | "todo" | "in_progress" | "question" | "review" | "done"
assignee"owner" | "staff" | "claude" | "external"
claimable"true" | "false"
maxAttemptsGanzzahl≥ 1 · ≤ 20 · Vorgabe: 3
limitGanzzahl≥ 1 · ≤ 100 · Vorgabe: 20
qTextmind. 1 Zeichen

Antwort

FeldTypHinweis
tasksListe aus Objekt

POST/v1/tasks

Eine Aufgabe anlegen; ähnliche offene Aufgaben werden als Dublette erkannt.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope tasks:write

Rumpf (JSON)

FeldTypHinweis
projectIdUUID
projectSlugText
title *Textmind. 25 Zeichen
descriptionMdTextmind. 1 Zeichen
area"frontend" | "backend" | "design" | "infra" | "support"
dueDateDatum (JJJJ-MM-TT)
estimateMinutesGanzzahl> 0
triggerConditionTextmind. 1 Zeichen
evidenceTextmind. 1 Zeichen

GET/v1/tasks/:id

Eine Aufgabe mit Beschreibung, Rückmeldungen und Anhängen.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope tasks:read

Antwort

FeldTypHinweis
taskObjekt
resultsListe aus Objekt
attachmentsListe aus Objekt

PATCH/v1/tasks/:id

Felder einer Aufgabe ändern.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope tasks:write

Rumpf (JSON)

FeldTypHinweis
titleTextmind. 1 Zeichen
descriptionMdText oder null
status"hold" | "todo" | "in_progress" | "question" | "review" | "done"
assignee"owner" | "staff" | "claude" | "external" oder null
area"frontend" | "backend" | "design" | "infra" | "support" oder null
dueDateDatum (JJJJ-MM-TT) oder null
estimateMinutesGanzzahl oder null> 0
positionTextmind. 1 Zeichen
triggerConditionText oder null

POST/v1/tasks/:id/claim

Eine Aufgabe atomar übernehmen — zwei Läufe bekommen nie dieselbe.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope tasks:write

Rumpf (JSON)

FeldTypHinweis
maxAttemptsGanzzahl≥ 1 · ≤ 20 · Vorgabe: 3
runIdUUID

POST/v1/tasks/:id/decision

Freigabe oder Absage eines Menschen auf eine Rückmeldung; eine Absage verlangt einen Kommentar.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
decision *"approved" | "rejected"
commentMdTextmind. 1 Zeichen · höchstens 20000 Zeichen
attachmentIdsListe aus UUIDVorgabe: []

Antwort

FeldTypHinweis
taskObjekt
resultObjekt

POST/v1/tasks/:id/handoff

Eine Aufgabe an Claude übergeben.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope tasks:write

POST/v1/tasks/:id/result

Den Stand einer Aufgabe zurückmelden (arbeitet, kontrolle, frage, master, blockiert, erledigt).

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope tasks:write

Rumpf (JSON)

FeldTypHinweis
state *"arbeitet" | "kontrolle" | "frage" | "master" | "blockiert" | "erledigt"
summaryMdTextmind. 1 Zeichen
detailsMdTextmind. 1 Zeichen
prUrlURL
evidenceTextmind. 1 Zeichen
runIdUUID

Agenten-Läufe

POST/v1/agent/runs

Einen Lauf eines Agenten beginnen.

Zugriff nur Agenten-Schlüssel mit Scope agent:run

Rumpf (JSON)

FeldTypHinweis
projectIdUUID
projectSlugText
metaObjekt (frei)Vorgabe: {}

Antwort

FeldTypHinweis
runObjekt

POST/v1/agent/runs/:id/finish

Einen Agentenlauf abschließen, mit Zusammenfassung oder Fehlerstatus.

Zugriff nur Agenten-Schlüssel

Rumpf (JSON)

FeldTypHinweis
status *"succeeded" | "failed"
summaryTextmind. 1 Zeichen

Antwort

FeldTypHinweis
runObjekt

POST/v1/agent/runs/:id/heartbeat

Lebenszeichen eines laufenden Agentenlaufs.

Zugriff nur Agenten-Schlüssel

Antwort

FeldTypHinweis
runObjekt

Projekte

POST/v1/errors/:id/task

Aus einem Fehler eine Aufgabe anlegen.

Zugriff Inhaber und Mitarbeitende

GET/v1/errors/summary

Fehlerzahlen über alle Projekte für die Übersicht.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
projectsListe aus Objekt

POST/v1/monitors/probe

Eine Monitor-Adresse vor dem Anlegen prüfen und Weiterleitungen samt Endziel melden.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
url *URLhöchstens 2048 Zeichen

GET/v1/projects

Projekte, die das Konto oder der Schlüssel sehen darf.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope projects:read

Abfrageparameter

FeldTypHinweis
status"active" | "blocked" | "review" | "paused"
includeArchived"true" | "false"
qTextmind. 1 Zeichen

Antwort

FeldTypHinweis
projectsListe aus Objekt

GET/v1/projects/:id

Ein Projekt über seine ID.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope projects:read

PATCH/v1/projects/:id/customer

Ein Projekt einem anderen Kunden zuordnen; Tickets, Entwürfe und Dokumente ziehen mit.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
customerId *UUID

Antwort

FeldTypHinweis
projectObjekt
changedtrue | false
movedObjekt

GET/v1/projects/:id/deploy

Welche Deploy-Ziele es gibt und was jedem fehlt.

Zugriff Inhaber

Antwort

FeldTypHinweis
targetsListe aus Objekt

POST/v1/projects/:id/deploy

Einen Deploy anstoßen (202: angestoßen, nicht erfolgreich).

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
target *"production" | "staging" | "preview"
provider"vercel" | "render"

Antwort

FeldTypHinweis
provider"vercel" | "render"
target"production" | "staging" | "preview"
externalIdText oder null
startedGanzzahl> 0

POST/v1/projects/:id/error-sources

Ein Projekt beim Fehler-Tracker diesem Projekt zuordnen.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
provider *"sentry" | "bugsnag" | "rollbar"
externalId *Textmind. 1 Zeichen · höchstens 200 Zeichen

DELETE/v1/projects/:id/error-sources/:sourceId

Eine Fehlerquelle vom Projekt lösen.

Zugriff Inhaber und Mitarbeitende

GET/v1/projects/:id/errors

Fehler aus Sentry, Bugsnag oder Rollbar zu diesem Projekt.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
issuesListe aus Objekt
statsObjekt
sourcesListe aus Objekt
providersListe aus "sentry" | "bugsnag" | "rollbar"

GET/v1/projects/:id/hosting

Die Hosting-Zuordnungen des Projekts.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
mappingsListe aus Objekt
providersListe aus "netlify" | "cloudflare_pages" | "aws_amplify" | "railway" | "flyio" | "digitalocean_app_platform"

POST/v1/projects/:id/hosting

Eine Site, App oder einen Dienst beim Hosting-Anbieter zuordnen.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
provider *"netlify" | "cloudflare_pages" | "aws_amplify" | "railway" | "flyio" | "digitalocean_app_platform"
externalId *Textmind. 1 Zeichen · höchstens 200 Zeichen

DELETE/v1/projects/:id/hosting/:mappingId

Eine Hosting-Zuordnung entfernen.

Zugriff Inhaber und Mitarbeitende

DELETE/v1/projects/:id/render-services/:serviceId

Eine veraltete Render-Dienstkennung vom Projekt lösen.

Zugriff Inhaber

POST/v1/projects/:id/sync

GitHub-Daten des Projekts sofort abgleichen statt erst nachts.

Zugriff Inhaber und Mitarbeitende

GET/v1/projects/by-slug/:slug

Ein Projekt über seinen Slug.

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope projects:read

Vorgänge

GET/v1/tickets

Vorgänge lesen, gefiltert nach Status, Kanal, Priorität, Projekt oder Kunde.

Zugriff Inhaber und Mitarbeitende (Scope tickets:read ist für Agenten-Schlüssel gesperrt)

Abfrageparameter

FeldTypHinweis
status"open" | "in_progress" | "waiting" | "resolved"
source"contact_form" | "app" | "email" | "monitor" | "portal" | "phone" | "on_site" | "stripe" | "api"
priority"low" | "normal" | "high" | "critical"
projectUUID
projectSlugText
customerUUID
withSla"true" | "false"
qTextmind. 1 Zeichen
limitGanzzahl≥ 1 · ≤ 100 · Vorgabe: 50

Antwort

FeldTypHinweis
ticketsListe aus Objekt

POST/v1/tickets

Einen Vorgang anlegen, etwa nach einem Anruf.

Zugriff Inhaber und Mitarbeitende (Scope tickets:write ist für Agenten-Schlüssel gesperrt)

Rumpf (JSON)

FeldTypHinweis
subject *Textmind. 3 Zeichen
bodyMd *Textmind. 1 Zeichen
source *"contact_form" | "app" | "email" | "monitor" | "portal" | "phone" | "on_site" | "stripe" | "api"
customerIdUUID oder null
projectIdUUID oder null
priority"low" | "normal" | "high" | "critical"Vorgabe: "normal"
requesterNameText
requesterEmailE-Mail
requesterMetaObjekt (frei)

DELETE/v1/tickets/:id

Einen Vorgang löschen.

Zugriff Inhaber und Mitarbeitende

GET/v1/tickets/:id

Ein Vorgang samt Verlauf.

Zugriff Inhaber und Mitarbeitende (Scope tickets:read ist für Agenten-Schlüssel gesperrt)

Antwort

FeldTypHinweis
ticketObjekt
messagesListe aus Objekt

PATCH/v1/tickets/:id

Betreff, Status, Priorität, Kanal, Kunde, Projekt, Zuständigkeit oder Portalfreigabe eines Vorgangs ändern.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
subjectTextmind. 3 Zeichen
status"open" | "in_progress" | "waiting" | "resolved"
priority"low" | "normal" | "high" | "critical"
source"contact_form" | "app" | "email" | "monitor" | "portal" | "phone" | "on_site" | "stripe" | "api"
customerIdUUID oder null
projectIdUUID oder null
assignedToUUID oder null
portalVisibletrue | false

POST/v1/tickets/:id/messages

Einen Eintrag in den Verlauf schreiben: interne Notiz oder Entwurf. Es geht keine Mail hinaus.

Zugriff Inhaber und Mitarbeitende (Scope tickets:write ist für Agenten-Schlüssel gesperrt)

Rumpf (JSON)

FeldTypHinweis
bodyMd *Textmind. 1 Zeichen
isInternalNotetrue | falseVorgabe: false
isDrafttrue | falseVorgabe: false

POST/v1/tickets/:id/reply

Dem Kunden antworten — der einzige Weg, auf dem eine Mail hinausgeht. Setzt den Vorgang auf „wartet".

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
bodyMd *Textmind. 1 Zeichen
isInternalNotetrue | falseVorgabe: false
isDrafttrue | falseVorgabe: false
draftIdUUID

POST/v1/tickets/:id/to-task

Aus einem Vorgang eine Aufgabe anlegen.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
projectId *UUID
titleTextmind. 10 Zeichen
assignee"owner" | "staff" | "claude" | "external" oder null

GET/v1/tickets/attachments/:id/url

Kurzlebige Adresse für einen Anhang eines Vorgangs.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
urlURL
expiresInSecondsGanzzahl> 0

Notizen

POST/v1/notes

Eine Notiz an einem Projekt anlegen (Projekt-ID oder Slug).

Zugriff Inhaber, Mitarbeitende oder Agenten-Schlüssel mit Scope notes:write

Rumpf (JSON)

FeldTypHinweis
projectIdUUID
projectSlugText
bodyMd *Textmind. 1 Zeichen
kind"idea" | "decision" | "risk"Vorgabe: "idea"

Antwort

FeldTypHinweis
noteObjekt

POST/v1/notes/:id/to-task

Aus einer Notiz eine Aufgabe anlegen.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
titleTextmind. 25 Zeichen
assignee"owner" | "staff" | "claude" | "external" oder null

Antwort

FeldTypHinweis
okfalse
errorText
code"note_already_converted"
taskObjekt

Zeit

GET/v1/time/entries

Zeiteinträge lesen.

Zugriff Inhaber und Mitarbeitende

Abfrageparameter

FeldTypHinweis
fromText
toText
projectUUID
userUUID
unbilled"true" | "false"
limitGanzzahl≥ 1 · ≤ 500 · Vorgabe: 200

Antwort

FeldTypHinweis
entriesListe aus Objekt

POST/v1/time/entries

Zeit nachtragen.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
label *Textmind. 1 Zeichen
startedAt *Zeitpunkt (ISO 8601)
endedAt *Zeitpunkt (ISO 8601)
secondsGanzzahl> 0
projectIdUUID oder null
ticketIdUUID oder null
taskIdUUID oder null
billabletrue | falseVorgabe: true

DELETE/v1/time/entries/:id

Einen Zeiteintrag löschen.

Zugriff Inhaber und Mitarbeitende

PATCH/v1/time/entries/:id

Einen Zeiteintrag ändern.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
labelTextmind. 1 Zeichen
secondsGanzzahl> 0
billabletrue | false
projectIdUUID oder null
ticketIdUUID oder null

GET/v1/time/timer

Den laufenden Timer des Kontos.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
timerObjekt oder null

POST/v1/time/timer/start

Den Timer starten.

Zugriff Inhaber und Mitarbeitende

Rumpf (JSON)

FeldTypHinweis
labelTextVorgabe: ""
projectIdUUID oder null
ticketIdUUID oder null
taskIdUUID oder null

POST/v1/time/timer/stop

Den Timer stoppen und die Zeit als Eintrag erfassen.

Zugriff Inhaber und Mitarbeitende

GET/v1/time/unbilled

Abrechenbare, noch nicht berechnete Stunden je Projekt samt Betrag.

Zugriff Inhaber

Antwort

FeldTypHinweis
projectsListe aus Objekt
totalsObjekt

Kunden

DELETE/v1/customers/:id

Einen Kunden samt Dateien löschen.

Zugriff Inhaber

Antwort

FeldTypHinweis
customerIdUUID
shortNameText
impactObjekt
filesObjekt
portalAccountsObjekt

GET/v1/customers/:id/deletion

Vorschau, was beim Löschen eines Kunden mit entfernt würde.

Zugriff Inhaber

Antwort

FeldTypHinweis
customerIdUUID
shortNameText
deletabletrue | false
reasonText oder null
blockersObjekt
impactObjekt

POST/v1/customers/:id/portal-access

Einem Ansprechpartner Zugang zum Kundenportal geben.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
email *E-Mail
displayNameTextmind. 1 Zeichen

Antwort

FeldTypHinweis
accessObjekt
mailObjekt

DELETE/v1/customers/:id/portal-access/:userId

Einem Konto den Portalzugang entziehen. Ein schon ausgegebenes Token gilt bis zu seiner Erneuerung.

Zugriff Inhaber

Antwort

FeldTypHinweis
revokedObjekt

POST/v1/customers/:id/portal-access/:userId/invite

Die Einladung ins Kundenportal erneut senden.

Zugriff Inhaber

Antwort

FeldTypHinweis
mailObjekt

Dokumente

GET/v1/documents

Dokumente lesen, gefiltert nach Kunde, Projekt oder Typ.

Zugriff jedes angemeldete Konto; was es sieht, entscheidet seine Rolle

Abfrageparameter

FeldTypHinweis
customerUUID
projectUUID
type"pdf" | "image" | "sheet" | "contract" | "other"
qTextmind. 1 Zeichen · höchstens 120 Zeichen
limitGanzzahl≥ 1 · ≤ 200 · Vorgabe: 50

Antwort

FeldTypHinweis
documentsListe aus Objekt

PATCH/v1/documents/:id

Zuordnung, Typ, Schlagwörter oder Portalfreigabe eines Dokuments ändern.

Zugriff jedes angemeldete Konto; was es sieht, entscheidet seine Rolle

Rumpf (JSON)

FeldTypHinweis
nameTextmind. 1 Zeichen · höchstens 200 Zeichen
type"pdf" | "image" | "sheet" | "contract" | "other"
projectIdUUID oder null
sharedWithPortaltrue | false
tagsListe aus Text

GET/v1/documents/:id/url

Kurzlebige Adresse zum Herunterladen eines Dokuments.

Zugriff jedes angemeldete Konto; was es sieht, entscheidet seine Rolle

Antwort

FeldTypHinweis
urlURL
expiresInSecondsGanzzahl> 0

Finanzen

GET/v1/finance/export

Jahresexport für die Steuerberatung: ZIP mit einer CSV je Tabelle und den abgelegten Belegen.

Zugriff Inhaber

GET/v1/invoices

Rechnungen lesen, gefiltert nach Status, Kunde oder „überfällig“.

Zugriff Inhaber

Abfrageparameter

FeldTypHinweis
status"draft" | "open" | "overdue" | "paid" | "cancelled"
customerUUID
overdue"true" | "false"
limitGanzzahl≥ 1 · ≤ 200 · Vorgabe: 50

Antwort

FeldTypHinweis
invoicesListe aus Objekt

POST/v1/invoices

Einen Rechnungsentwurf anlegen — noch ohne Rechnungsnummer.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
customerId *UUID
projectIdUUID oder null
paymentTermsDaysGanzzahl≥ 1 · ≤ 90
vatRateGanzzahl
vatScheme"standard" | "reverse_charge"
serviceFromTextfestes Muster
serviceToTextfestes Muster
serviceDateEqualsInvoiceDatetrue | falseVorgabe: false
positionsListe aus ObjektVorgabe: []

GET/v1/invoices/:id

Eine Rechnung mit Positionen, Summen und Zahlungen.

Zugriff Inhaber

Antwort

FeldTypHinweis
invoiceObjekt
positionsListe aus Objekt

POST/v1/invoices/:id/cancel

Eine finalisierte Rechnung stornieren; es entsteht ein Stornobeleg.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
reason *Textmind. 3 Zeichen · höchstens 500 Zeichen
serviceRendered *true | false

Antwort

FeldTypHinweis
invoiceObjekt
releasedEntriesGanzzahl≥ 0
entries"released" | "failed"
correction"stored" | "skipped" | "failed"
taxOfficeConsenttrue | false

GET/v1/invoices/:id/cancellation/pdf

Den Stornobeleg als PDF.

Zugriff Inhaber

POST/v1/invoices/:id/cancellation/send

Den Stornobeleg per Mail senden.

Zugriff Inhaber

Antwort

FeldTypHinweis
mail"sent" | "skipped"
reasonTextkann fehlen
invoiceObjekt

POST/v1/invoices/:id/dunning/send

Die fällige Mahnstufe senden.

Zugriff Inhaber

Antwort

FeldTypHinweis
mail"sent" | "skipped"
reasonTextkann fehlen
invoiceObjekt
levelGanzzahl oder null≥ 1 · ≤ 4

POST/v1/invoices/:id/finalize

Einen Entwurf finalisieren: vergibt die fortlaufende Nummer, sperrt die Rechnung und legt das PDF ab.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
settleObjekt

Antwort

FeldTypHinweis
invoiceObjekt
pdf"stored" | "skipped" | "failed"
payment"none" | "booked" | "failed"
paymentErrorTextkann fehlen

POST/v1/invoices/:id/payments

Eine Zahlung oder Rückzahlung erfassen.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
amountCents *Ganzzahl
paidOnTextfestes Muster
method"transfer" | "stripe" | "cash" | "other"Vorgabe: "transfer"
noteTexthöchstens 500 Zeichen

GET/v1/invoices/:id/pdf

Die Rechnung als PDF — der beim Finalisieren abgelegte Beleg.

Zugriff Inhaber

POST/v1/invoices/:id/positions

Eine Position an einen Entwurf anhängen.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
description *Textmind. 1 Zeichen
quantity *Zahl> 0
unit"hour" | "flat"Vorgabe: "hour"
unitPriceCents *Ganzzahl≥ 0
sortGanzzahl

POST/v1/invoices/:id/remind

Eine Zahlungserinnerung senden.

Zugriff Inhaber

Antwort

FeldTypHinweis
mail"sent" | "skipped"
reasonTextkann fehlen
invoiceObjekt

POST/v1/invoices/:id/send

Eine finalisierte Rechnung per Mail versenden.

Zugriff Inhaber

Antwort

FeldTypHinweis
mail"sent" | "skipped"
reasonTextkann fehlen
invoiceObjekt

GET/v1/invoices/:id/stripe-refund

Ob und in welcher Höhe sich eine Stripe-Zahlung erstatten lässt.

Zugriff Inhaber

POST/v1/invoices/:id/stripe-refund

Eine über Stripe bezahlte Rechnung über Stripe erstatten; gebucht wird über den Webhook.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
amountCentsGanzzahl> 0

POST/v1/invoices/from-unbilled

Aus den offenen, abrechenbaren Stunden eines Projekts einen Rechnungsentwurf machen — je Zeiteintrag eine Position.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
projectId *UUID
untilDateText
paymentTermsDaysGanzzahl≥ 1 · ≤ 90
vatRateGanzzahl
vatScheme"standard" | "reverse_charge"

Antwort

FeldTypHinweis
invoiceObjekt
entriesGanzzahl≥ 0
hoursZahl≥ 0

GET/v1/quotes

Angebote lesen.

Zugriff Inhaber

Antwort

FeldTypHinweis
quotesListe aus Objekt

POST/v1/quotes

Einen Angebotsentwurf anlegen.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
title *Textmind. 3 Zeichen
customerIdUUID oder null
prospectNameText
prospectEmailE-Mail
projectIdUUID oder null
validUntilText
vatRateGanzzahl
vatScheme"standard" | "reverse_charge"
positionsListe aus ObjektVorgabe: []

GET/v1/quotes/:id/pdf

Ein Angebot als PDF.

Zugriff Inhaber

POST/v1/quotes/:id/send

Ein Angebot per Mail versenden.

Zugriff Inhaber

Antwort

FeldTypHinweis
mail"sent" | "skipped"
reasonTextkann fehlen
quoteObjekt

Anbindungen

GET/v1/integrations

Die verbundenen Quellen des Betriebs, ohne Geheimnisse.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
integrationsListe aus Objekt
plattformtrue | false
githubInstallierbartrue | false

POST/v1/integrations

Eine Quelle verbinden. Der Zugang wird beim Anbieter geprüft, bevor er gespeichert wird.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
provider *"vercel" | "render" | "netlify" | "cloudflare_pages" | "aws_amplify" | "railway" | "flyio" | "digitalocean_app_platform" | "postmark" | "mailgun" | "amazon_ses" | "resend" | "sentry" | "bugsnag" | "rollbar" | "stripe"
fields *Objekt (frei)

DELETE/v1/integrations/:id

Eine Anbindung entfernen.

Zugriff Inhaber

PATCH/v1/integrations/:id

Eine Anbindung bearbeiten; ein leeres Geheimnis bleibt unverändert.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
fields *Objekt (frei)

GET/v1/integrations/:id/webhook

Die Webhook-Adresse einer Anbindung (Stripe, Sentry, Bugsnag, Rollbar) zum Eintragen beim Anbieter.

Zugriff Inhaber

Antwort

FeldTypHinweis
urlURL
signierttrue | false
bereittrue | false

GET/v1/integrations/:provider/error-projects

Projekte, die der Zugang beim Fehler-Tracker sieht.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
resourcesListe aus Objekt

GET/v1/integrations/:provider/resources

Sites, Apps oder Dienste, die der Hosting-Zugang beim Anbieter sieht.

Zugriff Inhaber und Mitarbeitende

Antwort

FeldTypHinweis
resourcesListe aus Objekt

GET/v1/integrations/github/callback

Rückweg von GitHub nach der Installation; bindet die Installation an den Betrieb.

Zugriff signierter state und GitHub-Anmeldung

Abfrageparameter

FeldTypHinweis
installation_idTextfestes Muster
setup_actionTexthöchstens 20 Zeichen
codeTexthöchstens 200 Zeichen
stateTexthöchstens 2000 Zeichen

POST/v1/integrations/github/install-url

Adresse zur Installation der VentionDesk-App auf GitHub.

Zugriff Inhaber

Antwort

FeldTypHinweis
urlURL

Konto, Einstellungen und Verwaltung

GET/v1/admin/api-keys

Die API-Schlüssel des Betriebs, ohne Klartext.

Zugriff Inhaber

Antwort

FeldTypHinweis
keysListe aus Objekt

POST/v1/admin/api-keys

Einen Agenten- oder Eingangs-Schlüssel anlegen. Der Klartext steht nur in dieser einen Antwort.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
name *Textmind. 3 Zeichen
kind"agent" | "intake"Vorgabe: "agent"
scopes *Liste aus "projects:read" | "tasks:read" | "tasks:write" | "tickets:read" | "tickets:write" | "notes:write" | "deployments:read" | "agent:run" | "intake:write" | "access-log:write"
projectIds *Liste aus UUID oder null
expiresAtZeitpunkt (ISO 8601)

Antwort

FeldTypHinweis
keyObjekt
plaintextText

DELETE/v1/admin/api-keys/:id

Einen Schlüssel zurückziehen — wirkt sofort.

Zugriff Inhaber

DELETE/v1/admin/api-keys/:id/endgueltig

Einen zurückgezogenen Schlüssel endgültig löschen.

Zugriff Inhaber

GET/v1/admin/members

Die Mitglieder des Betriebs mit Rolle.

Zugriff Inhaber

Antwort

FeldTypHinweis
membersListe aus Objekt

PATCH/v1/admin/members/:id

Die Rolle eines Mitglieds ändern.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
role *"owner" | "staff"

Antwort

FeldTypHinweis
memberObjekt
activeHeretrue | false

DELETE/v1/admin/users/:id

Ein Portalkonto löschen; Name und Adresse im Verlauf werden vorher pseudonymisiert.

Zugriff Inhaber

Antwort

FeldTypHinweis
removedObjekt
account"kept" | "deleted" | "locked"

POST/v1/admin/users/invite

Eine Mitarbeiterin oder einen Mitarbeiter per Mail einladen.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
email *E-Mail
role *"owner" | "staff"
displayNameTextmind. 1 Zeichen

Antwort

FeldTypHinweis
userObjekt
existingAccounttrue | falsekann fehlen · Vorgabe: false

GET/v1/me

Das eigene Konto: Rolle, Betrieb, Betriebe zur Auswahl und Adressen der Dienste.

Zugriff jedes angemeldete Konto; was es sieht, entscheidet seine Rolle

Antwort

FeldTypHinweis
idUUID
role"owner" | "staff" | "customer" | "agent"
customerIdUUID oder null
displayNameTextmind. 1 Zeichen
emailE-Mail
mfaRequiredtrue | false
intakeObjekt
organizationObjekt oder nullkann fehlen · Vorgabe: null
membershipsListe aus Objektkann fehlen · Vorgabe: []
supportObjekt oder nullkann fehlen

POST/v1/me/organization

Den aktiven Betrieb wechseln, wenn das Konto mehreren angehört.

Zugriff jedes angemeldete Konto; was es sieht, entscheidet seine Rolle

Rumpf (JSON)

FeldTypHinweis
orgId *UUID

Antwort

FeldTypHinweis
organizationObjekt
role"owner" | "staff"

GET/v1/settings

Einstellungen des Betriebs, darunter der Briefkopf für Belege.

Zugriff Inhaber

Antwort

FeldTypHinweis
companyObjekt

PATCH/v1/settings

Einstellungen und Briefkopf ändern.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
company *Objekt

Antwort

FeldTypHinweis
companyObjekt

GET/v1/settings/agreements

Stand der Zustimmung zu AGB und AVV.

Zugriff Inhaber

POST/v1/settings/agreements

Einer neuen Fassung von AGB oder AVV zustimmen oder sie ablehnen.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
document *"agb" | "avv"
version *Textmind. 1 Zeichen · höchstens 40 Zeichen
decision *"accepted" | "declined"

GET/v1/settings/benachrichtigungen

Mail bei neuem Vorgang: an oder aus, Empfänger, Kanäle und Mindest-Priorität.

Zugriff Inhaber

PATCH/v1/settings/benachrichtigungen

Mail bei neuem Vorgang einstellen (nur Inhaber).

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
aktiv *true | false
empfaenger *Liste aus E-Mail oder null
kanaele *Liste aus "contact_form" | "app" | "email" | "monitor" | "portal" | "phone" | "on_site" | "stripe" | "api" oder null
mindestPrioritaet *"low" | "normal" | "high" | "critical"

GET/v1/settings/mail

Absender für Mails an Kunden und Stand der eigenen Absender-Domain.

Zugriff Inhaber

PATCH/v1/settings/mail

Absendername und Absenderadresse ändern.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
absenderNameText oder nullhöchstens 60 Zeichen
postfachnameTexthöchstens 40 Zeichen

GET/v1/settings/mail-templates

Die Mailvorlagen des Betriebs samt Standardtexten.

Zugriff Inhaber

Antwort

FeldTypHinweis
vorlagenListe aus Objekt

DELETE/v1/settings/mail-templates/:kind

Eine Mailvorlage auf den Standardtext zurücksetzen.

Zugriff Inhaber

PUT/v1/settings/mail-templates/:kind

Eine Mailvorlage speichern.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
subject *Textmind. 1 Zeichen · höchstens 200 Zeichen
html *Textmind. 1 Zeichen · höchstens 102400 Zeichen

Antwort

FeldTypHinweis
kind"invoice_send" | "invoice_reminder" | "dunning" | "invoice_cancellation" | "quote_send" | "ticket_reply" | "ticket_receipt" | "ticket_internal" | "member_invite" | "portal_invite" | "deletion_reminder"
angepassttrue | false
subjectText oder null
htmlText oder null
aktualisiertAmText oder null
bereinigttrue | false

DELETE/v1/settings/mail/domain

Die eigene Absender-Domain entfernen.

Zugriff Inhaber

POST/v1/settings/mail/domain

Eine eigene Absender-Domain anlegen; die Antwort nennt die DNS-Einträge.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
adresse *Textmind. 3 Zeichen · höchstens 254 Zeichen

POST/v1/settings/mail/domain/verify

Die DNS-Einträge der Absender-Domain prüfen lassen.

Zugriff Inhaber

Abo von VentionDesk

GET/v1/abo

Stand des VentionDesk-Abos des Betriebs: Tarif, Testphase, Sperre.

Zugriff jedes angemeldete Konto; was es sieht, entscheidet seine Rolle

Antwort

FeldTypHinweis
betriebText
tarif"solo" | "team" | "enterprise"
abrechnung"jaehrlich" | "monatlich"
status"trial" | "active" | "past_due" | "canceled"
testphaseBisText oder null
laufzeitBisText oder null
kuendigtZumText oder nullkann fehlen · Vorgabe: null
loeschungAmText oder nullkann fehlen · Vorgabe: null
gesperrttrue | falsekann fehlen · Vorgabe: false
sperrGrund"beendet" | "testphase" | "zahlungsverzug" | "anbieter" oder nullkann fehlen · Vorgabe: null
sperreAbText oder nullkann fehlen · Vorgabe: null
plaetzeGanzzahl oder null
mitgliederGanzzahl
stripeKundetrue | false
stripeAbotrue | falsekann fehlen · Vorgabe: false
befreittrue | false
stripeBereittrue | false

POST/v1/abo/cancel

Das VentionDesk-Abo zum Ende der Laufzeit kündigen.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
nonce *Textfestes Muster
grund"too_expensive" | "missing_features" | "switched_service" | "unused" | "too_complex" | "low_quality" | "customer_service" | "other"
kommentarTexthöchstens 500 Zeichen

Antwort

FeldTypHinweis
angenommentrue
ausstehendtrue | falsekann fehlen
hinweisTextkann fehlen

POST/v1/abo/change

Tarif oder Zahlungsweise des VentionDesk-Abos wechseln.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
tarif *"solo" | "team" | "enterprise"
abrechnung *"jaehrlich" | "monatlich"
plaetze *Ganzzahl≥ 1 · ≤ 10000
nonce *Textfestes Muster

POST/v1/abo/checkout

Ein VentionDesk-Abo abschließen (leitet zu Stripe Checkout).

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
tarif *"solo" | "team" | "enterprise"
abrechnung *"jaehrlich" | "monatlich"

Antwort

FeldTypHinweis
urlURL

GET/v1/abo/export

Datenexport des ganzen Betriebs als ZIP (Aufbau siehe Datenexport).

Zugriff Inhaber

POST/v1/abo/preview

Vorschau eines Tarifwechsels mit dem anteiligen Betrag.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
tarif *"solo" | "team" | "enterprise"
abrechnung *"jaehrlich" | "monatlich"
plaetze *Ganzzahl≥ 1 · ≤ 10000

Antwort

FeldTypHinweis
waehrungText
anteiligCentGanzzahl
rechnungCentGanzzahl
steuerCentGanzzahl
sofortCentGanzzahl
faelligAmText oder null
imTesttrue | false

GET/v1/abo/rechnungen

Die Rechnungen von VentionDesk an den Betrieb.

Zugriff Inhaber

Antwort

FeldTypHinweis
rechnungenListe aus Objekt

POST/v1/abo/resume

Eine Kündigung zurücknehmen, solange die Laufzeit noch läuft.

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
nonce *Textfestes Muster

Antwort

FeldTypHinweis
angenommentrue
ausstehendtrue | falsekann fehlen
hinweisTextkann fehlen

GET/v1/abo/verlauf

Verlauf des Abos: Abschluss, Wechsel, Kündigung.

Zugriff Inhaber

Antwort

FeldTypHinweis
eintraegeListe aus Objekt

POST/v1/abo/zahlungsdaten

Zahlungsdaten bei Stripe ändern (leitet zu Stripe).

Zugriff Inhaber

Rumpf (JSON)

FeldTypHinweis
nonce *Textfestes Muster

Antwort

FeldTypHinweis
urlURL

GET/v1/abo/zahlungsmittel

Das hinterlegte Zahlungsmittel des Abos.

Zugriff Inhaber

Antwort

FeldTypHinweis
zahlungsmittelObjekt oder null

Öffentlicher Eingang

POST/f/:publicKey

HTML-Formular einer fremden Seite: legt einen Vorgang an (application/x-www-form-urlencoded).

Zugriff öffentlicher Projektschlüssel (vd_pub_…) in der Adresse

Antwort

FeldTypHinweis
oktrue
ticketObjekt

POST/v1/contact

Kontaktformular der VentionDesk-Website (Impressum).

Zugriff öffentlich

Antwort

FeldTypHinweis
oktrue

POST/v1/intake/reports

Meldung aus dem Browser einer Kunden-App, optional mit Bildschirmfoto — mit dem öffentlichen Projektschlüssel.

Zugriff öffentlicher Projektschlüssel im Kopf x-ventiondesk-key, erlaubte Herkunft

Antwort

FeldTypHinweis
oktrue
ticketObjekt

POST/v1/intake/tickets

Vorgang von Server zu Server einliefern, optional mit Bildschirmfoto — mit einem Eingangs-Schlüssel.

Zugriff Eingangs-Schlüssel (vd_intake_…) als Bearer

Antwort

FeldTypHinweis
oktrue
ticketObjekt

POST/v1/signup

Registrierung eines neuen Betriebs samt Inhaber-Konto.

Zugriff öffentlich

Antwort

FeldTypHinweis
oktrue
emailE-Mail
testphaseBisText
checkoutUrlURL oder nullkann fehlen · Vorgabe: null
testtrue | falsekann fehlen · Vorgabe: false

MCP

ALL/mcp

Jede andere Methode als POST antwortet mit 405 und Allow: POST.

Zugriff öffentlich

POST/mcp

MCP-Server über HTTP (zustandslos): die Werkzeuge für Claude, mit einem Agenten-Schlüssel.

Zugriff Agenten-Schlüssel (vd_live_…) als Bearer

Webhooks

POST/webhooks/errors/:provider/:integrationId

Webhook eines Fehler-Trackers mit Signatur im Kopf (Sentry).

Zugriff Signatur des Anbieters

POST/webhooks/errors/:provider/:integrationId/:token

Webhook eines Fehler-Trackers mit Geheimnis in der Adresse (Bugsnag, Rollbar).

Zugriff Geheimnis in der Adresse

POST/webhooks/stripe/:orgId

Stripe-Webhook des eigenen Stripe-Kontos eines Betriebs: bucht Zahlungen und Erstattungen von Rechnungen.

Zugriff Signatur Stripe-Signature

Betrieb und Bezahllink

GET/api/health

Lebenszeichen des Dienstes — antwortet, solange der Prozess läuft.

Zugriff öffentlich

GET/api/health/ready

Bereitschaft: meldet, welche Dienste konfiguriert sind; ohne Datenbank „degraded“.

Zugriff öffentlich

GET/pay/:token

Bezahllink einer Rechnung: leitet (303) zur Bezahlseite von Stripe weiter. Der Link steht in Rechnungsmail und PDF.

Zugriff Token in der Adresse

GET/pay/:token/abgebrochen

Rücksprungseite, wenn die Zahlung bei Stripe abgebrochen wurde.

Zugriff Token in der Adresse

GET/pay/:token/danke

Rücksprungseite nach erfolgreicher Zahlung bei Stripe.

Zugriff Token in der Adresse