Apps

Machen Sie aus Agenten-Arbeit geplante, veröffentlichbare Automatisierungen, die nach dem Ende der Konversation weiterlaufen.

Was eine App ist

Eine App ist wiederkehrende Agenten-Arbeit: ein Zeitplan oder Trigger, eine Anweisung und veröffentlichte Ausgabe.

Eine Konversation mit einem Agenten endet; eine App läuft weiter. Eine App ist eine kleine Automatisierung, die in einem Thread lebt: ein Trigger (ein Cron-Zeitplan, ein externer Webhook, eine hochgeladene Datei oder ein manueller Run), eine Anweisung, die dem Agenten sagt, was bei jedem Run zu tun ist, und optional ein Satz statischer Dateien, die der Agent unter einer öffentlichen URL veröffentlicht.

Die definierende Eigenschaft: Der Agent baut die App selbst. Sie beschreiben im Chat, was Sie wollen — "sammle jeden Morgen die KI-News, die mich interessieren, und veröffentliche eine Digest-Seite" — und der Agent schreibt das Manifest, registriert die App und veröffentlicht die erste Version. Ab dann weckt die Plattform den Agenten nach Zeitplan, und die App aktualisiert sich selbst.

trigger fires (cron / webhook / upload / run now)
        |
        v
  thread wakes ── agent receives an app.run turn
        |            with the app's instruction
        v
  agent does the work
        ├─ fetches data, runs code in /workspace
        ├─ publishes updated assets ──> https://app.outgate.ai/...
        └─ reports the run (ok / failed + summary)

Jeder Run ist ein sichtbarer Turn im Thread — die komplette Historie dessen, was die App getan hat und warum ein Run fehlgeschlagen ist, liest sich wie jede andere Konversation.

Ihre erste App erstellen

Beschreiben Sie die Automatisierung im Chat; der Agent erledigt den Rest.

Sie füllen keine Formulare aus, um eine App zu erstellen. Öffnen Sie einen Thread und beschreiben Sie die Automatisierung:

"Bau mir eine App namens news-digest, die täglich um 07:00 UTC läuft,
 die Top-Storys aus diesen drei RSS-Feeds zieht und eine saubere
 HTML-Digest-Seite veröffentlicht. Benenne den Thread entsprechend."
1

Der Agent schreibt ein Manifest

Eine kleine TOML-Datei im Workspace deklariert die App: Name, Anweisung, Trigger und welche Dateien veröffentlicht werden.

2

Der Agent registriert sie

Die Registrierung validiert das Manifest, aktiviert den Zeitplan und liefert die öffentliche URL der App. Die Registrierung ist idempotent über den App-Namen — Iterationen am Manifest aktualisieren dieselbe App.

3

Der Agent veröffentlicht die erste Version

Assets werden hochgeladen, und die Seite ist unter ihrer app.outgate.ai-Adresse live, bevor der erste geplante Run überhaupt feuert.

Der Apps-Tab im Chat zeigt die Karte jeder App: Adresse, Zeitplan, letzte Runs und Bedienelemente zum Ausführen, Pausieren, Fortsetzen oder Löschen. Ein Klick auf einen Run springt an die genaue Stelle im Transkript, an der dieser Run stattfand.

Das App-Manifest

Eine TOML-Datei deklariert alles, was die Plattform zum Ausführen der App braucht.

version = 1
name = "news-digest"
description = "Morgendlicher Digest mit KI-News"

instruction = """
Hole die drei in kv hinterlegten Feeds, wähle die 10 relevantesten
Storys aus, formuliere die Zusammenfassungen neu und veröffentliche
die Digest-Seite.
"""

[[triggers]]
type = "cron"
cron = "0 7 * * *"        # 5-Felder-Cron, UTC

[[triggers]]
type = "webhook"
name = "refresh-now"       # externe Systeme können diesen auslösen
mode = "run"               # oder "ingest": Daten speichern, kein Agent-Run
docs = "POST the source id to refresh"
schema = '{"type":"object","required":["source"]}'

[[triggers]]
type = "upload"
name = "inbox"             # externe Systeme können hier Dateien senden
mode = "ingest"            # oder "run": Agent mit der Datei wecken
dir = "incoming"           # Vorgabe: uploads/<name>
max_bytes = 10000000       # optional, max. 50 MB

[assets]
base_dir = "apps/news"
main = "index.html"
files = ["index.html", "style.css", "digest.json"]

[kv]
feed_1 = "https://example.com/ai.rss"
feed_2 = "https://example.org/ml.rss"

[secrets]
keys = ["NEWSAPI_KEY"]

[email]
purpose = "Sende mir jeden Morgen die Digest-Zusammenfassung"
subject_prefix = "News: "
notify_on_failure = true
FeldRegeln
nameKleinbuchstaben-Slug, bis zu 63 Zeichen. Registrierung ist idempotent über den Namen.
instructionErforderlich, 1–4000 Zeichen. Der Agent erhält sie bei jedem Run wörtlich.
triggers1 bis 3 Trigger; beliebige Mischung aus Cron, Webhook und Upload. Cron ist 5-Feld-UTC mit mindestens 15 Minuten Intervall.
triggers[].modeWebhook und Upload: "run" (jeder Aufruf bzw. jede Datei startet einen Agent-Run) oder "ingest" (im Workspace ablegen, ohne Run). Webhooks und Uploads verwenden standardmäßig run.
triggers[].schemaNur Webhook. Optionales JSON Schema (als String, bis 8 KB), das der Endpunkt durchsetzt: Nicht passende Payloads werden mit 400 abgelehnt, bevor sie die App erreichen.
triggers[].docs / exampleAufrufer-orientierte Beschreibung und Beispiel-Payload, neben dem Trigger auf der App-Karte angezeigt. Uploads unterstützen docs, aber kein example (die Nutzdaten sind eine Datei).
triggers[].dirWo Daten im Workspace landen. Ingest-Webhooks: Vorgabe ingest/<name>; Uploads: Vorgabe uploads/<name>, in beiden Modi verwendet.
triggers[].max_bytesNur Upload. Optionales Größenlimit pro Datei, begrenzt auf das Plattform-Maximum von 50 MB.
assetsbase_dir (im Workspace), die main-Einstiegsdatei und 1–50 zu veröffentlichende Dateien.
kvOptionale Klartext-Konfiguration: bis zu 20 Keys, 1 KiB pro Wert. Nicht für Secrets.
secretsOptionale Liste von UPPER_SNAKE-Secret-Namen, die die App nutzt (bis zu 10). Werte werden separat bereitgestellt — nie im Manifest.
emailOptional. Deklariert, dass die App Ihnen E-Mails senden darf, mit angegebenem Zweck (erforderlich) und optionalen Fehler-Benachrichtigungen.

Das Manifest ist überprüfbar

Weil die App eine Datei im Workspace ist, können Sie den Agenten jederzeit bitten, sie zu zeigen, zu erklären oder zu ändern — das Manifest ist die einzige Quelle der Wahrheit dafür, was die App tun darf.

Trigger: Cron, Webhook, Upload, manuell

Vier Wege, wie ein Run startet — und immer nur ein Run zur Zeit.

Cron-Trigger feuern nach UTC-Zeitplan mit einem Mindestintervall von 15 Minuten. Die Plattform weckt den Thread, falls er schläft — Zeitpläne funktionieren also unabhängig davon, ob jemand den Chat offen hat.

Manuelle Runs kommen vom Run-Button auf der App-Karte im Chat oder über POST /api/v1/agents/threads/{threadId}/apps/{appId}/run in der API.

Webhook-Trigger lassen externe Systeme einen Run starten. Ein im Manifest deklarierter Webhook-Trigger erlaubt dem Agenten, einen Fire-only-Endpoint mit eigenem Token zu erzeugen:

curl -X POST https://api.outgate.ai/api/v1/hooks/apps/{appId} \
  -H "X-Outgate-Hook-Token: oghk_..." \
  -H "Content-Type: application/json" \
  -d '{ "source": "github", "ref": "refs/heads/main" }'
  • Das oghk_-Token wird beim Erzeugen einmal angezeigt und kann jederzeit widerrufen und neu erzeugt werden.
  • Die JSON-Payload (bis zu 32 KB) wird dem Agenten klar als nicht vertrauenswürdige externe Eingabe gerahmt übergeben — der Agent behandelt sie als Daten, nicht als Anweisungen.
  • Auslösungen werden mit 202 und einer runId angenommen; der Run selbst ist asynchron.
  • Rate-Limits: 5 Auslösungen pro Minute und Hook, plus eine stündliche Obergrenze je Plan (20 / 100 / 500 für free / plus / pro).
  • Deklariert der Trigger ein Schema, validiert der Endpoint jede Payload dagegen und lehnt Abweichungen mit 400 schema_mismatch ab — der Agent kann sich auf die Form dessen verlassen, was ankommt.

Ein Run zur Zeit

Egal welcher Trigger: Eine App läuft nie parallel zu sich selbst. Ein Trigger, der mitten in einem Run eintrifft, wird mit run_in_flight (409) abgelehnt — versuchen Sie es nach Abschluss des laufenden Runs erneut.

Ein Webhook kann auch im Ingest-Modus laufen (mode = "ingest" im Manifest). Eine Ingest-Auslösung startet den Agenten gar nicht: Die Plattform nimmt die Payload sofort mit 202 und einer ingestId an, weckt die Sandbox im Hintergrund, falls sie schläft, und hängt das Event als eine JSON-Zeile an eine stündliche Datendatei im Workspace an:

/workspace/<dir>/YYYY/MM/DD/HH.jsonl        (UTC, dir defaults to ingest/<name>)
{"ts":"2026-07-11T14:03:00Z","hook":"github-push","payload":{...}}
  • Der Agent liest die angesammelten Dateien bei seinem nächsten Run — Ingest macht aus einem Webhook einen dauerhaften Event-Feed, den die App in Batches verarbeitet.
  • Die Zustellung ist at-least-once: Eine seltene doppelte Zeile ist möglich — behandeln Sie Einträge daher als idempotent über Inhalt oder Zeitstempel.
  • Ingest-Hooks bekommen deutlich höhere Limits: 60 Auslösungen pro Minute, mit stündlichen Obergrenzen von 200 / 1.000 / 5.000 je Plan. Ein gesättigter Puffer liefert 429 ingest_backlog.
  • Ingest erfordert einen persistenten Workspace — die Registrierung lehnt Ingest-Trigger auf ephemeren Threads ab.
  • Ein erneutes Registrieren des Manifests schaltet einen Hook zwischen run und ingest um (und aktualisiert schema/docs); bestehende Tokens folgen dem aktuellen Manifest.

Upload-Trigger sind dieselbe Idee für Dateien statt JSON. Wo ein Webhook seine Nutzdaten im Request-Body trägt (32 KB JSON), nimmt ein Upload-Trigger eine echte Datei entgegen — bis zu 50 MB — über ein zweistufiges Verfahren, und derselbe Modus-Schalter entscheidet, ob der Agent geweckt wird oder die Datei nur abgelegt wird.

1

Endpunkt erzeugen

Der Agent deklariert einen Upload-Trigger und erzeugt dessen Endpunkt, genau wie bei einem Webhook. Das Token beginnt mit oup_ und wird nur einmal angezeigt.

2

Vorsignierten Upload anfordern

Der Publisher sendet ein POST an diesen Endpunkt und erhält einen kurzlebigen vorsignierten Upload — eine url plus eine Reihe von Formularfeldern — zusammen mit der uploadId und dem Größenlimit.

3

Datei senden

Der Publisher sendet die Datei per POST an diese url mit den zurückgegebenen Feldern. Es gibt keinen Completion-Callback: Das Eintreffen der Datei im Speicher ist das Signal.

4

Die App reagiert

Die Plattform bemerkt das Eintreffen, und der Modus des Triggers entscheidet, was als Nächstes passiert.

# step 1 — ask for a presigned upload
curl -X POST "https://api.outgate.ai/api/v1/uploads/apps/{appId}?api_key=oup_..." \
  -H "Content-Type: application/json" \
  -d '{ "filename": "report.pdf" }'
# → { "uploadId": "upl_...", "maxBytes": 52428800, "url": "...", "fields": { ... } }

# step 2 — send the file (submit every returned field, the file last)
curl -F key=<fields.key> -F policy=<fields.Policy> ... \
     -F file=@report.pdf "<url>"
  • mode = "run" (die Vorgabe) weckt den Agenten, sobald die Datei bereitliegt — mit dem lokalen Pfad im Blick und dem Dateiinhalt als nicht vertrauenswürdige Eingabe gekennzeichnet.
  • mode = "ingest" legt die Datei still ab und startet keinen Run — der Agent verarbeitet sie beim nächsten Run, nach demselben Batching-Muster wie Ingest-Webhooks.
  • In beiden Fällen landet die Datei unter /workspace/<dir>/YYYY/MM/DD/<uploadId>_<filename>, wobei dir standardmäßig uploads/<name> ist.
  • Die 50-MB-Grenze setzt die Speicherebene selbst durch: Ein zu großer Upload wird direkt abgelehnt, statt angenommen und verworfen zu werden. Ein Trigger kann ein niedrigeres maxBytes setzen.
  • Jeder Upload weckt die App genau einmal, auch wenn Benachrichtigungen über das Eintreffen mehrfach zugestellt werden können.
  • Der vorsignierte Upload ist einmalig nutzbar, verfällt innerhalb einer Stunde und gilt für genau eine Datei — ein geleakter Link lässt sich weder wiederholen noch umlenken.
  • Wie Ingest benötigen Uploads einen persistenten Workspace und werden auf ephemeren Threads abgelehnt.

Secrets

Im Manifest deklariert, verschlüsselt gespeichert, nur während eines Runs an den Agenten freigegeben.

Apps, die externe Dienste aufrufen, brauchen Zugangsdaten — und Zugangsdaten gehören weder in Manifeste noch in Chat-Nachrichten oder kv. Der Secrets-Flow hält sie aus allen dreien heraus.

1

Deklarieren

Das Manifest listet die Secret-Namen, die die App nutzt — nur Namen, etwa NEWSAPI_KEY.

2

Bereitstellen

Setzen Sie Werte im Secrets-Bereich der App-Karte im Chat oder per PUT über die API. Werte sind write-only: Einmal gesetzt, zeigt keine Oberfläche sie je wieder an.

3

Nutzen

Während eines Runs holt der Agent ein deklariertes Secret bei Bedarf ab. Das Abholen funktioniert nur, solange dieser Run tatsächlich ausgeführt wird — außerhalb eines Runs verweigert die Plattform es.

Secrets sind at rest verschlüsselt, erscheinen nie im Event-Stream oder in der Run-Historie und werden mit der App gelöscht. Die Auflistung zeigt nur Namen und ob ein Wert gesetzt ist.

E-Mail aus Apps

Apps können Ihnen mailen — nur Ihnen — mit deklariertem Zweck und Tagesobergrenzen.

Eine App mit einem [email]-Block im Manifest darf im Rahmen ihrer Runs E-Mails senden — einen Morgen-Digest, einen Wochenbericht, einen Alarm. Empfänger ist immer die Account-Adresse des Thread-Besitzers; Apps können keine beliebigen Adressen anschreiben.

  • Das Manifest muss den Zweck der E-Mails angeben; er wird auf der App-Karte angezeigt, sodass immer klar ist, warum eine App Ihnen mailt.
  • Tagesobergrenzen pro App je Plan: 10 (free), 50 (plus), 200 (pro).
  • Mit aktiviertem notify_on_failure erhalten Sie eine E-Mail pro fehlgeschlagenem Run — und einen eigenen Hinweis, wenn die App nach wiederholten Fehlschlägen deaktiviert wird.

Veröffentlichen und Hosting

Veröffentlichte Assets werden von einem isolierten CDN-Origin unter stabiler Adresse ausgeliefert.

Wenn der Agent veröffentlicht, werden die im Manifest gelisteten Dateien aus dem Workspace hochgeladen und unter einer stabilen Adresse auf app.outgate.ai ausgeliefert. Die URL identifiziert Ihre Organisation, Ihren Nutzer, den Thread und die App, und die main-Datei ist das Standarddokument des App-Verzeichnisses.

  • Bis zu 50 Dateien pro App, 10 MiB pro Datei, 50 MiB gesamt.
  • Veröffentlichte Seiten werden von einem separaten Origin mit strikter Sandbox-Policy ausgeliefert — App-Inhalte sind vollständig von Outgate selbst isoliert.
  • Assets werden mit offenem CORS ausgeliefert, andere Seiten und Tools können App-Ausgaben (etwa einen veröffentlichten JSON-Feed) also direkt abrufen.
  • Updates propagieren innerhalb von etwa einer Minute; erneutes Veröffentlichen derselben App ersetzt schlicht ihre Dateien.

Veröffentlichen ist optional. Eine App, die nur E-Mails sendet oder auf Webhooks reagiert, braucht gar keine Assets.

Runs, Fehlschläge und Historie

Jeder Run ist nachvollziehbar: im Transkript sichtbar, berichtet und zeitlich begrenzt.

Ein Run beginnt mit einem app.run-Turn im Thread, der den Trigger-Typ, eine Run-ID und die Anweisung trägt. Der Agent arbeitet wie in jedem anderen Turn und meldet dann das Ergebnis — Erfolg oder Fehlschlag, eine kurze Zusammenfassung und optional die veröffentlichte URL.

  • Runs haben ein hartes Budget von 15 Minuten; ein Run, der es überschreitet, wird als Timeout-Fehlschlag verbucht, und der Zeitplan läuft weiter.
  • Drei aufeinanderfolgende Fehlschläge versetzen die App in einen Fehlerzustand und pausieren den Zeitplan — eine kaputte App kann Runs also nicht endlos verbrennen. Beheben Sie die Ursache im Chat und setzen Sie sie fort.
  • Die App-Karte listet die letzten Runs; ein Klick scrollt das Transkript zu diesem Run — einen fehlerhaften Run zu debuggen heißt zu lesen, was der Agent tatsächlich getan hat.
  • Run-Ergebnisse werden zusätzlich als app.run- und app.run_result-Events ausgegeben, die Webhook-Abonnements empfangen können.

Apps verwalten

Pausieren, fortsetzen, ausführen und löschen — über die App-Karte oder die API.

Die App-Karte im Chat ist die Alltagsoberfläche: veröffentlichte Seite öffnen, Adresse kopieren, Run auslösen, Zeitplan pausieren oder fortsetzen, Secrets und Webhooks verwalten und die App löschen. Dieselben Operationen gibt es zur Automatisierung auf der API.

Apps leben in ihrem Thread. Das Löschen des Threads entfernt seine Apps; eine gesunde, aktive App hält ihren Thread am Leben, indem sie dessen Lebensdauer bei Registrierung, Updates und erfolgreichen Runs verlängert — eine gut laufende App läuft Ihnen nicht still unter den Händen ab.

AktionChatAPI
Apps auflistenApps-TabGET .../threads/{id}/apps
Inspektion + Run-HistorieApp-KarteGET .../apps/{appId}
Jetzt ausführenRun-ButtonPOST .../apps/{appId}/run
Pausieren / fortsetzenKarten-MenüPATCH .../apps/{appId} { "status": "paused" | "active" }
Secrets verwaltenSecrets-BereichPUT / DELETE .../apps/{appId}/secrets/{name}
UnpublishUnpublish-ButtonPOST .../apps/{appId}/unpublish
LöschenKarten-MenüDELETE .../apps/{appId}

Unpublish nimmt die veröffentlichte Seite offline, ohne die App anzutasten: Die Assets werden von app.outgate.ai gelöscht (gecachte Kopien können bis zu fünf Minuten bestehen bleiben, während der CDN-Cache abläuft), die Karte wechselt auf unveröffentlicht, und das nächste Publish bringt die Seite zurück. Das Löschen einer App — oder ihres Threads — entfernt die veröffentlichten Assets auf dieselbe Weise.

Was der Agent tun kann

Die App-Tools, die Agenten zur Verfügung stehen — nützlich beim Schreiben von Prompts.

Agenten verwalten Apps über eingebaute Tools. Sie rufen diese nie selbst auf, aber sie zu kennen macht Prompts präzise — "registriere sie, veröffentliche sie und erzeuge einen Webhook namens deploy-done" bildet eins zu eins darauf ab, was der Agent tatsächlich tun kann.

ToolZweck
og_app_registerDas Manifest validieren und die App erstellen oder aktualisieren.
og_app_listDie Apps des Threads mit Status und nächster Run-Zeit auflisten.
og_app_publishDie Asset-Dateien des Manifests an die Adresse der App hochladen.
og_app_reportDas Ergebnis eines Runs melden (am Ende jedes Runs erforderlich).
og_app_unregisterDie App entfernen und ihren Zeitplan aufheben.
og_app_secret_set / list / deleteSecret-Werte verwalten (write-only; Lesen ist an Runs gebunden).
og_app_emailEine E-Mail an den Thread-Besitzer senden, innerhalb der Tagesobergrenze.
og_app_webhook_create / list / revokeFire-only-Webhook-Endpoints erzeugen und verwalten.
og_app_upload_create / list / revokeDatei-Upload-Endpunkte erzeugen und verwalten (vorsigniert, bis 50 MB).

Limits

Die Leitplanken, die Apps vorhersehbar halten.

LimitWert
Apps pro Thread10
Trigger pro App3 (cron und webhook zusammen)
Cron-Mindestintervall15 Minuten (UTC-Zeitplan)
Run-Timeout15 Minuten
Aufeinanderfolgende Fehlschläge bis zur Auto-Pause3
Veröffentlichte Assets50 Dateien, 10 MiB pro Datei, 50 MiB gesamt
kv-Einträge20 Keys, 1 KiB pro Wert
Deklarierte Secrets10 pro App
Webhook-Payload32 KB JSON
Webhook-Auslösungen (Run-Modus)5 pro Minute und Hook; 20 / 100 / 500 pro Stunde je Plan
Webhook-Auslösungen (Ingest-Modus)60 pro Minute und Hook; 200 / 1.000 / 5.000 pro Stunde je Plan
Payload-Schema / docs pro Trigger8 KB JSON Schema; docs mit 2.000 Zeichen
E-Mails pro App und Tag10 (free), 50 (plus), 200 (pro)