Automations
Triggers

Triggers

A trigger is the event that causes an automation rule to fire. Each trigger is scoped to a specific entity via its trigger_id — for example, a particular form, a particular tag, or a particular pipeline stage.

Gordon CRM supports eight trigger types.


Entity-Based Triggers

These triggers fire when a contact interacts with a specific entity in the CRM.

Form Submitted

trigger_typeform_submission
trigger_idThe UUID of the specific form
Fires whenA contact submits a headless form (see Context-Aware Double Opt-In below)
Called from/api/forms/[id] (new contacts) or /api/forms/verify (existing contacts)

Context-Aware Double Opt-In

Gordon CRM uses a split processing model based on whether the submitter already exists in the workspace:

  • New contact — The contact is created immediately, the submission is logged, and the automation fires right away in the form submission endpoint (/api/forms/[id]). No email verification is required because a brand-new email address has no prior data to protect.

  • Existing contact — The submission is staged in a pending_form_submissions table with a secure token, and a verification email is sent. The automation only fires after the contact clicks the verification link (/api/forms/verify), which prevents impersonation attacks that could overwrite existing contact data.

Example use case: When someone submits the "Request a Demo" form → add the "Demo Request" tag.


Event Registration

trigger_typeevent_registration
trigger_idThe UUID of the CRM event
Fires whenA contact registers for an event (manual RSVP or Eventbrite ticket purchase)
Called from/api/rsvp/[id] (manual events) and /api/webhooks/eventbrite (Eventbrite events)

This trigger fires from both event sources:

  • Manual events — When a contact submits the public RSVP form, the automation fires after the registration record is created or re-activated.

  • Eventbrite events — When the Eventbrite webhook handler (order.placed or attendee.updated) processes a registration, it also calls processAutomationTrigger with the CRM event ID. The handler deduplicates per-contact — if a single order contains multiple tickets for the same contact, the automation fires only once.

Note: For Eventbrite events, the trigger_id is the CRM event UUID (not the Eventbrite event ID). This means the same automation rule works regardless of whether the registration came through the native RSVP form or an Eventbrite webhook.

Example use case: When someone registers for "Spring Gala 2026" → enroll in the "Event Reminder" campaign.


Product Purchase

trigger_typeproduct_purchase
trigger_idThe UUID of the purchased product
Fires whenA Stripe checkout.session.completed webhook is received for a linked product
Called from/api/webhooks/stripe — after the payment is verified and the contact is matched

Example use case: When someone purchases "Annual Membership" → add the "Member" tag.


Tag-Based Triggers

These triggers fire when a tag is added to or removed from a contact. They can be caused by manual user action or by a preceding automation action.

Tag Applied

trigger_typetag_applied
trigger_idThe UUID of the tag that was applied
Fires whenThe specified tag is added to a contact
Called fromThe processAutomationTrigger engine itself (cascading), or manual tag operations

Example use case: When "VIP" tag is applied → enroll in the "VIP Welcome Sequence" campaign.


Tag Removed

trigger_typetag_removed
trigger_idThe UUID of the tag that was removed
Fires whenThe specified tag is removed from a contact
Called fromThe processAutomationTrigger engine itself (cascading), or manual tag operations

Example use case: When "Active Member" tag is removed → remove from the "Members-Only Newsletter" campaign.


Deal Triggers

These triggers fire when a deal progresses through a sales pipeline. Both use a cascading pipeline → stage/status picker in the UI.

Deal Stage Changed

trigger_typedeal_stage_changed
trigger_idThe UUID of the pipeline stage
Fires whenA deal is moved to the specified stage (via drag-and-drop on the Kanban board or manual edit)
Called fromDeal update server actions

The UI uses a cascading picker: first select a pipeline, then select a stage within that pipeline.

Example use case: When a deal moves to the "Proposal Sent" stage → add the "Proposal Sent" tag.


Deal Status Changed

trigger_typedeal_status_changed
trigger_idComposite: {pipeline_id}_{status} (e.g. abc123_won)
Fires whenA deal's terminal status is changed to Won or Lost
Called fromDeal update server actions

The trigger_id for this trigger type is a composite key that combines the pipeline UUID and the status (won or lost) with an underscore separator. This allows different automations for different pipelines.

Example use case: When a deal is marked as "Won" in the "Enterprise Sales" pipeline → add the "Customer" tag.


Lifecycle Triggers

Contact Birthday

trigger_typecontact_birthday
trigger_id__birthday__ (static sentinel value)
Fires whenThe daily birthday cron sweeper finds contacts whose birthday matches today
Called from/api/cron/birthday-sweeper

Unlike other triggers, this one does not require a specific entity to be selected in the UI — it fires globally for all contacts in the workspace whose birth_month and birth_day fields match the current date.

Example use case: On a contact's birthday → enroll in the "Birthday Greeting" campaign.


Trigger Resolution

When a trigger fires, the engine resolves human-readable names for display purposes:

Trigger TypeResolution Strategy
form_submissionForm name from forms table
event_registrationEvent name from events table
product_purchaseProduct name from products table
tag_applied / tag_removedTag name from tags table
deal_stage_changed"Pipeline Name: Stage Name" from joined pipeline_stages + pipelines
deal_status_changed"Pipeline Name: Won/Lost" by parsing the composite trigger_id
contact_birthdayStatic label: "Contact's Birthday"