Skip to main content

Workflow Webhook Actions

A Workflow Webhook Action is a governed step that sends a typed, minimized envelope to a configured target. It is separate from Event Hook subscriptions and Lead Delivery. The Workflow run owns authorization, approval, correlation, idempotency, and terminal outcome.

Destination rules

Use a destination approved by the Workflow/Workspace policy. The current shared URL validator accepts http or https and rejects malformed, localhost, private, and restricted DNS/IP resolutions; stronger HTTPS-only policy must be enforced by the owning configuration before publication. Resolve and pin DNS/IP behavior where the deployment contract requires it; do not follow an unsafe redirect.

{
"targetUrl": "https://automation.example.invalid/qanivo",
"mappingId": "<YOUR_MAPPING_ID>",
"eventVersion": "1.0"
}

The mapping should be allowlisted and typed by the owning Workflow contract. It must not copy an arbitrary customer record or provider payload. The current worker sends the supplied Workflow payload and does not add a Qanivo signing or idempotency header; do not document those guarantees as implemented. Authorization, run/version state, and any idempotency policy are owned by the Workflow dispatcher and must be verified before publication.

Delivery envelope

An action envelope may include a version, action key, run/correlation IDs, subject reference, event type, and bounded mapped fields according to the Workflow contract. It must not include API keys, signing secrets, access grants, raw provider diagnostics, or unapproved Workspace data. The current handler sends the command payload as JSON without adding a signing envelope.

type WorkflowWebhookEnvelope = {
contractVersion: '1.0';
actionKey: string;
correlationId: string;
idempotencyKey: string;
subject: { type: 'Lead' | 'Conversation'; id: string };
data: Record<string, string | number | boolean | null>;
};

export function handleWorkflowWebhook(body: WorkflowWebhookEnvelope) {
if (body.contractVersion !== '1.0' || !body.idempotencyKey) throw new Error('unsupported or unsafe envelope');
return enqueueOnce(body.idempotencyKey, body);
}

Transport delivery does not imply CRM acceptance, qualification, conversion, or Workflow completion. Record the target response as a normalized attempt and let the Workflow state machine decide the next permitted transition. Retries and terminal failures are covered in Retries, idempotency, and failures.