Zernio
Zernio
OverviewWebhooksPost webhooksInbox webhooksAutomation webhooksAccount webhooksAnalytics webhooksAds webhooksCall webhooksWhatsApp webhooksPhone number webhooksSMS registration webhooksBranded Calling webhooks
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources
Webhooks

Automation webhooks

Receive an event when a contact's tags or custom fields change, a contact enters or leaves a sequence, or a workflow run starts, ends or fails.


Automation events follow what your automations do to contacts: tag and custom-field writes, sequence enrollments and workflow runs. Use them to mirror a contact's state into your CRM or to react when a run finishes, without polling. Subscribe with POST /v1/webhooks/settings and the event names below (first event); delivery, retries and signatures are the same for every event (how webhooks behave).

Events

EventDescription
contact.tag_addedA tag was added to a contact.
contact.tag_removedA tag was removed from a contact.
contact.field_changedA contact custom field changed value.
sequence.enrolledA contact was enrolled in a sequence.
sequence.exitedA contact left a sequence; exitReason says why.
workflow.run.startedA workflow run started.
workflow.run.completedA workflow run ended.
workflow.run.failedA workflow run failed.

How it behaves

One event per real change

Contact events fire once per tag or field a write actually changed. Re-adding a tag the contact already has, or writing a field's current value, fires nothing. A bulk operation (renaming or deleting a tag, clearing a custom field) fires one event per contact it changed. Creating a contact with tags fires nothing; only changes to an existing contact do. source says who made the change: api (the API or the dashboard), workflow (an add_tag, remove_tag or set_field node) or automation (a comment-automation link click that tags the clicker).

Payloads carry ids, not accounts

These events carry no account block. contact.id, sequence.id and workflow.id are the keys; read the full record with Get contact, Get sequence or Get workflow. An endpoint scoped to accounts still receives sequence.* and workflow.run.* for the account that sent them.

Runs report how they ended

workflow.run.completed carries execution.status: "completed", or "exited" when it ended on purpose before its last node (a handoff, or a button that switched the contact to another workflow). workflow.run.failed carries error, naming the node that failed and why. conversation is null while a comment-triggered run has not sent the private reply that opens its conversation, and trigger.type is null when the workflow was deleted while the run was live.

Inbox access gates them

Contacts, sequences and workflows are inbox features, so these events need inbox access like the inbox events.


contact.tag_added

A tag was added to a contact, by the API, a workflow add_tag node or a comment-automation click.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/contact.tag_added


contact.tag_removed

A tag was removed from a contact.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/contact.tag_removed


contact.field_changed

A contact custom field changed value. field is the field slug; previousValue is null when the field was not set and value is null when it was removed.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/contact.field_changed


sequence.enrolled

A contact was enrolled in a sequence, through the API or a workflow enroll_sequence node.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/sequence.enrolled


sequence.exited

A contact left a sequence. exitReason is completed (the last step was sent), replied, manual (unenrolled through the API), failed (the step kept failing to send) or unsubscribed.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/sequence.exited


workflow.run.started

A workflow run started. trigger.type is the trigger node's type and trigger.text the inbound message that started the run, when there was one.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/workflow.run.started


workflow.run.completed

A workflow run ended, with execution.status completed or exited (why).


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/workflow.run.completed


workflow.run.failed

A workflow run failed. error says which node failed and why.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

Example Requests

POST/workflow.run.failed

Related

  • Webhooks: create an endpoint, retries, signatures.
  • Workflows: triggers, nodes and runs.
  • Inbox webhooks: message.sent carries the workflowId, executionId, sequenceId and automationId that sent each message.
  • Contacts and Sequences: the records these events describe.
Was this page helpful?

Inbox webhooks

Receive an event for every DM, delivery receipt, reaction, comment and review that reaches the inbox, and know which platforms send which.

Account webhooks

Receive an event when an account is connected to a profile or stops working, and know how fast each disconnect path reaches you.

On this page

EventsHow it behavesOne event per real changePayloads carry ids, not accountsRuns report how they endedInbox access gates themcontact.tag_addedcontact.tag_removedcontact.field_changedsequence.enrolledsequence.exitedworkflow.run.startedworkflow.run.completedworkflow.run.failedRelated
id*string

Event id, the dedupe key.

event*string

Value in

  • "contact.tag_added"
  • "contact.tag_removed"
timestamp*string
Formatdate-time
contact*
tag*string
source*string

Who wrote the tag: the API or dashboard, a workflow add_tag / remove_tag node, or a comment-automation link click.

Value in

  • "api"
  • "workflow"
  • "automation"
id*string

Event id, the dedupe key.

event*string

Value in

  • "contact.tag_added"
  • "contact.tag_removed"
timestamp*string
Formatdate-time
contact*
tag*string
source*string

Who wrote the tag: the API or dashboard, a workflow add_tag / remove_tag node, or a comment-automation link click.

Value in

  • "api"
  • "workflow"
  • "automation"
id*string

Event id, the dedupe key.

event*"contact.field_changed"

Value in

  • "contact.field_changed"
timestamp*string
Formatdate-time
contact*
field*string

Custom field slug.

previousValue*unknown

Value before the write; null when the field was not set.

value*unknown

Value after the write; null when the field was removed.

source*string

Who wrote the field: the API or dashboard, a workflow set_field node, or an automation.

Value in

  • "api"
  • "workflow"
  • "automation"
id*string

Event id, the dedupe key.

event*string

Value in

  • "sequence.enrolled"
  • "sequence.exited"
timestamp*string
Formatdate-time
sequence*
contact*
enrollment*
exitReason?string

sequence.exited only. completed: the last step was sent; replied: the contact replied and the sequence exits on reply; manual: unenrolled through the API; failed: the step kept failing to send; unsubscribed: the contact opted out.

Value in

  • "completed"
  • "replied"
  • "manual"
  • "failed"
  • "unsubscribed"
id*string

Event id, the dedupe key.

event*string

Value in

  • "sequence.enrolled"
  • "sequence.exited"
timestamp*string
Formatdate-time
sequence*
contact*
enrollment*
exitReason?string

sequence.exited only. completed: the last step was sent; replied: the contact replied and the sequence exits on reply; manual: unenrolled through the API; failed: the step kept failing to send; unsubscribed: the contact opted out.

Value in

  • "completed"
  • "replied"
  • "manual"
  • "failed"
  • "unsubscribed"
id*string

Event id, the dedupe key.

event*string

Value in

  • "workflow.run.started"
  • "workflow.run.completed"
  • "workflow.run.failed"
timestamp*string
Formatdate-time
workflow*
execution*
conversation*|

Null while a comment-triggered run has not sent the private reply that opens its conversation.

contact*|null
trigger*
error?string

workflow.run.failed only: which node failed and why.

id*string

Event id, the dedupe key.

event*string

Value in

  • "workflow.run.started"
  • "workflow.run.completed"
  • "workflow.run.failed"
timestamp*string
Formatdate-time
workflow*
execution*
conversation*|

Null while a comment-triggered run has not sent the private reply that opens its conversation.

contact*|null
trigger*
error?string

workflow.run.failed only: which node failed and why.

id*string

Event id, the dedupe key.

event*string

Value in

  • "workflow.run.started"
  • "workflow.run.completed"
  • "workflow.run.failed"
timestamp*string
Formatdate-time
workflow*
execution*
conversation*|

Null while a comment-triggered run has not sent the private reply that opens its conversation.

contact*|null
trigger*
error?string

workflow.run.failed only: which node failed and why.