Skip to Content
AdaptersWebhook Adapter

Webhook Adapter

Overview

Mechanism: POST task payload to a tenant-configured URL. The external agent processes the task and POSTs the result back to callbackUrl (async phone-home pattern).

Why a webhook adapter:

  • Enterprise tenants may have their own internal LLM inference infrastructure
  • Enables integration with any agent runtime that can make HTTP calls — Python agents, Java services, GPU inference servers, or any future LLM
  • Enables gradual migration: an enterprise can run their own agent while still being orchestrated by the control plane

This is the only async adapter — the control plane does not wait for the result inline; it receives it via callback when the external agent is done.


Configuration

interface WebhookAdapterConfig { webhookUrl: string; // target endpoint for task delivery authHeader: string; // e.g. 'Authorization' authValue: string; // e.g. 'Bearer <secret>' — stored encrypted timeoutMs: number; // how long to wait for the callback before timing out }

How Data Flows IN — POST to Webhook

POST https://agent-runner.internal.acmecorp.com/run Authorization: Bearer <agent-runner-secret> Content-Type: application/json { "taskId": "run_xyz789", "tenantId": "ten_abc123", "agentRole": "blog-writer", "prompt": "<full assembled task prompt>", "systemPrompt": "<system prompt with placeholders filled>", "skillsContext": "<skills Markdown concatenated — no --add-dir available>", "wakeReason": "new_task", "sessionId": null, "callbackUrl": "https://api.leadmetrics.io/api/agent-callback/run_xyz789", "taskToken": "<JWT signed with run-scoped secret, expires in 1h>", "timeoutMs": 180000 }

How Data Flows OUT — The External Agent POSTs Back

POST https://api.leadmetrics.io/api/agent-callback/run_xyz789 Authorization: Bearer <taskToken> Content-Type: application/json { "status": "completed", "output": "# Blog Post\n\n...", "sessionId": null, "usage": { "inputTokens": 4200, "outputTokens": 1800 }, "error": null }

Callback Authentication — taskToken

  • Short-lived JWT signed by the control plane at dispatch time
  • Scoped to a single runId — cannot be reused for other runs
  • Expires after the activity’s configured timeout
  • The control plane validates the token before accepting the callback payload

Async Flow Diagram

Worker External Agent Control Plane API │ │ │ │── POST /run ─────────────►│ │ │ (prompt + callbackUrl) │ │ │◄─ 202 Accepted ───────────│ │ │ │ (agent executes...) │ │ │── POST /agent-callback ──►│ │ │ (output + taskToken) │ │ │◄─ 200 OK ─────────────────│ │◄────────────────────────────────────── SSE event ─────│ │ (activity completed) │

What Happens While Waiting

  • DispatchResult.callbackUrl is returned immediately (no text field yet)
  • Activity status stays in_progress
  • The callback handler at /api/agent-callback/:runId:
    1. Validates the JWT
    2. Stores the output in MongoDB activity_streams
    3. Updates the activity_runs record
    4. Broadcasts the completion event via SSE to any connected UI clients

Streaming

The webhook adapter does not support live text streaming. The entire output arrives in one payload at callback time. The UI shows a spinner until the callback arrives; then displays the full result at once.


Cost Source

Usage object from callback payload → MODEL_PRICING[model] × tokens if model pricing is known, else $0.00.

© 2026 Leadmetrics — Internal use only