Zum Inhalt springen

Anleitungen

Aufgaben

Eine Aufgabe wählt eine Empfängerliste mit einem Agenten an, nach Regeln, die Sie vorab festlegen - Budget, Anruffenster, Anzahl der Versuche. Nichts wird gewählt, solange Sie die Aufgabe nicht selbst starten.

Was eine Aufgabe ist

Eine Aufgabe (task_...) ist eine ausgehende Kampagne: ein Agent auf dem volai-Motor, eine Liste von Empfängern mit Telefonnummer und optionalen Variablen für den System-Prompt sowie Regeln (Budget, Anruffenster, maximale Anzahl der Versuche und Gesprächsdauer). Es gibt drei Typen nach Zweck - invoice (Zahlungserinnerung), appointment (Terminbestätigung) und custom (alles andere) - bei den ersten beiden trägt zusätzlich, wenn source den Wert integration hat, jeder Empfänger einen Verweis auf den Beleg oder das Ereignis (externalRefs), den der Agent im Gespräch erwähnt.

Der Agent muss auf dem eigenen volai-Motor laufen (useForOutboundTasks: true beim Anlegen, siehe POST /v1/agents), nicht bei ElevenLabs - der Motor beherrscht Variablen für den System-Prompt, Obergrenzen für die Gesprächsdauer und die Prüfung, dass sich seine Konfiguration während der Kampagne nicht geändert hat. Der Entwurf des Agenten muss VERÖFFENTLICHT sein (PATCH /v1/agents/{id} oder POST /v1/agents/{id}/draft/publish) UND die veröffentlichte Version muss GETESTET sein (POST /v1/agents/{id}/simulate) - fehlt einer der Schritte, liefert start den Fehler agent_not_ready.

Status und Übergänge

In der Praxis geht eine Aufgabe immer von `draft` direkt zu `running` (`start`); löschen (`DELETE`) lässt sie sich nur in den markierten Status.

draft
BedeutungGerade angelegt, start lief noch nie. Bearbeitbar (PATCH), löschbar.
ready
BedeutungEin Modellstatus zwischen draft und running, den start als Ausgangspunkt akzeptiert - kein öffentlicher Endpunkt (weder REST noch MCP) versetzt eine Aufgabe jedoch heute in diesen Status, sodass er Ihnen in der Praxis nicht begegnet. Träte er ein, ist die Aufgabe wie draft bearbeitbar und löschbar.
running
BedeutungWählt Empfänger an. NICHT bearbeitbar - PATCH liefert ausnahmslos task_not_editable. Wer Variablen ändern muss, hält die Aufgabe zuerst an (POST .../pause) und ändert erst in paused - und nur solange noch kein Empfänger angewählt wurde; nach dem ersten Versuch lassen sich recipients (und damit die Variablen) nicht mehr austauschen (items_immutable), es bleibt nur, eine neue Aufgabe anzulegen. Löschen ist nicht möglich. Stößt die Aufgabe auf ein Anruflimit (rate_limited - Limit der ausgehenden Minuten des eigenen Motors, Obergrenze seiner gleichzeitigen ausgehenden Anrufe, standardmäßig 10 Anrufe pro Minute oder 1000 pro Tag), bleibt sie running: Sie setzt lastError: "rate_limited", der Versuch wird nicht gezählt, und wartende Kontakte erhalten items[].nextAttemptAt zum Ende des Limits (nach Retry-After, sonst nach 5 Minuten; bei der Obergrenze der gleichzeitigen Anrufe sendet der Motor Retry-After: 30). Nach Ablauf läuft sie von selbst weiter. Genauso wartet sie, wenn das Kontingent gleichzeitiger Anrufe des Agenten je Konto voll ist (relay_lease_limit, standardmäßig 2 laufende Anrufe): lastError: "relay_lease_limit", nächster Versuch nach einer Minute, der Versuch wird nicht gezählt. Eine besetzte Nummer (destination_busy - auf dieselbe Nummer läuft gerade ein anderer Anruf, etwa aus einer anderen Aufgabe oder einem manuellen Anruf, oder sie ist nach einem unsicheren Wählvorgang 15 Minuten gesperrt) lässt nur den betroffenen Kontakt warten, nicht die ganze Aufgabe: items[].lastError: "destination_busy", items[].nextAttemptAt nach der Restdauer der Nummernsperre (mindestens 30 s, höchstens 16 min, ohne Sperre 90 s), der Versuch wird nicht gezählt (countsAsAttempt: false) und die übrigen Kontakte werden weiter angerufen. Nach dem 6. Besetztfall in Folge (also nach 5 Wartezeiten) geht der Kontakt mit reviewReason: "dial:destination_busy" in review. Ein dauerhaftes Hindernis bei der Nummer (on_dnc, destination_auto_blocked, cannot_call_own_number, cannot_call_volai_number, invalid_number, unsupported_country, blocked_destination) hält die Aufgabe ebenfalls nicht an: Der Kontakt geht mit reviewReason: "dial:<Code>" in review (es kam kein Anruf zustande, daher hat der Versuch countsAsAttempt: false und verbraucht maxAttempts nicht), die Aufgabe bleibt running, ruft die übrigen Kontakte an und wechselt erst in needs_attention, wenn keine andere Arbeit mehr übrig ist. Hält der Betreiber von volai den Agenten der Aufgabe manuell an, bleibt die Aufgabe running und wählt nichts an; nach der Wiederaufnahme läuft sie von selbst weiter. Einen angehaltenen Agenten erkennen Sie an suspended: true in GET /v1/agents/{id}.
paused
BedeutungVor dem nächsten Anruf angehalten (POST .../pause); ein laufender Anruf wird zu Ende geführt. Bearbeitbar, löschbar, start setzt sie fort. Eine Pause mitten im Anruf hinterlässt reviewReason: "dispatch_in_flight", bis reconcile (der Planer startet es innerhalb weniger Minuten) diesen Anruf abgerechnet hat, und bis dahin lehnt start mit task_needs_attention ab; danach bleibt eine Aufgabe mit Restarbeit paused, auch wenn andere Kontakte in review warten. Eine Pause, die knapp vor den eigentlichen Anruf fällt (der Anruf ist noch nicht entstanden), hinterlässt kein dispatch_in_flight: Der Planer stellt den Kontakt zurück zu den wartenden, und die Aufgabe ist sofort paused ohne Grund. Einen Kontakt, dessen Verarbeitung ein Absturz unterbrochen hat, bevor ein Anruf entstand, gibt reconcile frühestens 15 Minuten nach Beginn des Wählvorgangs frei (Claim 10 Minuten plus 5 Minuten Reserve) und stellt ihn zurück zu den wartenden; eine Aufgabe, die inzwischen wegen eines abgelaufenen Claims angehalten wurde (dispatch_claim_expired), wechselt dann in paused. Endet ein laufender Anruf ohne bekannten Preis, wechselt die Aufgabe zunächst in needs_attention mit reviewReason: "billing_unknown" und kehrt erst in paused zurück, wenn der Preis vorliegt (reconcile ergänzt ihn). Senken Sie maxAttempts inzwischen so, dass kein auf den nächsten Versuch wartender Kontakt mehr einen freien Versuch hat, bleibt die Aufgabe paused (ein solcher Kontakt zählt als Arbeit), aber start lehnt sie mit task_not_startable ab, bis Sie maxAttempts erhöhen.
completed
BedeutungAlle Empfänger haben ein Endergebnis. Löschbar (es gilt nichts mehr).
needs_attention
BedeutungEtwas erfordert einen Eingriff - typischerweise hat sich während der Laufzeit die Konfiguration des Agenten geändert (agent_version_changed), der Motor war vorübergehend nicht erreichbar (engine_contract_unavailable) oder der Preis eines bereits geführten Anrufs ist noch nicht bekannt (billing_unknown). POST .../reconcile gleicht den Zustand ab; löschbar, solange kein Element in_progress geblieben ist. Einen Kontakt im Status review erledigen Sie über POST .../items/{itemId}/resolve (retry/skip); ein Kontakt mit dauerhaftem Hindernis bei der Nummer (dial:on_dnc, dial:destination_auto_blocked, dial:cannot_call_own_number, dial:cannot_call_volai_number, dial:invalid_number, dial:unsupported_country, dial:blocked_destination oder dial:destination_busy nach dem 6. Besetztfall in Folge) hält die Aufgabe so erst an, wenn die übrigen Kontakte durchgelaufen sind. Ein unsicheres Ergebnis des Wählvorgangs (z. B. dial:engine_unavailable) schickt die Aufgabe sofort in needs_attention, und die übrigen Kontakte werden nicht angewählt. Sobald der Anruf hinter einer solchen Unterbrechung (oder einem unbekannten Preis) über reconcile abgerechnet ist, wechselt die Aufgabe in paused, solange irgendein Kontakt auf den nächsten Versuch wartet, auch wenn andere in review sind; nach needs_attention nur, wenn außer einem Kontakt in review nichts mehr anzuwählen ist, und nach completed, wenn nichts mehr übrig ist. Ein Wählvorgang, dessen Ergebnis unsicher bleibt (der Anruf lässt sich nicht finden), hält die Aufgabe in needs_attention, bis Sie über den Kontakt entscheiden. Bei einem gewöhnlichen Grund wechselt die Aufgabe nach der letzten Entscheidung in paused, wenn noch Arbeit übrig ist, oder in completed, wenn alle Kontakte erledigt oder übersprungen sind. Ein Grund auf Ebene der ganzen Aufgabe bleibt in needs_attention, bis er behoben ist; Ausnahme ist budget_exceeded, bei dem das Überspringen aller auf einen weiteren Versuch wartenden Kontakte die Aufgabe abschließt, sofern kein Zustand beim Anbieter mehr aussteht. Das besondere Vorgehen bei billing_unknown steht weiter unten.

Genaue Bedingung zum Löschen: Der Status ist einer der oben markierten UND KEIN Element hat status: "in_progress" (ein laufender Anruf, der noch nicht beendet ist) - sonst task_not_deletable.

Import von Empfängern (CSV)

POST /v1/tasks/csv-preview parst die CSV und gibt sie mit Fehlern je Zeile zurück - es wird NICHTS gespeichert, es ist nur eine Vorschau vor dem Anlegen oder Ändern einer Aufgabe. Dieselbe Funktion ruft auch das Formular für neue Aufgaben im Portal auf.

  • Das Trennzeichen wird anhand der ersten Zeile automatisch erkannt (Komma oder Semikolon).
  • Es muss eine Spalte phone geben - Groß- und Kleinschreibung, Leerzeichen um den Namen und ein Doppelpunkt dahinter spielen keine Rolle, und auch telefon, tel oder mobil werden akzeptiert; in der Vorschau wird die Spalte immer als phone zurückgegeben. Eine bloße Nummernliste ohne Kopfzeile (eine pro Zeile, eine einzige Spalte) wird ebenfalls akzeptiert. Sonst scheitert die gesamte CSV an dem einen Fehler phone bei der Kopfzeile.
  • Jede weitere Spalte ist eine Variable für den System-Prompt des Agenten ({{column_name}}) - höchstens 20 Spalten, Name höchstens 64 Zeichen, Wert höchstens 512 Zeichen.
  • Die Telefonnummer wird wie überall in der API normalisiert (normalizePhone) - eine ungültige oder leere Nummer ist nur in DIESER Zeile ein Fehler, der Rest der CSV wird weiter verarbeitet.
  • Eine Zelle, die wie eine Tabellenkalkulationsformel aussieht (beginnt mit =, +, - oder @), wird abgelehnt - Schutz vor CSV-Injection beim Öffnen in Excel.
  • Höchstens 1000 Zeilen pro CSV (dieselbe Obergrenze wie die Zahl der Empfänger einer Aufgabe) und 1 MB Rohtext; die ganze Aufgabe samt Unterlagen muss in 2 MB passen, sonst liefert das Anlegen validation.

Die Antwort enthält headers, delimiter, rows (jede Zeile mit ihren Fehlern), validRows (nur die einwandfreien, genau in der Form, die recipients in POST /v1/tasks erwartet) und die zusammenfassenden errors. Senden Sie validRows beim Anlegen oder Ändern der Aufgabe direkt als recipients.

Budget und Anruffenster

Budget

budgetHal ist die OBERGRENZE der Ausgaben in Heller für die gesamte Aufgabe. Beim Anlegen muss es mindestens einen Versuch in maximaler Länge abdecken (sonst budget_too_low); beim Start wird vor JEDEM Wählvorgang der höchstmögliche Preis des Versuchs reserviert (reservedBudgetHal), erst ein angenommener Anruf schlägt sich in spentHal nieder. Die Reservierung entspricht dem Preis eines Anrufs in genau der Länge maxDurationSecs (Anrufabschnitt und Agentenabschnitt, jeweils wie bei der Abrechnung auf den Heller aufgerundet), und ein durch die Längenobergrenze beendeter Anruf wird höchstens für maxDurationSecs abgerechnet, auch wenn er einen Sekundenbruchteil später endet. Eine Aufgabe gibt nie mehr aus, als Sie ihr in budgetHal geben.

Anruffenster

callingWindow ist {timezone: "Europe/Prague", start, end, days} - heute wird nur die Prager Zeitzone unterstützt, start/end im Format HH:MM (das Ende gilt einschließlich der ganzen Minute: Das Fenster 09:00-18:00 lässt den letzten Anruf um 18:00:59 zu, ein Fenster bis 23:59 deckt den ganzen Tag ab) und days als Zahlen 0-6 (0 = Sonntag). Ohne Angabe gelten Werktage 9:00-18:00. Außerhalb des Fensters liefert start window_closed - warten Sie entweder, bis es öffnet, oder passen Sie das Fenster über PATCH an. Das optionale expiresAt ist das Ende der Kampagne als positive sichere Ganzzahl in Unix-Millisekunden. Es wird beim Start und vor jedem Wählvorgang geprüft, auch dem ersten. Ab diesem Zeitpunkt beginnt kein neuer Anruf, und kein Versuch wird verbraucht; ein laufender Anruf wird zu Ende geführt. Der Wiederholungshorizont der Richtlinie lorela_enterprise (retryMaxAgeDays, standardmäßig 5) wird dagegen als N × 24 Stunden ab dem ersten gezählten Versuch berechnet, nicht ab dem Anlegen der Aufgabe.

Versuche und Gesprächsdauer

maxAttempts beträgt ohne Richtlinie 1-3 (Standard 1), mit retryPolicy: "lorela_enterprise" 1-4 (beim Anlegen Standard 4). Es legt die höchste Anzahl automatischer Wählvorgänge je Kontakt einschließlich des ersten fest (1 = keine Wiederholung). Gezählt wird jeder Versuch, bei dem der Anruf stattfinden konnte, also auch ein nicht angenommener oder vom Angerufenen abgelehnter Anruf und ein Versuch mit unsicherem Ergebnis. Nicht gezählt wird ein Versuch, den volai schon vor dem Wählen abgelehnt hat (zum Beispiel gesperrte, eigene oder ungültige Nummer, Do-not-call-Liste, eine Nummer, auf die gerade ein anderer Anruf läuft, Anruflimits); ein solcher Versuch hat items[].attempts[].countsAsAttempt: false. Nicht gezählt wird auch ein Anruf, dessen Ziel der Betreiber nicht rechtzeitig erhielt, sodass das Telefon des Angerufenen gar nicht klingelte (der Versuch hat errorCode: "relay_not_routed", der Anruf endReason: "rejected"): Der Kontakt erhält frühestens nach einer Minute einen neuen Versuch (mit der Richtlinie lorela_enterprise nach deren Zeitplan), und nach dem dritten solchen Versuch in Folge geht er mit reviewReason: "call:relay_not_routed" zur Prüfung. Nicht gezählt wird auch ein Anruf, über den unser Sprachmotor nie berichtet hat und den wir nach zwei Stunden ohne Meldung als nicht gewählt und ohne Preis abgeschlossen haben (der Versuch hat errorCode: "no_provider_report"): Der Kontakt kehrt zu den wartenden zurück und erhält frühestens nach einer Minute einen neuen Versuch (mit der Richtlinie lorela_enterprise nach deren Zeitplan). Drei nicht gezählte Versuche in Folge, auch gemischt mit relay_not_routed-Versuchen, schicken den Kontakt mit dem reviewReason des letzten von ihnen zur Prüfung, also call:no_provider_report; Kontakte, die ein solcher Anruf früher zur Prüfung geschickt hat (call:failed, mit der Richtlinie call:unknown), werden nicht von selbst wieder geöffnet. Ohne Richtlinie gilt die Obergrenze nur für automatische Wählvorgänge: Ein Kontakt, dem Sie nach Verbrauch der Versuche resolve mit action: "retry" geben, erhält einen weiteren Wählvorgang. maxDurationSecs (30-300) ist die Obergrenze für die Länge EINES Anrufs, nach der er automatisch beendet wird - die Standarddauer beträgt 120 Sekunden. Die optionale Richtlinie lorela_enterprise wird vor dem ersten Versuch über API oder MCP eingeschaltet; bestehende Aufgaben ändern sich nicht von selbst. Der zweite Versuch erfolgt frühestens 8 Minuten nach Beginn des ersten tatsächlichen Versuchs, innerhalb von 08:00-22:00 Europe/Prague. Der dritte geht in das nächste andere Fenster 08:00-09:00 oder 17:00-19:00, der vierte in das gegenteilige Fenster am folgenden Kalendertag. Es gelten stets auch callingWindow und seine Tage; nach dem Wiederholungshorizont ruft die Richtlinie nicht mehr an: Das optionale retryMaxAgeDays ist eine ganze Zahl von Tagen 1-30 (ohne Angabe 5) und gilt nur mit der Richtlinie. Der Horizont endet N × 24 Stunden nach dem ersten gezählten Versuch des Kontakts (feste 24-Stunden-Tage, sodass sich über eine Zeitumstellung hinweg die lokale Endzeit um eine Stunde verschiebt). Er lässt sich über PATCH auch nach Beginn der Versuche ändern (nicht bei einer Aufgabe im Status running oder completed, die sich nicht bearbeiten lässt): Eine Erhöhung bei einer angehaltenen Aufgabe bringt Kontakte, die nur wegen des Horizonts ausgefallen sind (reviewReason: "retry_age_expired"), zurück in den Status failed (warten auf den nächsten Versuch) mit neuem nextAttemptAt, sofern sie noch einen freien Versuch haben und der nächste Zeitplan-Slot in den neuen Horizont und vor expiresAt fällt; eine Senkung öffnet nichts. Nur ein PATCH, der den Horizont erhöht, öffnet Kontakte wieder, senden Sie daher retryMaxAgeDays und ein verlängertes expiresAt in einer Anfrage. Wiederholt werden nur no_answer, missed, busy, eine abgeschlossene Mailbox und ein angenommener Anruf, in dem der Angerufene nichts gesagt hat (alles ohne Kontakt mit einem Menschen). Kontakt mit einem Menschen, Ablehnung und Motorfehler beenden die automatische Wiederholung; ein unklares Ergebnis geht zur Prüfung. Der letzte erlaubte Versuch (maxAttempts), der mit einem solchen wiederholbaren Ergebnis endet (nicht angenommen, besetzt, Mailbox oder angenommener Anruf, in dem der Angerufene nichts gesagt hat), schließt den Kontakt als skipped mit reviewReason: "retry_policy_exhausted" ab (wie retry_age_expired nach Ablauf des Horizonts): Es gibt nichts zu prüfen oder zu wiederholen. Ein unklares Ergebnis des letzten Versuchs bleibt mit demselben Grund in review. Ohne Richtlinie ändert sich nichts: Der letzte nicht angenommene Versuch ist weiterhin review. Ein verifizierter Rückruf eines Menschen nach Verbrauch der Versuche setzt den Kontakt auf completed. DNC, Budget und Limits bleiben in Kraft: Die automatische Sperre nach 3 Fehlschlägen innerhalb von 24 Stunden kann auch den vierten Versuch verhindern. Bei PATCH ohne maxAttempts bleibt das bisherige Limit erhalten. Mit der Richtlinie liefert ein manuelles resolve mit action: "retry" den Fehler validation; erlaubt sind nur ihre automatisch geplanten Versuche. Eine Ausnahme ist die Wiederherstellung eines nachweislich nicht gewählten, abgelaufenen Claims vor dem ersten tatsächlichen Versuch: ohne aktiven Worker, Dispatch-Absicht, Provider-Call-ID, Reservierung, Preis oder Callback und nur mit nachgewiesenen Ablehnungen vor dem Wählen in der Historie. Die Wiederherstellung bewahrt Historie und Obergrenzen und stellt den Kontakt in einer angehaltenen Aufgabe zurück zu den wartenden; sie wählt selbst nicht an. Erinnerungen lassen sich so nicht wieder öffnen. Eine manuelle Wiederholung umgeht also weder die vier Versuche noch den Wiederholungshorizont noch das Ende nach Kontakt mit einem Menschen.

Globaler Durchsatz

Das Anwählen aller Aufgaben auf der GESAMTEN Plattform (nicht nur Ihres Kontos) läuft über einen einzigen Cron, der alle 2 Minuten läuft und pro Durchlauf höchstens 20 Elemente verarbeitet - ABER diese Obergrenze wird auf gleichzeitig laufende Aufgaben aufgeteilt, eine einzelne Aufgabe darf sie nicht ausschöpfen: Aus JEDER aktiven Aufgabe wird pro Durchlauf genau EIN Empfänger angewählt. Auch auf einer völlig leeren Plattform wählt eine Aufgabe daher nie mehr als einen Empfänger pro 2 Minuten an - hundert Empfänger sind also nicht in ~20 Minuten durch, sondern in etwa 200 Minuten (100 x 2 Minuten). Planen Sie das Anruffenster bei zeitkritischen Kampagnen entsprechend (z. B. appointment am Tag vor dem Termin).

Vorgehen für den Agenten

Ein typischer Ablauf, in dieser Reihenfolge:

  1. Der Agent der Aufgabe muss VERÖFFENTLICHT und die veröffentlichte Version GETESTET sein (POST /v1/agents/{id}/draft/publish, dann POST /v1/agents/{id}/simulate) - sonst liefert ein späteres start agent_not_ready.
  2. Optional POST /v1/tasks/csv-preview - prüft die CSV der Empfänger, bevor die Aufgabe angelegt wird.
  3. POST /v1/tasks - legt die Aufgabe im Status draft an. Es wird nichts angewählt.
  4. GET /v1/tasks/{id} - lesen Sie issues (Dry-Run-Validierung) und prüfen Sie, dass die Aufgabe startbereit ist.
  5. Bei Bedarf PATCH /v1/tasks/{id} - passen Sie die Regeln an, IMMER mit der revision aus dem letzten Lesen.
  6. POST /v1/tasks/{id}/start - startet das Anwählen. Jeder angenommene Anruf wird sofort abgerechnet.
  7. POST /v1/tasks/{id}/pause jederzeit während des Laufs, POST /v1/tasks/{id}/start setzt wieder fort.
  8. Nach einer Unterbrechung (Pause mitten im Anruf, abgelaufener Claim, ein Anruf mit noch unbekanntem Preis oder ein unsicherer Wählvorgang, zu dem der Anruf gefunden wurde) gleicht POST /v1/tasks/{id}/reconcile den Zustand mit den tatsächlichen Anrufen ab; eine solche Aufgabe mit Restarbeit endet in paused, auch wenn einige Kontakte in review warten, und lässt sich über start erneut starten. Eine laufende Aufgabe und jeden anderen Grund (variables_limit, Fehlschlag der Rechnungs- oder Kalenderprüfung, ein unsicherer Wählvorgang, zu dem der Anruf nicht gefunden wurde) ändert reconcile nicht; Kontakte zur Prüfung erledigen Sie über resolve.
  9. Einen Kontakt, der zur Prüfung geendet hat (items[].status: "review"), erledigen Sie mit POST /v1/tasks/{id}/items/{itemId}/resolve mit action: "retry" oder "skip". Bei einem gewöhnlichen Grund stellt retry den Kontakt zurück zu den wartenden und die Aufgabe nach paused; skip schließt ihn ab, und die Aufgabe wechselt nach paused, wenn noch Arbeit übrig ist, oder nach completed, wenn alle Kontakte erledigt oder übersprungen sind. Eine Aufgabe in paused setzen Sie dann mit POST /v1/tasks/{id}/start fort.
  10. Hat ein Kontakt reviewReason: "dial:destination_auto_blocked", ist die Nummer nach wiederholt nicht angenommenen Anrufen 30 Tage automatisch gesperrt, und ein bloßes retry hebt die Sperre nicht auf - der Kontakt wäre sofort wieder in review. Heben Sie zuerst die Sperre auf (POST /v1/dnc/{e164}/unblock, in MCP unblock_destination, die Nummer entnehmen Sie items[].phone), dann resolve mit action: "retry". Bei dial:on_dnc entfernen Sie die Nummer zuerst aus der Do-not-call-Liste (DELETE /v1/dnc/{e164}), andernfalls überspringen Sie den Kontakt. Bei der eigenen Nummer des Kontos, der Nummer eines anderen volai-Kontos, einer ungültigen Nummer, einer Nummer außerhalb Tschechiens und der Slowakei und einer Premiumnummer (dial:cannot_call_own_number, dial:cannot_call_volai_number, dial:invalid_number, dial:unsupported_country, dial:blocked_destination) hilft ein weiterer Versuch nicht: Verwenden Sie nur skip.
  11. Hat ein Kontakt reviewReason: "billing_unknown", ist der ursprüngliche Anruf möglicherweise schon gelaufen und hat nur noch keinen bekannten Preis. Rufen Sie zuerst reconcile auf und prüfen Sie den verknüpften Anruf. retry merkt sich, dass der Kontakt erneut versucht werden soll, erlaubt aber keinen neuen Anruf, bis sich der ursprüngliche Preis gesetzt hat; danach wechselt die Aufgabe in paused und erfordert ein neues start. skip verhindert einen weiteren Anruf; der ursprüngliche Anruf bleibt verknüpft, und seine Reservierung zählt weiter zum Budget, bis sich der Preis gesetzt hat. Ist noch Arbeit übrig, wechselt die Aufgabe nach skip direkt in paused und lässt sich starten; ohne weitere Arbeit wartet sie in needs_attention und endet nach Setzen des Preises in completed. Ein Anruf, der gar nicht gewählt wurde (der Motor hat ihn abgelehnt), wird nie abgerechnet und setzt sich sofort auf 0.
  12. Einen Kontakt, der inzwischen gekauft hat oder sich abgemeldet hat, überspringen Sie ohne Anruf über resolve mit action: "skip", reason: "customer_purchased" oder "unsubscribed", revision, einer festen operationId und einer evidenceRef, die auf den Beleg des Kaufs oder der Abmeldung verweist (nie auf Telefon oder E-Mail). Das geht bei einem pending-Kontakt in einer draft-Aufgabe und bei pending/failed in einer paused-Aufgabe ohne offenen Anruf; Versuche, Preise und die Do-not-call-Liste bleiben erhalten. GET /v1/tasks/{id} zeigt den Beleg dann in items[].resolution (reason, operationId, evidenceRef, resolvedAt); derselbe Body lässt sich gefahrlos wiederholen, ein anderer reason oder eine andere evidenceRef beim selben Kontakt ist 409 revision_conflict. Das Überspringen trägt die Nummer nicht in die Do-not-call-Liste ein: Soll ein Kontakt nie wieder angerufen werden, fügen Sie ihn über POST /v1/dnc hinzu.
  13. DELETE /v1/tasks/{id} am Ende, wenn die Aufgabe nie lief oder bereits durchgelaufen ist und Sie den Eintrag löschen möchten.

Fast jeder schreibende Aufruf (PATCH, start, pause, DELETE) nimmt die revision aus dem letzten Lesen der Aufgabe - dieselbe optimistische Nebenläufigkeit wie bei Entwürfen von Agenten. Bei einer Abweichung kommt revision_conflict: Laden Sie die Aufgabe erneut (GET) und wiederholen Sie den Aufruf mit der aktuellen revision. reconcile ist eine Ausnahme - die revision ist dort optional.

MCP

Dieselben Tools wie in REST (list_tasks, get_task, create_task, update_task, pause_task, resolve_task_item, reconcile_task, start_task) - bis auf einen Unterschied beim Start.

start_task bestätigt die Zahlen

MCP start_task nimmt zusätzlich confirmedRecipients und confirmedBudgetHal entgegen - sie müssen genau zur tatsächlichen Zahl der Empfänger und zum Budget der Aufgabe passen, sonst liefert es validation mit den tatsächlichen Werten und startet NICHTS. Ein fremder KI-Agent kann so aufgrund einer einzigen missverstandenen Anweisung nicht versehentlich eine kostenpflichtige Kampagne mit erfundenen Zahlen starten - REST POST .../start hat diesen Mechanismus nicht, weil dort der Kontoinhaber direkt mit seinem eigenen Schlüssel aufruft.

delete_task und die CSV-Vorschau gibt es in MCP nicht - das Löschen bleibt in REST und im Portal (eine unumkehrbare Aktion mit Abtippen des Namens), die CSV-Vorschau ist nur ein Formularschritt.

Fehler

  • task_not_found - Auf dem Konto gibt es keine Aufgabe mit dieser id.
  • task_not_editable - Die Aufgabe läuft oder ist abgeschlossen (running/completed) oder ist needs_attention ohne Möglichkeit zur Wiederaufnahme - die Regeln lassen sich jetzt nicht ändern. Denselben Code liefert auch POST .../items/{itemId}/resolve bei einer laufenden Aufgabe: Ein Kontakt in review erscheint schon, während die Aufgabe die übrigen Kontakte anruft und noch running ist - warten Sie, bis sie in needs_attention wechselt, oder halten Sie sie an (POST .../pause).
  • items_immutable - Die Empfängerliste lässt sich nicht ersetzen, nachdem mindestens ein Wählversuch stattgefunden hat oder ein Kontakt mit reason übersprungen wurde (Kauf oder Abmeldung).
  • budget_too_low - Das Budget deckt nicht einmal einen Versuch in maximaler Gesprächslänge ab - erhöhen Sie budgetHal oder senken Sie maxDurationSecs.
  • task_not_startable - Die Aufgabe ist nicht im Status draft/ready/paused oder hat keinen wartenden Empfänger.
  • task_needs_attention - Vor dem nächsten Start ist POST .../reconcile nötig - während der Laufzeit hat sich etwas geändert (Version des Agenten, Motor).
  • agent_not_ready - Der Entwurf des Agenten ist entweder nicht veröffentlicht oder die veröffentlichte Version ist nicht getestet - veröffentlichen Sie ihn (POST /v1/agents/{id}/draft/publish) und testen Sie vor dem Start die veröffentlichte Version (POST /v1/agents/{id}/simulate).
  • agent_version_changed - Die Konfiguration des Agenten hat sich WÄHREND der laufenden Aufgabe geändert - testen Sie und starten Sie über reconcile neu.
  • engine_required - Der Agent der Aufgabe läuft nicht auf dem volai-Motor (useForOutboundTasks: true) - ausgehende Kampagnen erfordern heute den Motor, nicht ElevenLabs.
  • engine_contract_unavailable - Der Motor meldet derzeit keine Unterstützung für Variablen und Obergrenzen ausgehender Aufgaben - versuchen Sie den Start später erneut.
  • window_closed - Außerhalb des eingestellten Anruffensters - warten Sie, bis es öffnet, oder passen Sie callingWindow an.
  • task_not_running - Eine Pause geht nur bei einer laufenden Aufgabe.
  • item_not_resolvable - Der Kontakt ist nicht im Status review - entscheiden (retry/skip) lässt sich nur über einen Kontakt, der auf Prüfung wartet, und nur bei einer Aufgabe, die nicht läuft. Eine Ausnahme ist das Überspringen mit reason (customer_purchased, unsubscribed): Dafür ist ein inaktiver pending-Kontakt in einer draft-Aufgabe oder pending/failed in einer paused-Aufgabe ohne offenen Anruf nötig.
  • task_not_deletable - Löschen lässt sich nur eine Aufgabe ohne Element in_progress im Status draft/ready/paused/completed/needs_attention.
  • revision_conflict - Die Aufgabe hat sich inzwischen geändert - laden Sie sie erneut (GET) und wiederholen Sie den Aufruf mit der aktuellen revision.

Die vollständige Fehlertabelle für jeden Endpunkt finden Sie im Abschnitt Aufgaben in der REST-API-Referenz.