Agents API

Cloud-Agenten per REST erstellen, steuern und beobachten — dieselbe API, die den Outgate-Chat antreibt.

Überblick

Alles, was der Chat kann, kann auch Ihr Code: eine REST-Oberfläche für die gesamte Agenten-Plattform.

Die Agents API stellt die Agenten-Plattform auf https://api.outgate.ai unter /api/v1/agents bereit. Sie ist keine Seitentür mit einem Teil der Features — der Outgate-Chat ist auf genau diesen Endpoints gebaut, alles aus der UI lässt sich also automatisieren.

POST /api/v1/agents/threads          create an agent
POST .../threads/{id}/events         send a message
GET  .../threads/{id}/events         read what happened
GET  <region events url>?wait=25     follow live output (long-poll)
POST /api/v1/agents/webhooks         get notified without polling

Die typische Integration ist klein: Thread erstellen, Eingabe senden, Events bis zum Abschluss des Turns verfolgen, Ergebnis lesen. Webhooks ersetzen Polling bei Fire-and-forget-Automatisierung.

Authentifizierung und Scopes

API-Keys mit expliziten Read-/Write-Scopes; ein konsistenter Error-Envelope.

Erstellen Sie einen API-Key in der Console. Keys tragen das Präfix gw_ und werden nur einmal bei der Erstellung angezeigt. Senden Sie den Key als Bearer-Token bei jedem Request mit.

curl https://api.outgate.ai/api/v1/agents/regions \
  -H "Authorization: Bearer gw_your_key"
ScopeErlaubt
outgate.agents.readThreads auflisten und inspizieren, Event-Historie lesen, Modelle, Configs und Regionen auflisten.
outgate.agents.writeThreads erstellen, steuern und löschen; Workspaces, Webhooks und Provider-Anmeldung verwalten.

Jeder Fehler auf jedem Agents-Endpoint nutzt denselben Envelope: ein error-Objekt mit einem stabilen, maschinenlesbaren Code und einer menschenlesbaren Message. Matchen Sie auf den Code, nicht auf die Message.

{
  "error": {
    "code": "thread_not_found",
    "message": "No thread with this id exists in your organization."
  }
}

Requests sind pro Organisation gemäß Ihrem Plan rate-limitiert; Antworten enthalten X-RateLimit-Header, damit Clients sich selbst takten können.

Einen Thread erstellen

Die Erstellung ist asynchron: Sie erhalten sofort einen Thread, die Sandbox ist Sekunden später live.

Ermitteln Sie zuerst, was Ihre Organisation ausführen kann: GET /api/v1/agents/configs listet die verfügbaren Agent-Konfigurationen (jede legt Agent-Typ, Region und Sandbox-Ressourcen fest), GET /api/v1/agents/regions listet die Regionen. Dann erstellen Sie den Thread.

curl -X POST https://api.outgate.ai/api/v1/agents/threads \
  -H "Authorization: Bearer gw_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "agentConfigId": "acfg-example",
    "metadata": { "ticket": "OPS-1423" }
  }'
{
  "threadId": "6f9d2c1e-...",
  "status": "starting",
  "tool": "claude",
  "regionId": "de-west-1",
  "ephemeral": true,
  "expiresAt": null,
  "events": {
    "url": "https://<region>/v1/agents/threads/6f9d2c1e-.../events",
    "token": "<consumer token>",
    "expiresAt": "2026-07-11T10:00:00Z"
  }
}

Die Antwort kommt sofort mit Status starting; das Sandbox-Provisioning läuft im Hintergrund weiter. Pollen Sie GET /api/v1/agents/threads/{threadId}, bis der Status live ist, oder beobachten Sie die Events-URL — ein Lifecycle-Event meldet spawned oder spawn_failed, Fehlschläge sind also explizit statt still.

FeldBedeutung
agentConfigIdErforderlich. Welche Agent-Konfiguration ausgeführt wird (aus GET /configs).
regionIdOptional. Standard ist die Region der Konfiguration.
workspaceIdOptional. Hängt ein persistentes Workspace-Volume an. Weglassen für einen ephemeren Thread mit reinem Scratch-Speicher.
ttlSecondsOptionale begrenzte Thread-Lebensdauer in Sekunden: 0 (läuft nie ab), 60, 300, 3600, 28800, 86400 oder 2592000. Weglassen, um die Region-Standardeinstellung zu verwenden — Threads auf von Outgate verwalteten Regionen sind standardmäßig langlebig, daher kommt expiresAt als null zurück.
idleTimeoutSecondsOptional. Wie lange die Sandbox ohne Aktivität aktiv bleibt, bevor sie schläft (60–86400).
permissionModeask (Agent bittet um Freigabe für Tools) oder skip (autonom).
effortReasoning-Effort: low, medium, high, xhigh oder max.
metadataBis zu 4 KB eigenes JSON, am Thread gespeichert und bei Reads zurückgegeben.

Threads lassen sich nach der Erstellung ändern: PATCH /api/v1/agents/threads/{threadId} ändert Modell, Effort oder Permission-Modus (die Sandbox startet an Ort und Stelle neu, die Konversation bleibt erhalten), POST .../resume weckt einen Idle-Thread explizit, und DELETE baut ihn ab.

Eingaben senden

Posten Sie Events an den Thread: Text, Interrupts, Permission-Antworten, Titel.

curl -X POST https://api.outgate.ai/api/v1/agents/threads/{threadId}/events \
  -H "Authorization: Bearer gw_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "input.text",
    "payload": { "text": "Run the test suite and summarize the failures." },
    "correlation_id": "my-req-42"
  }'
KindPayloadWirkung
input.text{ "text": "..." }Eine Nutzernachricht. Weckt die Sandbox, falls sie idle ist.
interrupt{}Stoppt den aktuellen Turn des Agenten.
permission_response{ "granted": true }Beantwortet einen ausstehenden permission_request.
thread.title{ "title": "..." }Benennt den Thread um.

Die Antwort enthält die Sequenznummer und den Zeitstempel des angehängten Events. Wenn Sie eine correlation_id (bis zu 128 Zeichen) übergeben, wird sie auf dem kanonischen Event zurückgespiegelt, damit optimistische UIs ihre lokale Kopie mit dem Stream abgleichen können.

Nur diese Consumer-Kinds werden akzeptiert; servergenerierte Kinds werden mit einem forbidden_kind-Fehler abgelehnt — ein fehlerhafter Client kann also keine Agenten-Ausgabe fälschen.

Events lesen

Die vollständige Thread-Historie ist ein geordnetes, filterbares Event-Log.

Alles, was auf einem Thread passiert — Nutzereingaben, Agenten-Text, Tool-Aufrufe, Lifecycle-Übergänge — ist ein Event mit monoton steigender Sequenznummer. GET /api/v1/agents/threads/{threadId}/events liest das Log.

Query-ParameterBedeutung
since / untilSequenznummern-Grenzen für die Seite.
limitMaximale Anzahl zurückgegebener Events; nextCursor setzt die Seite fort.
kindsKommagetrennter Filter, z. B. kinds=text_delta,turn_complete.
reverse=trueNeueste zuerst — mit limit kombinieren, um die letzte Aktivität zu holen.
from / toZeitstempel-Grenzen als ISO 8601.

Die neuesten Events abrufen

Das Log wird standardmäßig älteste zuerst zurückgegeben. Um zu zeigen, "was gerade passiert ist", nutzen Sie reverse=true mit einem limit und sortieren clientseitig um — pagen Sie nicht bei jedem Refresh ab Sequenz null.

{
  "events": [
    { "seq": 41, "ts": "2026-07-11T09:14:03Z", "kind": "input.text",
      "payload": { "text": "Run the test suite..." } },
    { "seq": 42, "ts": "2026-07-11T09:14:09Z", "kind": "text_delta",
      "payload": { "text": "Running pytest..." } },
    { "seq": 57, "ts": "2026-07-11T09:15:40Z", "kind": "turn_complete",
      "payload": {} }
  ],
  "nextCursor": null,
  "thread": { "id": "6f9d2c1e-...", "maxSeq": 57 }
}

Live-Ausgabe verfolgen

Long-Poll auf den regionsdirekten Events-Endpoint für Streaming mit niedriger Latenz.

Für Live-Ausgabe nutzen Sie die regionsdirekte Events-URL, die bei der Thread-Erstellung zurückgegeben wurde. Sie liefert dasselbe Event-Log, unterstützt aber einen wait-Parameter: Der Request blockiert, bis neue Events eintreffen oder das Fenster abläuft — Zustellung unter einer Sekunde, ohne Websocket.

# events.url und events.token stammen aus der Thread-Erstellung
curl "$EVENTS_URL?since=$LAST_SEQ&wait=25" \
  -H "Authorization: Bearer $EVENTS_TOKEN"
  • wait akzeptiert bis zu 25 Sekunden. Ein leeres events-Array nach Ablauf des Fensters ist normal — stellen Sie den Request einfach mit demselben Cursor erneut.
  • Das Events-Token ist auf diesen einen Thread gescoped und läuft ab; POST /api/v1/agents/threads/{threadId}/events-token rotiert es (das alte Token wird widerrufen).
  • Bei einem 401 vom Region-Endpoint rotieren Sie das Token und versuchen es erneut — das ist der normale Recovery-Pfad, kein Fehlerzustand.

Die Schleife: Request mit der zuletzt gesehenen Sequenznummer und wait=25 stellen, das Ergebnis anwenden, Cursor aktualisieren, wiederholen. Zusammen mit der asynchronen Erstellung ergibt das einen vollständig event-getriebenen Client mit zwei beweglichen Teilen.

Webhooks

Einmal abonnieren, signierte Benachrichtigungen für die Momente erhalten, die zählen.

Wenn Sie keinen Long-Poll offen halten wollen, abonnieren Sie Ihren Endpoint auf grobkörnige Thread-Events. Outgate postet für jedes Vorkommen über alle Threads Ihrer Organisation hinweg eine signierte Zustellung.

curl -X POST https://api.outgate.ai/api/v1/agents/webhooks \
  -H "Authorization: Bearer gw_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://ops.example.com/hooks/outgate",
    "events": ["lifecycle", "error", "turn_complete", "permission_request"]
  }'

Die Antwort enthält ein whsec_-Signing-Secret — einmal angezeigt, später nie wieder abrufbar. Abonnierbare Kinds sind lifecycle, error, turn_complete, permission_request sowie die App-Run-Kinds app.run und app.run_result. Eine Organisation kann bis zu 10 Abonnements halten.

Jede Zustellung trägt den Event-Kind in X-Outgate-Event und eine HMAC-SHA256-Signatur des rohen Bodys in X-Outgate-Signature. Verifizieren Sie, bevor Sie vertrauen:

import crypto from 'node:crypto';

function verify(rawBody, signatureHeader, secret) {
  const expected = crypto.createHmac('sha256', secret)
    .update(rawBody).digest('hex');
  const got = signatureHeader.replace(/^sha256=/, '');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(got));
}
  • Zustellungen laufen nach 5 Sekunden in den Timeout und werden bei Netzwerkfehlern oder 5xx einmal wiederholt — halten Sie Ihren Handler schnell und idempotent.
  • Ein fehlschlagender Endpoint blockiert nie den Agenten oder andere Abonnements.
  • Beantworten Sie permission_request-Zustellungen, indem Sie ein permission_response-Event an den Thread posten — das schließt den Kreis für vollautonome Freigabe-Policies.

Modelle und Provider-Anmeldung

Den Live-Modellkatalog inspizieren und die Provider-Anmeldung programmatisch abschließen.

GET /api/v1/agents/threads/{threadId}/models liefert den Modellkatalog so, wie die Sandbox ihn tatsächlich sieht — die Modelle, die Ihr Provider-Account anbietet, frisch vom Provider aktualisiert. Kombinieren Sie ihn mit PATCH auf dem Thread, um das Modell zu wechseln.

Die Provider-Anmeldung — der Connect-Claude-/Connect-ChatGPT-Flow aus dem Chat — ist ebenfalls verfügbar: POST .../login startet den Flow und liefert die URL, die der Nutzer bestätigen muss; POST .../login/code übermittelt den resultierenden Code; GET .../auth meldet, ob der Thread angemeldet ist; POST .../logout löscht die Session. Damit betten Sie Agenten-Onboarding in Ihr eigenes Produkt ein, ohne Nutzer zum Outgate-Chat zu schicken.

Dateien und Git

Den Workspace inspizieren und Git-Operationen gegen echte Repositories ausführen.

GET /api/v1/agents/threads/{threadId}/files listet Workspace-Inhalte (übergeben Sie path, um in Verzeichnisse abzusteigen). Es ist dieselbe Ansicht wie der Files-Tab im Chat.

POST /api/v1/agents/threads/{threadId}/git führt einen Git-Befehl in der Sandbox aus:

{
  "cmd": "clone",
  "args": ["https://github.com/acme/service.git", "."],
  "auth": { "token": "<token for private repos>" }
}

Die Antwort enthält stdout, stderr und den Exit-Code. So übergebene Tokens werden nur für die eine Operation genutzt und nicht in der Sandbox gespeichert. Für GitHub-Repositories, die eine Installation der Outgate GitHub App abdeckt, erhalten Agenten automatisch kurzlebige, gescopte Tokens — es muss gar kein Token übergeben werden.

Workspaces

Die persistenten Volumes erstellen und verwalten, die Threads unter /workspace mounten.

Workspaces sind benannte persistente Volumes, die in einer Region liegen. Erstellen Sie eines und übergeben Sie seine ID als workspaceId beim Erstellen von Threads — jeder Thread, der es mountet, sieht dieselben /workspace-Inhalte. Lassen Sie workspaceId weg, erhalten Sie stattdessen einen ephemeren Thread.

# Workspace-Routen werden pro Region adressiert
curl -X POST https://api.outgate.ai/api/v1/agents/workspaces \
  -H "Authorization: Bearer gw_your_key" \
  -H "X-Region-Id: de-west-1" \
  -H "Content-Type: application/json" \
  -d '{ "workspaceId": "ci-nightly" }'
  • Workspace-IDs sind Kleinbuchstaben-Slugs (Buchstaben, Ziffern, Bindestriche, Unterstriche; bis zu 64 Zeichen).
  • GET /api/v1/agents/workspaces/{workspaceId} meldet die aktuelle Größe in Bytes.
  • DELETE entfernt das Volume samt Inhalt — Threads, die es gerade mounten, sollten zuerst beendet werden.
  • Alle Workspace-Routen erfordern den X-Region-Id-Header, weil Volumes physische Ressourcen in einer Region sind.

Routen-Referenz

Die komplette v1-Oberfläche auf einen Blick.

MethodePfadScope
POST/api/v1/agents/threadswrite
GET/api/v1/agents/threadsread
GET/api/v1/agents/threads/{id}read
PATCH/api/v1/agents/threads/{id}write
DELETE/api/v1/agents/threads/{id}write
POST/api/v1/agents/threads/{id}/resumewrite
POST/api/v1/agents/threads/{id}/eventswrite
GET/api/v1/agents/threads/{id}/eventsread
POST/api/v1/agents/threads/{id}/events-tokenwrite
GET/api/v1/agents/threads/{id}/modelsread
POST/api/v1/agents/threads/{id}/loginwrite
POST/api/v1/agents/threads/{id}/login/codewrite
POST/api/v1/agents/threads/{id}/logoutwrite
GET/api/v1/agents/threads/{id}/authread
GET/api/v1/agents/threads/{id}/filesread
POST/api/v1/agents/threads/{id}/gitwrite
GET/api/v1/agents/threads/{id}/appsread
GET/api/v1/agents/threads/{id}/apps/{appId}read
POST/api/v1/agents/threads/{id}/apps/{appId}/runwrite
POST/api/v1/agents/threads/{id}/apps/{appId}/unpublishwrite
PATCH/api/v1/agents/threads/{id}/apps/{appId}write
DELETE/api/v1/agents/threads/{id}/apps/{appId}write
GET/api/v1/agents/threads/{id}/apps/{appId}/secretsread
PUT/api/v1/agents/threads/{id}/apps/{appId}/secrets/{name}write
DELETE/api/v1/agents/threads/{id}/apps/{appId}/secrets/{name}write
GET/api/v1/agents/threads/{id}/apps/{appId}/webhooksread
POST/api/v1/agents/workspaceswrite
GET/api/v1/agents/workspaces/{id}read
DELETE/api/v1/agents/workspaces/{id}write
GET/api/v1/agents/configsread
GET/api/v1/agents/regionsread
POST/api/v1/agents/webhookswrite
GET/api/v1/agents/webhooksread
DELETE/api/v1/agents/webhooks/{id}write
POST/api/v1/hooks/apps/{appId}Hook-Token

Fehler und Status

Stabile maschinenlesbare Codes für jeden Fehlerfall.

HTTPCodeBedeutung
400invalid_requestFehlerhafter Body, fehlendes Feld oder ungültiger Enum-Wert; details listet die Felder auf.
400forbidden_kindDer Event-Kind ist servergeneriert und kann von Consumern nicht gepostet werden.
401unauthorizedFehlende, ungültige oder widerrufene Zugangsdaten.
403forbiddenDer Key ist gültig, hat aber nicht den erforderlichen Scope.
404thread_not_foundKein solcher Thread in Ihrer Organisation (organisationsübergreifender Zugriff liest sich ebenfalls als 404).
409thread_lostDie Sandbox existiert nicht mehr; erstellen Sie einen neuen Thread.
409run_in_flightAuf diesem Thread läuft bereits ein App-Run.
502region_unavailableDie Region hat den Befehl nicht angenommen; mit Backoff erneut versuchen.
504region_timeoutDie Region hat nicht innerhalb des Befehlsfensters geantwortet; mit Backoff erneut versuchen.
Thread-StatusBedeutung
startingSandbox-Provisioning läuft; Eingaben werden noch nicht angenommen.
liveDer Agent läuft und nimmt Eingaben an.
idleDie Sandbox schläft; der Zustand ist intakt, die nächste Nachricht weckt sie.
endedDer Thread ist abgelaufen oder wurde gelöscht; seine Sandbox ist weg.