# Sales automation

Three kinds of automation, each the same as its page in TruTec:

- **Pipeline automation** (Jobs › Automation): which stage a job moves to when a proposal is started, sent, accepted or declined, bid follow-up reminders, follow-up sequences, stale-job cleanup and follow-up tasks after proposals.
- **Company automations**: no-code rules on the company sales pipeline ("when a company enters *Bidding*, create a call follow-up for the salesperson").
- **Email campaigns**: one-time emails and drips to companies in the sales pipeline. Campaigns are built in TruTec; the API reads them and starts, pauses, resumes or stops them.

Changing settings and rules needs a key created by a workspace **owner** (other keys get `403`). Company automations and email campaigns are available on workspaces with the company sales pipeline (`403 Not available for this workspace` otherwise).

!!! warning
    These endpoints can make TruTec **email your customers**: a follow-up sequence that is switched on, a company automation with an *Email the customer* or *Add to an email campaign* step, and launching or resuming a campaign. Confirm with whoever owns the account before turning any of them on.

## Pipeline automation

### Get pipeline automation

`GET /v1/pipeline-automation`

**Permission:** Read jobs

```json
{
  "data": {
    "proposal_started_status": "estimating",
    "proposal_sent_status": "proposal_sent",
    "proposal_accepted_status": "won",
    "proposal_declined_status": "lost",
    "post_bid_enabled": true,
    "post_bid_trigger_statuses": ["proposal_sent"],
    "post_bid_followup_days": [5, 20, 45, 60],
    "post_bid_overdue_after_days": 60,
    "stale_inactive_enabled": false,
    "sales_sequence_enabled": true,
    "sales_sequence_stop_on_response": true,
    "sales_sequences": [
      {"id": "default", "name": "Follow-up sequence", "enabled": true, "trigger_mode": "proposal",
       "trigger_statuses": [], "steps": [{"delay_days": 1, "task_type": "email", "title": "Send first follow-up",
                                           "subject": "Following up on {{job_name}}", "body": "Hi {{contact_name}}, ..."}]}
    ],
    "sales_sequences_revision": "a41c09e2",
    "proposal_sent_task_enabled": false,
    "proposal_sent_task_title": "Confirm the proposal landed",
    "proposal_sent_task_delay_days": 1
  }
}
```

Stage values are pipeline stage keys (`GET /v1/job-stages`); `""` means no move. The response also carries the subcontractor pricing, RFQ due date and crew work stage settings shown on the same page.

### Update pipeline automation

`PATCH /v1/pipeline-automation`

**Permission:** Write jobs, owner key

Send any of the fields above; only those change. Unknown fields are a `400`. `sales_sequences` replaces every sequence (a sequence you leave out is removed and its open steps are closed); send `sales_sequences_revision` from your last read to get a `409` instead of overwriting someone else's edit.

```bash
curl -X PATCH "https://trutec.ai/api/v1/pipeline-automation" \
  -H "X-API-Key: sk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"proposal_sent_status": "proposal_sent", "post_bid_followup_days": [3, 10, 30]}'
```

Returns the full settings. **Errors:** `400` with the app's reason (an unknown stage, a bad sequence step); `403` when the key's user isn't an owner; `409` when the sequences changed since `sales_sequences_revision`.

## Company automations

### The rule object

| Field | Type | Description |
|---|---|---|
| `id` | integer | TruTec id. |
| `name` | string | |
| `enabled` | boolean | Rules only act on what happens after they are switched on. |
| `trigger_type` | string | `enters_stage`, `no_touch`, `in_stage_days`, `company_created`, `job_created`, `proposal_sent`, `job_won`, `job_lost`, `customer_replied`, `renewal_upcoming`. |
| `trigger_config` | object | `stage` (a stage id or `any_open` / `any_won` / `any_nurture`) and `days`, as the trigger needs. |
| `conditions` | object | Optional: `salesperson_ids`, `temperatures`, `tags`, `customer_types`, `stages`. |
| `actions` | array | 1-5 steps (below). |
| `run_count`, `runs_this_week`, `failed_this_week` | integer | |
| `last_run_at`, `created_at`, `updated_at` | string | UTC. |

Action steps, each `{"type": ...}`:

| Type | Fields |
|---|---|
| `create_task` | `title`, `task_type`, `due_days`, `due_time` (`HH:MM`), `assign_to` (`salesperson`, `mover`, `member` + `user_id`) |
| `move_stage` | `stage_id`, `forward_only` (default true) |
| `email_team` | `to` (`salesperson`, `owners`, `member` + `user_id`), `subject`, `message` |
| `email_customer` | `to` (`primary` or `all`), `subject`, `body`. **Emails the customer.** |
| `enroll_campaign` | `campaign_id`. **Emails the customer** through the campaign. |
| `assign_salesperson` | `mode` (`member` + `user_id`, or `round_robin` + `user_ids`), `only_if_unassigned` |
| `set_temperature` | `temperature` (`hot`, `warm`, `cold`) |
| `add_tag` | `tag` |

Texts may use merge fields: `{{contact_first_name}}`, `{{contact_name}}`, `{{company_name}}`, `{{salesperson_name}}`, `{{salesperson_phone}}`, `{{my_company_name}}`.

### List rules and options

`GET /v1/company-automations` (filter `enabled`, paged) and `GET /v1/company-automations/options` (the workspace's stages, campaigns, triggers, actions and the values each field takes).

**Permission:** Read jobs

### Create, change, switch on or off, delete

| Endpoint | Permission | Notes |
|---|---|---|
| `POST /v1/company-automations` | Write jobs, owner key | `trigger_type` and `actions` required; on unless `enabled: false`. `201`. |
| `PATCH /v1/company-automations/{automation_id}` | Write jobs, owner key | Fields not sent keep their values; `actions` replaces the list. |
| `POST /v1/company-automations/{automation_id}/enable` | Write jobs, owner key | Acts on what happens from now on. |
| `POST /v1/company-automations/{automation_id}/disable` | Write jobs, owner key | |
| `DELETE /v1/company-automations/{automation_id}` | Write jobs + Delete records, owner key | Deletes its run history too. `204`. |

```bash
curl -X POST "https://trutec.ai/api/v1/company-automations" \
  -H "X-API-Key: sk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"name": "Gone quiet for 2 weeks", "trigger_type": "no_touch",
       "trigger_config": {"stage": "any_open", "days": 14},
       "actions": [{"type": "create_task", "title": "Check in with {{company_name}}", "task_type": "call",
                    "due_days": 0, "assign_to": "salesperson"}]}'
```

**Errors:** `400` with the app's reason (for example *Pick the stage to move the company to.*); `403` for a non-owner key.

## Email campaigns

### List and read campaigns

`GET /v1/email-campaigns` (filter `status`: `draft`, `scheduled`, `sending`, `active`, `paused`, `completed`, `cancelled`) and `GET /v1/email-campaigns/{campaign_id}` (adds its `emails`: subject and delay of each step).

**Permission:** Read jobs

Each campaign has `name`, `kind` (`one_time` or `drip`), `status`, `sender_mode`, `scheduled_at`, and results: `recipient_count`, `emails_sent`, `opened_count`, `clicked_count`, `replied_count`, `unsubscribed_count`, `failed_count`.

### Launch, pause, resume, stop

| Endpoint | What it does |
|---|---|
| `POST /v1/email-campaigns/{campaign_id}/launch` | Starts a **draft**. `when`: `now` (default; the first emails go out within about 10 minutes) or `schedule` (at its saved send time). **Emails everyone in its audience**, from the senders set on the campaign. |
| `POST /v1/email-campaigns/{campaign_id}/pause` | Nothing more goes out until it is resumed. |
| `POST /v1/email-campaigns/{campaign_id}/resume` | A paused campaign **starts emailing again**. |
| `POST /v1/email-campaigns/{campaign_id}/cancel` | Stops it for good; waiting emails are skipped. |

**Permission:** Write jobs. Each returns `{"data": {campaign}, "message": "..."}`. **Errors:** `400` with the app's reason when a campaign can't launch (no audience, no sender mailbox, ...); `409` when it is in the wrong state (launching one that already started, resuming one that isn't paused).
