# POST /automations

**Resource:** [Automations](./automations.md)  
**Scopes:** `automations:write`  
**Write operation:** yes

Create a new automation. name and trigger_type are required. For stage_changed automations, pass stage_id directly on the automation -- this is the single source of truth for stage matching (do not use automations_triggers for stage_changed). Note: trigger_type "form_submitted" is deprecated and rejected -- use "form_completed" instead.

## Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `name` | body | string | yes | Automation name |
| `trigger_type` | body | string | yes | Trigger type. Common values: stage_changed, form_completed, call_analyzed, sms_received, email_received, checkout_completed. CRM entity triggers (fired by Portal API on CRUD): contact_created, contact_updated, customer_created, customer_updated, deal_created, deal_updated. ENTITY AXIS RULES: contact_type lives on contacts (use contact_created/updated); account_type lives on customers (use customer_created/updated); opportunity_type lives on deals (use deal_created/updated). Update triggers include _changed_fields and _previous_values in trigger data for field-level condition matching. ALL entity triggers also include _trigger_entity_kind ("contact"\|"customer"\|"deal") and _trigger_entity_id (the UUID of the triggering row) so CRM Integration actions can match the exact record by id without needing email/phone/name extraction. DEPRECATED: "form_submitted" is rejected with a 400 -- use "form_completed". |
| `stage_id` | body | uuid | no | Pipeline stage UUID. Required when trigger_type is "stage_changed". Single source of truth for stage matching. |
| `description` | body | string | no | Description |
| `enabled` | body | boolean | no | Whether enabled (default: false) |
| `priority` | body | number | no | Execution priority |
| `conditions` | body | object | no | Conditions that must ALL pass (AND logic) for the automation to fire. Evaluated AFTER CRM enrichment, so CRM fields (tags, deal value, lead source, contact email) are available for ALL trigger types. When conditions are not met the run status is "skipped". Operators: eq, neq, exists, not_exists, gt, gte, lt, lte, contains (tag array), not_contains, contains_any, contains_text, in. Example: { "tags": { "contains": "VIP" }, "deal.value": { "gte": 5000 }, "lead_source": { "in": ["Referral", "Website"] } } |

## Request example

```bash
curl -X POST \
  "https://api.trustpager.com/functions/v1/api/v1/automations" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "VIP Lead Welcome",
    "trigger_type": "stage_changed",
    "stage_id": "stage-uuid",
    "conditions": {
      "tags": { "contains": "VIP" },
      "deal.value": { "gte": 5000 },
      "lead_source": { "in": ["Referral", "Website"] }
    },
    "description": "Send welcome email to VIP leads only"
  }'
```

## Response example

```json
{
  "data": {
    "id": "auto-uuid-...",
    "name": "VIP Lead Welcome",
    "trigger_type": "stage_changed",
    "stage_id": "stage-uuid",
    "conditions": {
      "tags": { "contains": "VIP" },
      "deal.value": { "gte": 5000 },
      "lead_source": { "in": ["Referral", "Website"] }
    },
    "enabled": false,
    "created_at": "2026-04-18T00:00:00Z"
  }
}
```

---
Base URL: `https://api.trustpager.com/functions/v1/api/v1` — Auth: `Authorization: Bearer YOUR_API_KEY`