Connectors

Outbound Integrations (iPaaS)

Ductor as the source — the iPaaS webhook adapter that pushes domain events to Zapier/n8n/custom consumers, and the n8n community node.

Most of this section is about Ductor reaching out to providers, or providers reaching in through triggers. Outbound integrations are the opposite direction of a different kind: Ductor as the event source for an external automation platform (iPaaS) like Zapier, n8n, or a custom endpoint. When a unit of Work is routed or a worker goes down, Ductor pushes that event to whatever the customer wired up on the other side.

Here the usual framing inverts: Zapier and n8n are downstream consumers of the clearing layer, not competitors to it. Ductor clears the work — prices it, routes it, executes it, settles it — and emits the lifecycle events those platforms react to. They automate what happens after a decision; Ductor is what made the decision.

Not the same as inbound provider webhooks

This is distinct from the Ductor-owned provider webhook subscriptions in Triggers & Polling, which receive events from providers. Here Ductor is the sender: it signs and delivers its own domain events to external consumers.

The iPaaS webhook adapter

The webhook adapter (modules/integrations/webhook/adapter.go) bridges Ductor's internal event system to external webhook consumers. It subscribes to a fixed set of domain events and maps them to stable iPaaS event types:

iPaaS eventMapped from domain event
lead.routedRoutableAssigned
recipient.downRecipientStateChanged (only when the new state is down / unhealthy / failed)
budget.exhaustedRecipientCapacityChanged
quality.alertquality TierChanged and ProbationEnter
sla.breachSLA breach

A Registration (id, URL, optional secret, and an events allowlist — empty or * means all) receives a standardized WebhookPayload (id, event, timestamp, tenant_id, data). An event whose type isn't mapped is dropped before delivery, and recipient.down only fires on an actual failure transition.

Signing and retries

When a registration has a secret, each delivery is signed per the Standard Webhooks spec — SignPayload computes HMAC-SHA256 over {msg_id}.{timestamp}.{body}, encodes it as v1,<base64>, and sets the X-Webhook-ID, X-Webhook-Timestamp, and X-Webhook-Signature headers. Consumers verify with VerifySignature (constant-time compare). Delivery retries with exponential backoff (MaxRetries, RetryBaseDelay), treating any non-2xx response as a failure to retry.

Ductor domain event TransformEvent (map + filter) Per subscribed registration Sign (HMAC-SHA256, Standard Webhooks) POST with retries + backoff

The n8n community node

For n8n specifically, Ductor ships a community node package (modules/integrations/n8n/) with three TypeScript entry points:

  • Ductor.node.ts — the action node (Ductor as a step in an n8n workflow).
  • DuctorTrigger.node.ts — the trigger node (n8n workflows started by Ductor events).
  • Ductor.credentials.ts — the ductorApi credential used to authenticate.

Each operation's HTTP method and path come from an explicit route table (routes.ts) derived from the google.api.http annotations on the proto services, so every action maps to a REST endpoint that actually exists.

Action node

The action node lets an n8n builder manage Ductor routing objects and push leads without writing HTTP calls by hand. Four resources — Pool, Recipient, Rule, and Publisher — expose full CRUD. Lead is create-only, because a lead is routed, not stored as a collection.

ResourceOperationsRouting notes
Poolget, getAll, create, update, deleteupdate is a PATCH to /api/pools/{id}.
Recipientget, getAll, create, update, deletecreate and getAll are pool-scoped (/api/pools/{pool_id}/recipients); get / update / delete address a recipient by id (/api/recipients/{id}).
Ruleget, getAll, create, update, deleteSame shape as Recipient — pool-scoped create/list, id-scoped get/update/delete.
Publisherget, getAll, create, update, deleteupdate is a PUT to /api/publishers/{id}.
LeadcreateRoutes a lead through POST /api/route and returns the routing decision.

Lead is create-only now

Earlier versions of the node listed get/getAll/update/delete on Lead and targeted /api/v2/{resource}s paths that did not exist — every one of those operations returned 404. The node now offers only Create on Lead, which posts the routable to /api/route, and routes the remaining resources through the verified route table above.

Trigger node and signature verification

The trigger node registers a webhook subscription through the API and then receives the iPaaS events listed above at the n8n webhook URL.

When you set a Webhook Secret on the trigger, the node verifies every delivery before handing it to the workflow: it recomputes the HMAC-SHA256 over {id}.{timestamp}.{body}, compares it in constant time against the X-Webhook-Signature header (keyed by X-Webhook-ID and X-Webhook-Timestamp), and rejects a mismatch with 401. The v1,<base64> format and inputs mirror SignPayload in the webhook adapter exactly, so a forged or tampered payload never reaches your workflow.

Set a webhook secret

Configuring a secret is strongly recommended. When it is left empty the trigger passes deliveries through without verification — anyone who learns the webhook URL could post events to it. Set a secret and only deliveries signed by Ductor are accepted; everything else is rejected with 401.

Where to go next

  • SDKs — programmatic integration when a webhook or n8n node isn't the right fit.
  • Triggers & Polling — the inbound, Ductor-owned provider webhook side.