Inbound Email Automations

Rules that tag, assign, answer, mark as spam or trash new mail the moment it opens a ticket or conversation.

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

A rule's match setting says how its conditions combine. With all (the default) every condition must pass. With any the rule fires as soon as one passes, so one rule can cover several subject patterns. String comparisons are case-insensitive; body comparisons strip HTML before matching.

TypeOperatorValue
from_emailequals (default)Exact address, e.g. [email protected]
from_emaildomainBare domain, e.g. acme.com (matches any sender at that domain)
subject_contains—Substring, e.g. urgent
body_contains—Substring, 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.

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.
mark_as_spam—Marks the new ticket or conversation as spam.
move_to_trash—Puts the new ticket or conversation straight in the trash. Nobody is notified, the sender gets no confirmation email, and no send_response goes out for it, even from another rule that matched.

Keep the conditions of a move_to_trash rule narrow. A trashed item can be restored, but the trash is emptied after 30 days, attachments included. Rules only run on mail that starts a new ticket or conversation, so a reply on an existing thread is never trashed this way.

Template variables for send_response

The body of a send_response action supports 9 placeholders, the same ones canned responses use. Unknown variables are left as written.

Execution Order

Within a single event, rules run in the order you put them in (see Reordering Rules below). 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,
    "match": "all",
    "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": "[email protected]",
    "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:

PATCH /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 the order you set with the reorder endpoint, top 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