Nox-Lumen MfgNox-Lumen Mfg

Webhook events

Two directions

Rendering diagram…

Inbound (external → platform)

Remote systems POST to combo agent; signature verification routes into Event Triggers / sessions.

Envelope

POST /v1/webhook/{channel}
Content-Type: application/json
X-Combo-Signature: sha256=<hmac>
X-Combo-Timestamp: 1699999999
X-Combo-Event-Id: <unique-id>
 
{ ...channel-specific payload... }

Signature verification

HMAC-SHA256 over timestamp + "." + body using the secret from Integrations → Webhooks.

import hmac
import hashlib
 
def verify(body: bytes, timestamp: str, signature: str, secret: str) -> bool:
    payload = timestamp.encode() + b"." + body
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Supported inbound channels

ChannelPathPurpose
Feishu events/v1/webhook/larkMessages / approvals / calendar
WeCom events/v1/webhook/wecomMessages / directory
Gerrit hook/v1/webhook/gerritpatchset-created, change-merged, …
GitLab webhook/v1/webhook/gitlabPush / MR / pipeline
GitHub webhook/v1/webhook/githubPush / PR / issues
Gitee webhook/v1/webhook/giteeGitHub-compatible payload
Generic/v1/webhook/generic/{trigger_id}Custom triggers

Outbound (platform → customer)

Push internal events to customer endpoints.

Subscribe

POST /v1/webhook/subscriptions
Content-Type: application/json
 
{
  "url": "https://client.example.com/combo-callback",
  "events": ["session.finished", "tool.called"],
  "secret": "your-shared-secret"
}

Event catalog

EventWhenKey payload fields
session.createdSession spins upsession_id, tenant_id, user_id
session.finishedAgent completessession_id, cost, artifacts
session.archivedSession archivedsession_id
tool.calledTool invokedtool_name, session_id, args_hash
tool.errorTool failuretool_name, error, session_id
agent.stepVerbose step tracingaction, confidence, session_id
review.completedCode review wrapspr_url, report_url, issues_found
import.completedRequirement/bug ingest donesource, count, errors
cost.threshold_exceededBudget breachedtenant_id, period, amount

Payload example

{
  "event": "review.completed",
  "event_id": "evt_abc123",
  "timestamp": "2026-04-23T10:15:00Z",
  "tenant_id": "t_corp_a",
  "data": {
    "session_id": "sess_xyz",
    "pr_url": "https://gerrit.../c/12345",
    "report_url": "https://combo.../sessions/sess_xyz/report",
    "issues_found": {
      "critical": 2,
      "warning": 5,
      "info": 12
    },
    "cost": { "tokens": 8320, "duration_ms": 45000 }
  }
}

Retry policy

AttemptBackoff
1Immediate
230 s
32 min
410 min
51 h

Consumers must answer HTTP 2xx within ~2 s; failures roll into a dead-letter queue manageable in the console.

Event triggers bridge inbound → automation

YAML sketch:

trigger:
  source: gerrit
  match:
    event: patchset-created
    project_regex: "^platform/.*"
  action:
    agent_id: "code-review-agent"
    session_template: "code-review-session"
    inputs:
      pr_url: "{{ event.change.url }}"
      change_id: "{{ event.change.number }}"

FAQ

Q: Signature failures on inbound hooks? A: Rotate secrets deliberately; timestamps must be ±5 min; ensure proxies don’t mutate bodies.

Q: Consumers time out sporadically? A: Return 200 immediately, enqueue asynchronous processing—never block webhook threads.

Q: Replay historic events? A: Console → Integrations → Webhooks → Historical replay filtered by timeframe.

On this page