## Create automation

`POST https://whatsapp.paaltech.org/api/v1/businesses/{external_id}/automations`

When `trigger` happens to a contact and the optional `conditions` (a segment condition
tree) hold, run `steps` in order. See the [Automations guide](/docs/automations) for
triggers and steps. The definition is checked when saved (templates must be APPROVED).

Ability: `automations.manage`

### Path parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `external_id` | string | yes | Your own ID for the business (Multi-SKUUL - the tenant ID). Max 191 characters. Pattern `^[A-Za-z0-9._:-]+$` |

### Body

| Name | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes | Max 191 characters |
| `trigger` | string | yes | One of: `message_received`, `keyword`, `contact_created`, `conversation_status`, `date_reached` |
| `trigger_config` | object | null | no | keyword: {keywords: [...]}; conversation_status: {status}; date_reached: {field: a date custom field, offset_days: -3 = three days before}. |
| `conditions` | object | null | no | {"all": [...]} or {"any": [...]} of conditions {"field", "op", "value"} or nested groups (3 levels, 30 conditions). Fields: name, phone, email, locale, timezone, external_id, created_at, tag (has, not_has), consent.<category> (eq granted\|revoked\|none), last_incoming_at (within_days, older_than_days), custom.<key> (by the field's type). Ops: eq, neq, gt, gte, lt, lte, contains, starts_with, in, exists, not_exists, within_days, older_than_days. Example `{"all":[{"field":"custom.class","op":"eq","value":"SHS 2"},{"field":"custom.fee_balance","op":"gt","value":0}]}` |
| `steps` | array of objects | yes | In order. send_template {template, language, parameters, category?, topic?}; send_text {text} (inside the 24-hour window); add_tag / remove_tag {tag}; set_status {status}; add_note {text}; notify {data} (automation.action callback); wait {minutes \| hours \| days}. Max 20 items |

### Request

```bash
curl --request POST \
  --url 'https://whatsapp.paaltech.org/api/v1/businesses/presec/automations' \
  --header "Authorization: Bearer $PAALCHAT_TOKEN" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Chase unpaid fees",
  "trigger": "date_reached",
  "trigger_config": {"field": "fee_due_date", "offset_days": -3},
  "conditions": {"all": [{"field": "custom.fee_balance", "op": "gt", "value": 0}]},
  "steps": [
    {
      "action": "send_template",
      "template": "school_fee_reminder",
      "language": "en_US",
      "parameters": {
        "parent": "field:name",
        "amount": "custom:fee_balance",
        "student": "custom:ward_name",
        "due_date": "custom:fee_due_date"
      }
    },
    {"action": "wait", "days": 3},
    {
      "action": "send_template",
      "template": "school_fee_reminder",
      "language": "en_US",
      "parameters": {
        "parent": "field:name",
        "amount": "custom:fee_balance",
        "student": "custom:ward_name",
        "due_date": "custom:fee_due_date"
      }
    },
    {"action": "notify", "data": {"reason": "fees_overdue"}}
  ]
}'
```

### Responses

- **201** - Saved and active.
- **401** - unauthenticated - missing, invalid, revoked or expired token

```json
{
  "error": {"code": "unauthenticated", "message": "A valid product token is required."}
}
```

- **403** - missing_ability, product_suspended or product_token_required

```json
{
  "error": {
    "code": "missing_ability",
    "message": "This token does not have the ability this request needs."
  }
}
```

- **404** - not_found - not yours, or does not exist

```json
{"error": {"code": "not_found", "message": "Business not found."}}
```

- **422** - validation_failed - fields are invalid; see errors.

```json
{
  "error": {
    "code": "validation_failed",
    "message": "The external id field format is invalid. (and 1 more error)"
  },
  "errors": {
    "external_id": ["The external id field format is invalid."],
    "name": ["The name field is required."]
  }
}
```

- **429** - rate_limited - over 300 requests/minute for this product

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and retry after the Retry-After header."
  }
}
```

