Inbound Email Automations

Rules that tag, assign, and auto-reply the moment a new ticket or conversation is created from an inbound email.

Overview

Automations are trigger-action rules. Each rule has an event (what it listens for), conditions (what must match), and actions (what it does). They run in the background right after a new ticket or conversation is persisted and before outbound notifications.

Rules are workspace-scoped and only owners can create, edit, or reorder them.

Events

EventFires when
ticket_createdA new ticket is created from an inbound email (ticket-purpose address).
conversation_createdA new conversation is created from an inbound email (inbox-purpose address, shared or personal).

Conditions

All conditions on a rule must match (AND semantics). String comparisons are case-insensitive; body comparisons strip HTML before matching.

TypeOperatorValue
from_emailequals (default)Exact address, e.g. customer@acme.com
from_emaildomainBare domain, e.g. acme.com (matches any sender at that domain)
subject_containsSubstring, e.g. urgent
body_containsSubstring, matched against the plaintext body
contact_listin / not_inlist_id of a Contact List. Matches when the sender's contact is (or isn't) a member. Sender list memberships are pre-resolved once per rule run, so the check is O(1) per evaluation.

Actions

TypeParametersBehavior
add_tagtag_idAttaches a workspace-scoped tag to the ticket or conversation.
assign_agentuser_idAssigns the ticket or conversation to a workspace member. Non-members are silently skipped.
send_responsebodySends a templated auto-reply from a sendable workspace email. Per-recipient cooldown of 60 minutes prevents loops.

Template variables for send_response

The body of a send_response action supports Mustache-style placeholders. Unknown variables are left intact.

Execution Order

Within a single event, rules run in ascending priority order (lower numbers run first). Set stop_on_match to true on a rule to short-circuit remaining rules once it matches. Inactive rules (is_active = false) are skipped.

Every match increments the rule's match_count and updates last_matched_at. A successful match also logs an automation_applied entry on the ticket or conversation activity timeline.

Cooldown

The send_response action checks the last 60 minutes of automated messages to the same recipient within the workspace. If one exists, the action is skipped. This applies even if the earlier automated message was never successfully delivered, so it's a hard guarantee against auto-reply loops.

Creating a Rule via API

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Urgent auto-reply",
    "event": "conversation_created",
    "is_active": true,
    "priority": 10,
    "stop_on_match": false,
    "conditions": [
      { "type": "subject_contains", "value": "urgent" },
      { "type": "from_email", "operator": "domain", "value": "acme.com" }
    ],
    "actions": [
      { "type": "add_tag", "tag_id": 12 },
      { "type": "assign_agent", "user_id": 3 },
      { "type": "send_response",
        "body": "Hi {{contact.name}}, we got your message and will respond shortly." }
    ]
  }' \
  /api/v1/workspaces/WORKSPACE_ID/automations

Testing a Rule

Use the dry-run endpoint to verify a rule matches a payload without creating tickets, tags, or sending any email.

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from_email": "customer@acme.com",
    "subject": "Urgent: site down",
    "body": "Production is offline"
  }' \
  /api/v1/workspaces/WORKSPACE_ID/automations/RULE_ID/test

The response includes matched (boolean) and a trace of each condition's result.

Reordering Rules

Send an ordered list of rule IDs to reorder priorities in bulk:

POST /api/v1/workspaces/{id}/automations/reorder
{ "ids": [3, 1, 2] }

Endpoints

Frequently Asked Questions

Do automations run retroactively on existing tickets?

No. Automations fire only on fresh ticket_created and conversation_created events. To act on existing tickets, use the REST API directly.

What is the cooldown on auto-replies?

Sixty minutes per recipient per workspace. The send_response action checks for any automated message to the same address within the last 60 minutes and skips if one exists, which prevents auto-reply loops.

Can I test a rule before it runs live?

Yes. Send a sample payload to POST /workspaces/{id}/automations/{rule}/test. The response includes a matched boolean and a trace of each condition's result. Nothing is persisted.

What happens when two rules match the same inbound email?

Rules run in ascending priority order (lower numbers first). Set stop_on_match to true on any rule to halt the chain once it matches.

Who can manage automations?

Workspace owners only. Creating, editing, reordering, and deleting automations requires the owner role. Members can view rules and results.

Can I route a rule based on a Contact List?

Yes. Use the contact_list condition with operator in or not_in and a list_id. The check matches when the sender's contact is (or isn't) a member of that list. Deleting a list while it's referenced by any rule returns 409 Conflict — remove the condition first.

Related