autotouch-cli 0.2.26__tar.gz → 0.2.27__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/PKG-INFO +183 -22
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/autotouch_cli.egg-info/PKG-INFO +183 -22
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/autotouch_cli.egg-info/SOURCES.txt +1 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/docs/research-table/reference/autotouch-cli.md +182 -21
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/pyproject.toml +1 -1
- autotouch_cli-0.2.27/scripts/migrations/20260306_migrate_lead_identity_v1.py +538 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/smart_table_cli.py +1347 -48
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_contactout_pipeline.py +4 -9
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_lead_required_fields.py +7 -5
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/autotouch_cli.egg-info/dependency_links.txt +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/autotouch_cli.egg-info/entry_points.txt +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/autotouch_cli.egg-info/requires.txt +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/autotouch_cli.egg-info/top_level.txt +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/__init__.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/add_column_unique_index.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/attach_csv_import_leads_to_research_table.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/bundle_sequences_backend.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/check_agent_traces.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/check_column_mode.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/exit_terminal_leads_from_sequences.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/fetch_lead.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/fix_lead_titles_from_csv.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250106_add_column_position.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250108_fix_legacy_column_fields.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250109_add_user_fields_to_tables.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250117_add_call_logs_webhook_indexes.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250117_rename_call_logs_collection.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250119_create_leads_unique_email_index.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250123_add_filter_indexes.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250123_add_llm_responses_collection.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250128_migrate_user_ids_to_objectid.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250208_backfill_task_research_values.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250604_add_origin_indexes.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250608_cleanup_agent_metadata.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250608_rename_agent_metadata_to_metadata.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250922_add_activity_indexes.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250926_migrate_single_to_arrays.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250928_add_missing_timestamp_fields.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250929_add_task_join_indexes.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250929_add_task_join_indexes_safe.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20250929_create_shared_phone_cache.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20251007_add_rows_position_id_index.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20251109_add_ttl_for_llm_and_preview_traces.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20260113_normalize_table_filter_operators.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20260113_set_user_permissions_user_admin.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20260204_sync_lead_owner_from_tasks.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20260303_add_webhook_subscription_collections.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/20260305_force_formatter_autorun_on_source_update.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/migrate_org_user_credits.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/set_default_lead_status.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/migrations/update_lead_owner_from_tasks.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/reassign_sequence_owner.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/run_sidecar_orchestrator_demo.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/test_crm_company_policy.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/test_sequences_instantly_e2e.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/test_sequences_personal_e2e.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/test_task_error_logger.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/scripts/verify_azurite_voicemail.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/setup.cfg +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_contactout_custom.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_contactout_integration.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_contactout_multi_titles.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_contactout_simple.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_contactout_v2_bulk.py +0 -0
- {autotouch_cli-0.2.26 → autotouch_cli-0.2.27}/tests/test_phone_provider_pipeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autotouch-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.27
|
|
4
4
|
Summary: Autotouch Smart Table CLI
|
|
5
5
|
Requires-Python: >=3.9
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -21,7 +21,7 @@ Use this order when you are orienting in the CLI:
|
|
|
21
21
|
2. Use the API endpoint -> CLI command map when translating an existing API workflow.
|
|
22
22
|
3. Use `autotouch columns recipe` before creating provider-backed workflow columns.
|
|
23
23
|
4. Use `autotouch jobs get` as the source of truth for async run state.
|
|
24
|
-
5. Use
|
|
24
|
+
5. Use `autotouch sequences ...` for sequence definitions, status changes, and direct enrollments; tasks still use raw HTTP.
|
|
25
25
|
|
|
26
26
|
### Quick decision guide
|
|
27
27
|
|
|
@@ -36,14 +36,20 @@ Use this order when you are orienting in the CLI:
|
|
|
36
36
|
| run one exact row or an explicit list of row IDs | `scope=row` for one ID, `scope=subset` for many IDs |
|
|
37
37
|
| verify whether a job is really done | `autotouch jobs get --job-id <JOB_ID>` |
|
|
38
38
|
| create projections from JSON output | `autotouch columns projections` |
|
|
39
|
-
|
|
|
39
|
+
| create/manage sequence definitions directly | `autotouch sequences recipe`, then `autotouch sequences create/update/activate` |
|
|
40
|
+
| enroll leads directly into a sequence | `autotouch sequences enroll --sequence-id <SEQUENCE_ID> ...` |
|
|
41
|
+
| enroll table rows into an existing sequence | `autotouch columns recipe --type add_to_sequence`, then `autotouch columns create` + `autotouch columns run` |
|
|
42
|
+
| create or update a CRM lead | `autotouch leads recipe --type create`, then `autotouch leads create` / `autotouch leads update` |
|
|
43
|
+
| add email or phone contact info to a lead | `autotouch leads recipe --type contact_upsert`, then `autotouch leads upsert-contact-channels --lead-id <LEAD_ID> ...` |
|
|
44
|
+
| bulk update lead status or owner | `autotouch leads update-status` / `autotouch leads reassign-owner` |
|
|
45
|
+
| manage tasks directly | raw HTTP plus `docs/platform/external-workflows-api.md` |
|
|
40
46
|
| query/filter CRM leads and attached research | `autotouch leads query` then `autotouch leads research` |
|
|
41
47
|
|
|
42
48
|
### Operating model
|
|
43
49
|
|
|
44
50
|
- This file is the full CLI reference and the package readme published to PyPI.
|
|
45
51
|
- The installed package gives you CLI entrypoints and package metadata; do not assume there is a separate installed docs directory.
|
|
46
|
-
- Research-table APIs and
|
|
52
|
+
- Research-table APIs, sequence commands, and lead create/query/update operations are the primary CLI surface today; direct task management is still HTTP-first.
|
|
47
53
|
- For async operations, backend bulk-job state is authoritative; local terminal output is only a convenience layer.
|
|
48
54
|
- For staged or cost-sensitive runs, estimate first and prefer filtered scopes plus `firstN` or `run-next`.
|
|
49
55
|
|
|
@@ -129,6 +135,23 @@ Notes:
|
|
|
129
135
|
| `POST /api/tables/{table_id}/columns/{column_id}/stop` | `autotouch columns stop --table-id <TABLE_ID> --column-id <COLUMN_ID>` |
|
|
130
136
|
| `GET /api/bulk-jobs` | `autotouch jobs list --table-id <TABLE_ID> --column-id <COLUMN_ID> --limit 10` |
|
|
131
137
|
| `GET /api/bulk-jobs/{job_id}` | `autotouch jobs get --job-id <JOB_ID>` |
|
|
138
|
+
| `GET /api/sequences` | `autotouch sequences list --limit 50` |
|
|
139
|
+
| `GET /api/sequences/{sequence_id}` | `autotouch sequences get --sequence-id <SEQUENCE_ID>` |
|
|
140
|
+
| `GET /api/sequences/{sequence_id}/stats` | `autotouch sequences stats --sequence-id <SEQUENCE_ID>` |
|
|
141
|
+
| `GET /api/sequences/delivery-status` | `autotouch sequences delivery-status` |
|
|
142
|
+
| `POST /api/sequences` | `autotouch sequences create --data-file sequence.json` |
|
|
143
|
+
| `PUT /api/sequences/{sequence_id}` | `autotouch sequences update --sequence-id <SEQUENCE_ID> --data-file sequence.json` |
|
|
144
|
+
| `DELETE /api/sequences/{sequence_id}` | `autotouch sequences delete --sequence-id <SEQUENCE_ID> --yes` |
|
|
145
|
+
| `POST /api/sequences/{sequence_id}/clone` | `autotouch sequences clone --sequence-id <SEQUENCE_ID>` |
|
|
146
|
+
| `PATCH /api/sequences/{sequence_id}/status` | `autotouch sequences status --sequence-id <SEQUENCE_ID> --status ACTIVE` |
|
|
147
|
+
| `POST /api/sequences/{sequence_id}/enroll` | `autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID>` |
|
|
148
|
+
| `POST /api/sequences/{sequence_id}/enrollments/pause` | `autotouch sequences pause-enrollment --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID>` |
|
|
149
|
+
| `GET /api/leads/{lead_id}` | `autotouch leads get --lead-id <LEAD_ID>` |
|
|
150
|
+
| `POST /api/leads` | `autotouch leads create --data-file lead.json` |
|
|
151
|
+
| `PUT /api/leads/{lead_id}` | `autotouch leads update --lead-id <LEAD_ID> --data-file patch.json` |
|
|
152
|
+
| `POST /api/leads/{lead_id}/contact-channels` | `autotouch leads upsert-contact-channels --lead-id <LEAD_ID> --data-file contacts.json` |
|
|
153
|
+
| `POST /api/leads/bulk_update_status` | `autotouch leads update-status --lead-id <LEAD_ID> --status contacting` |
|
|
154
|
+
| `POST /api/leads/bulk_reassign_owner` | `autotouch leads reassign-owner --lead-id <LEAD_ID> --user-id <USER_ID>` |
|
|
132
155
|
| `POST /api/leads/query` | `autotouch leads query --filter-file lead-filter.json --limit 50` |
|
|
133
156
|
| `POST /api/leads/query/count` | `autotouch leads count --filter-file lead-filter.json` |
|
|
134
157
|
| `POST /api/leads/query/stats` | `autotouch leads stats --filter-file lead-filter.json` |
|
|
@@ -138,6 +161,15 @@ Notes:
|
|
|
138
161
|
| `GET /api/tables/{table_id}/webhook` | `autotouch webhooks get --table-id <TABLE_ID>` |
|
|
139
162
|
| `POST /api/tables/{table_id}/webhook` | `autotouch webhooks rotate --table-id <TABLE_ID>` |
|
|
140
163
|
| `POST /api/webhooks/tables/{table_id}/ingest` | `autotouch webhooks ingest --table-id <TABLE_ID> --records-file records.json --webhook-token <WEBHOOK_TOKEN>` |
|
|
164
|
+
| `GET /api/webhook-subscriptions` | `autotouch webhooks subscriptions list --limit 100` |
|
|
165
|
+
| `POST /api/webhook-subscriptions` | `autotouch webhooks subscriptions create --data-file subscription.json` |
|
|
166
|
+
| `GET /api/webhook-subscriptions/{subscription_id}` | `autotouch webhooks subscriptions get --subscription-id <SUBSCRIPTION_ID>` |
|
|
167
|
+
| `PATCH /api/webhook-subscriptions/{subscription_id}` | `autotouch webhooks subscriptions update --subscription-id <SUBSCRIPTION_ID> --data-file patch.json` |
|
|
168
|
+
| `DELETE /api/webhook-subscriptions/{subscription_id}` | `autotouch webhooks subscriptions delete --subscription-id <SUBSCRIPTION_ID>` |
|
|
169
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/pause` | `autotouch webhooks subscriptions pause --subscription-id <SUBSCRIPTION_ID>` |
|
|
170
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/resume` | `autotouch webhooks subscriptions resume --subscription-id <SUBSCRIPTION_ID>` |
|
|
171
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/rotate-secret` | `autotouch webhooks subscriptions rotate-secret --subscription-id <SUBSCRIPTION_ID>` |
|
|
172
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/test` | `autotouch webhooks subscriptions test --subscription-id <SUBSCRIPTION_ID>` |
|
|
141
173
|
| `POST /api/auth/agent-bootstrap` | HTTP-only bootstrap (no direct CLI wrapper yet) |
|
|
142
174
|
|
|
143
175
|
## Delete column
|
|
@@ -153,19 +185,81 @@ CLI:
|
|
|
153
185
|
autotouch columns delete --table-id <TABLE_ID> --column-id <COLUMN_ID> --yes
|
|
154
186
|
```
|
|
155
187
|
|
|
156
|
-
##
|
|
188
|
+
## Sequence commands
|
|
157
189
|
|
|
158
|
-
|
|
190
|
+
The CLI now exposes the public Sequences endpoints under `autotouch sequences`.
|
|
191
|
+
Tasks still use raw HTTP plus `docs/platform/external-workflows-api.md`.
|
|
159
192
|
|
|
160
|
-
|
|
161
|
-
- `
|
|
162
|
-
- `
|
|
163
|
-
- `
|
|
164
|
-
- `
|
|
165
|
-
- `
|
|
166
|
-
- `
|
|
167
|
-
- `
|
|
168
|
-
- `
|
|
193
|
+
Common commands:
|
|
194
|
+
- `autotouch sequences recipe --type create --out-file sequence.json`
|
|
195
|
+
- `autotouch sequences recipe --type bulk_automated --out-file sequence.json`
|
|
196
|
+
- `autotouch sequences create --data-file sequence.json`
|
|
197
|
+
- `autotouch sequences update --sequence-id <SEQUENCE_ID> --data-file sequence.json`
|
|
198
|
+
- `autotouch sequences activate --sequence-id <SEQUENCE_ID>`
|
|
199
|
+
- `autotouch sequences pause --sequence-id <SEQUENCE_ID>`
|
|
200
|
+
- `autotouch sequences archive --sequence-id <SEQUENCE_ID>`
|
|
201
|
+
- `autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID> --wait`
|
|
202
|
+
- `autotouch sequences pause-enrollment --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID>`
|
|
203
|
+
- `autotouch sequences delivery-status`
|
|
204
|
+
- `autotouch sequences list --include-stats`
|
|
205
|
+
|
|
206
|
+
Important contract notes:
|
|
207
|
+
- Create/update via developer key still requires `sourceTableId`.
|
|
208
|
+
- Mutating sequence commands accept `--actor-user-id` for explicit actor resolution.
|
|
209
|
+
- Recommended default: personal delivery plus `EMAIL` steps with `emailSendMode=MANUAL` and `aiDraft=true`.
|
|
210
|
+
- Use `bulk_automated` only when the provider should send email automatically at scale. `aiDraft` does not apply to bulk automated email steps.
|
|
211
|
+
- Personal delivery uses the connected inbox for the enrolled owner (`assignedToUserId`, else the enrolling actor); there is no per-sequence personal sender picker yet.
|
|
212
|
+
- If that user has multiple connected personal inboxes for the same provider, the most recently updated one is used. Gmail is tried before Microsoft. Sender stays pinned after the first personal email in that enrollment.
|
|
213
|
+
- Bulk delivery uses `emailDelivery.bulkProvider`; Instantly can also narrow sending accounts via `emailDelivery.providerConfig.instantly.selectedAccounts`.
|
|
214
|
+
- `activate`, `pause`, and `archive` are convenience wrappers around `autotouch sequences status`.
|
|
215
|
+
- `autotouch sequences enroll --wait` polls `/api/bulk-jobs/{job_id}` and preserves the API response `task_id` as the bulk job id.
|
|
216
|
+
- Research-table `add_to_sequence` is still available through `autotouch columns create/update/run` and still targets an existing sequence.
|
|
217
|
+
- Real enrollment requires the target sequence to be `ACTIVE` unless direct enroll uses `reviewOnly=true`.
|
|
218
|
+
- Tasks remain HTTP-only.
|
|
219
|
+
|
|
220
|
+
AI draft outputs:
|
|
221
|
+
- Manual new email: subject + body
|
|
222
|
+
- Manual reply email: reply body
|
|
223
|
+
- LinkedIn connect: connection note
|
|
224
|
+
- LinkedIn message: message copy
|
|
225
|
+
- Call: call script
|
|
226
|
+
|
|
227
|
+
Example:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
autotouch sequences recipe --type create --out-file sequence.json
|
|
231
|
+
autotouch sequences create --data-file sequence.json
|
|
232
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Cookbooks:
|
|
236
|
+
|
|
237
|
+
1. Recommended personal AI-assisted outreach
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
autotouch sequences recipe --type create --out-file sequence.json
|
|
241
|
+
autotouch sequences create --data-file sequence.json
|
|
242
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
243
|
+
autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-ids-file lead_ids.json --wait
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Notes:
|
|
247
|
+
- `recipe --type create` is the recommended default.
|
|
248
|
+
- It starts with personal delivery, a manual AI-drafted email, then AI-drafted call and LinkedIn follow-up steps.
|
|
249
|
+
- Favorite/starred research fields are the default grounding context when explicit `fieldIds` are not provided.
|
|
250
|
+
|
|
251
|
+
2. Bulk automated email sequence
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
autotouch sequences recipe --type bulk_automated --out-file sequence.json
|
|
255
|
+
autotouch sequences create --data-file sequence.json
|
|
256
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
257
|
+
autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-ids-file lead_ids.json --wait
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Notes:
|
|
261
|
+
- Use this when Instantly or Smartlead should send email automatically.
|
|
262
|
+
- Bulk automated email steps do not support `aiDraft`; author the templates directly in `subjectTemplate` and `bodyTemplate`.
|
|
169
263
|
|
|
170
264
|
Reference contract (actor model + manual/automated/AI-draft nuances):
|
|
171
265
|
- `docs/platform/external-workflows-api.md`
|
|
@@ -177,16 +271,25 @@ Signature controls for sequence payloads:
|
|
|
177
271
|
|
|
178
272
|
## Leads API coverage
|
|
179
273
|
|
|
180
|
-
The CLI now exposes the public read
|
|
274
|
+
The CLI now exposes the public leads read + write endpoints under `autotouch leads`.
|
|
181
275
|
|
|
182
276
|
Use this pattern:
|
|
183
277
|
|
|
184
|
-
1. `autotouch leads
|
|
185
|
-
2. `autotouch leads
|
|
186
|
-
3. `autotouch leads
|
|
278
|
+
1. `autotouch leads create` when you need to create one lead from canonical JSON input.
|
|
279
|
+
2. `autotouch leads recipe` when you want a ready-to-edit payload for create, update, or contact upsert.
|
|
280
|
+
3. `autotouch leads update` for scalar or partial lead updates.
|
|
281
|
+
4. `autotouch leads upsert-contact-channels` when you need to add or merge emails/phones without replacing the full arrays.
|
|
282
|
+
5. `autotouch leads update-status` / `autotouch leads reassign-owner` for operational bulk changes by explicit IDs or descriptor selection.
|
|
283
|
+
6. `autotouch leads query` to page through leads, apply descriptor filters, and inspect `related_tables` / `research_summary`.
|
|
284
|
+
7. `autotouch leads research` when you need actual research field values for specific lead IDs from one source table.
|
|
187
285
|
|
|
188
286
|
Important contract notes:
|
|
189
287
|
- External callers should use `POST /api/leads/query` rather than the older `GET /api/leads` list route.
|
|
288
|
+
- `autotouch leads get` is the direct single-lead lookup path.
|
|
289
|
+
- Use `autotouch leads update` for scalar lead fields only.
|
|
290
|
+
- `autotouch leads update` rejects email/phone fields and points callers to `autotouch leads upsert-contact-channels`.
|
|
291
|
+
- Contact upsert merges into canonical `email_addresses` and `phone_numbers` instead of replacing those arrays.
|
|
292
|
+
- `update-status` and `reassign-owner` accept either explicit lead IDs or descriptor selection input (`--filter-json`, `--search`, `--scope`, etc.).
|
|
190
293
|
- `autotouch leads query` accepts the same descriptor payload shape as the backend:
|
|
191
294
|
- `filter`
|
|
192
295
|
- `search`
|
|
@@ -200,6 +303,52 @@ Important contract notes:
|
|
|
200
303
|
|
|
201
304
|
Examples:
|
|
202
305
|
|
|
306
|
+
```bash
|
|
307
|
+
autotouch leads recipe --type create --out-file lead.json
|
|
308
|
+
autotouch leads create --data-file lead.json
|
|
309
|
+
autotouch leads get --lead-id <LEAD_ID>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
autotouch leads recipe --type update --out-file lead-patch.json
|
|
314
|
+
autotouch leads update \
|
|
315
|
+
--lead-id <LEAD_ID> \
|
|
316
|
+
--data-file lead-patch.json
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
autotouch leads recipe --type contact_upsert --out-file contacts.json
|
|
321
|
+
autotouch leads upsert-contact-channels \
|
|
322
|
+
--lead-id <LEAD_ID> \
|
|
323
|
+
--data-file contacts.json
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
`contacts.json` example:
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"emails": [
|
|
331
|
+
{ "address": "john@acme.com", "type": "work", "primary": true }
|
|
332
|
+
],
|
|
333
|
+
"phones": [
|
|
334
|
+
{ "number": "+14155551234", "type": "mobile", "primary": true }
|
|
335
|
+
]
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
autotouch leads update-status \
|
|
341
|
+
--filter-json '{"root":{"kind":"rule","field":"lead_status","operator":"eq","value":"new"}}' \
|
|
342
|
+
--status contacting
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
autotouch leads reassign-owner \
|
|
347
|
+
--lead-id <LEAD_ID_1> \
|
|
348
|
+
--lead-id <LEAD_ID_2> \
|
|
349
|
+
--user-id <USER_ID>
|
|
350
|
+
```
|
|
351
|
+
|
|
203
352
|
```bash
|
|
204
353
|
autotouch leads query \
|
|
205
354
|
--filter-json '{"root":{"kind":"rule","field":"status","operator":"eq","value":"new"}}' \
|
|
@@ -246,6 +395,7 @@ Important fields:
|
|
|
246
395
|
- `total_rows`: scoped row count for the run
|
|
247
396
|
- `pending_batches`: derived remaining batches
|
|
248
397
|
- `terminal_reason`: terminal classifier
|
|
398
|
+
- timing checkpoints: `enqueued_at`, `orchestrator_started_at`, `provider_started_at`, `provider_completed_at`
|
|
249
399
|
|
|
250
400
|
Terminal states:
|
|
251
401
|
- `completed`
|
|
@@ -497,11 +647,13 @@ Notes:
|
|
|
497
647
|
}
|
|
498
648
|
```
|
|
499
649
|
|
|
500
|
-
Add-to-Leads note:
|
|
650
|
+
Add-to-Leads note: `companyDomain` is required; LinkedIn is optional. Each row still needs at least one usable hard identity signal (LinkedIn, email, or phone). Names and location fields are metadata only for this flow. Run is non-billable.
|
|
501
651
|
If `companyDomain` is missing in the table, derive or enrich that domain column first, then rerun `add_to_crm`.
|
|
652
|
+
Queued lifecycle: the CLI/API accepts the run immediately, then the backend hands off `ops -> data_io` for execution.
|
|
502
653
|
|
|
503
654
|
CRM data model expectations (recommended before `add_to_crm`):
|
|
504
|
-
- Lead identity/dedupe expects `
|
|
655
|
+
- Lead identity/dedupe expects `company_domain` plus one usable hard identity signal. `linkedin_url` is a strong optional signal, not a requirement.
|
|
656
|
+
- Placeholder or malformed hard identifiers are treated as missing during research-table export. Rows without any surviving LinkedIn/email/phone signal are skipped instead of erroring.
|
|
505
657
|
- `company_domain` is required; `company_name` is only a display hint and is applied to the linked Company record when provided.
|
|
506
658
|
- Lead records link to Company via `company_id`; company names live on Company docs, not as canonical lead fields.
|
|
507
659
|
- Canonical contact fields are arrays (`email_addresses[]`, `phone_numbers[]`); top-level `email`/`mobile_number` may exist on legacy rows but should not be treated as source of truth.
|
|
@@ -558,7 +710,7 @@ Notes:
|
|
|
558
710
|
```
|
|
559
711
|
|
|
560
712
|
Notes:
|
|
561
|
-
- `sourceLeadColumn` must
|
|
713
|
+
- `sourceLeadColumn` must be the source column key that stores lead IDs (for example `add_to_leads` or another lead-id column key from `lead_finder` output), not the provider name `add_to_crm`.
|
|
562
714
|
- `sequenceId` is the target sequence workflow ID.
|
|
563
715
|
- The target sequence must already be `ACTIVE` for real enrollment. Table `add_to_sequence` runs and direct `POST /api/sequences/{id}/enroll` share the same activation check.
|
|
564
716
|
- `add_to_sequence` runs auto-attach `research_context.source_table_id` (and table name when available). Field selection stays implicit so sequence drafts/audience resolve favorites from current starred columns by default.
|
|
@@ -573,12 +725,21 @@ autotouch tables create --name "CLI Contacts"
|
|
|
573
725
|
autotouch rows import-csv --table-id <TABLE_ID> --file contacts.csv
|
|
574
726
|
autotouch columns recipe --type add_to_crm --out-file column.json
|
|
575
727
|
autotouch columns create --table-id <TABLE_ID> --data-file column.json
|
|
728
|
+
autotouch sequences recipe --type create --out-file sequence.json
|
|
729
|
+
autotouch sequences create --data-file sequence.json
|
|
730
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
576
731
|
autotouch columns recipe --type add_to_sequence --out-file add-to-sequence.json
|
|
577
732
|
autotouch columns create --table-id <TABLE_ID> --data-file add-to-sequence.json
|
|
578
733
|
autotouch columns run-next --table-id <TABLE_ID> --column-id <COLUMN_ID> --count 25 --filters-file filters.json --show-estimate --wait
|
|
579
734
|
autotouch jobs get --job-id <JOB_ID>
|
|
580
735
|
```
|
|
581
736
|
|
|
737
|
+
Sequence creation note:
|
|
738
|
+
- The CLI can create/update/activate sequence definitions directly with `autotouch sequences ...`.
|
|
739
|
+
- Research-table `add_to_sequence` columns and direct `autotouch sequences enroll` both target an existing sequence.
|
|
740
|
+
- Real enrollment still requires that sequence to be `ACTIVE` unless direct enroll uses `reviewOnly=true`.
|
|
741
|
+
- Tasks still use raw HTTP.
|
|
742
|
+
|
|
582
743
|
## Safe run patterns (`firstN` + `--unprocessed-only`)
|
|
583
744
|
|
|
584
745
|
Use this pattern for progressive rollouts.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autotouch-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.27
|
|
4
4
|
Summary: Autotouch Smart Table CLI
|
|
5
5
|
Requires-Python: >=3.9
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -21,7 +21,7 @@ Use this order when you are orienting in the CLI:
|
|
|
21
21
|
2. Use the API endpoint -> CLI command map when translating an existing API workflow.
|
|
22
22
|
3. Use `autotouch columns recipe` before creating provider-backed workflow columns.
|
|
23
23
|
4. Use `autotouch jobs get` as the source of truth for async run state.
|
|
24
|
-
5. Use
|
|
24
|
+
5. Use `autotouch sequences ...` for sequence definitions, status changes, and direct enrollments; tasks still use raw HTTP.
|
|
25
25
|
|
|
26
26
|
### Quick decision guide
|
|
27
27
|
|
|
@@ -36,14 +36,20 @@ Use this order when you are orienting in the CLI:
|
|
|
36
36
|
| run one exact row or an explicit list of row IDs | `scope=row` for one ID, `scope=subset` for many IDs |
|
|
37
37
|
| verify whether a job is really done | `autotouch jobs get --job-id <JOB_ID>` |
|
|
38
38
|
| create projections from JSON output | `autotouch columns projections` |
|
|
39
|
-
|
|
|
39
|
+
| create/manage sequence definitions directly | `autotouch sequences recipe`, then `autotouch sequences create/update/activate` |
|
|
40
|
+
| enroll leads directly into a sequence | `autotouch sequences enroll --sequence-id <SEQUENCE_ID> ...` |
|
|
41
|
+
| enroll table rows into an existing sequence | `autotouch columns recipe --type add_to_sequence`, then `autotouch columns create` + `autotouch columns run` |
|
|
42
|
+
| create or update a CRM lead | `autotouch leads recipe --type create`, then `autotouch leads create` / `autotouch leads update` |
|
|
43
|
+
| add email or phone contact info to a lead | `autotouch leads recipe --type contact_upsert`, then `autotouch leads upsert-contact-channels --lead-id <LEAD_ID> ...` |
|
|
44
|
+
| bulk update lead status or owner | `autotouch leads update-status` / `autotouch leads reassign-owner` |
|
|
45
|
+
| manage tasks directly | raw HTTP plus `docs/platform/external-workflows-api.md` |
|
|
40
46
|
| query/filter CRM leads and attached research | `autotouch leads query` then `autotouch leads research` |
|
|
41
47
|
|
|
42
48
|
### Operating model
|
|
43
49
|
|
|
44
50
|
- This file is the full CLI reference and the package readme published to PyPI.
|
|
45
51
|
- The installed package gives you CLI entrypoints and package metadata; do not assume there is a separate installed docs directory.
|
|
46
|
-
- Research-table APIs and
|
|
52
|
+
- Research-table APIs, sequence commands, and lead create/query/update operations are the primary CLI surface today; direct task management is still HTTP-first.
|
|
47
53
|
- For async operations, backend bulk-job state is authoritative; local terminal output is only a convenience layer.
|
|
48
54
|
- For staged or cost-sensitive runs, estimate first and prefer filtered scopes plus `firstN` or `run-next`.
|
|
49
55
|
|
|
@@ -129,6 +135,23 @@ Notes:
|
|
|
129
135
|
| `POST /api/tables/{table_id}/columns/{column_id}/stop` | `autotouch columns stop --table-id <TABLE_ID> --column-id <COLUMN_ID>` |
|
|
130
136
|
| `GET /api/bulk-jobs` | `autotouch jobs list --table-id <TABLE_ID> --column-id <COLUMN_ID> --limit 10` |
|
|
131
137
|
| `GET /api/bulk-jobs/{job_id}` | `autotouch jobs get --job-id <JOB_ID>` |
|
|
138
|
+
| `GET /api/sequences` | `autotouch sequences list --limit 50` |
|
|
139
|
+
| `GET /api/sequences/{sequence_id}` | `autotouch sequences get --sequence-id <SEQUENCE_ID>` |
|
|
140
|
+
| `GET /api/sequences/{sequence_id}/stats` | `autotouch sequences stats --sequence-id <SEQUENCE_ID>` |
|
|
141
|
+
| `GET /api/sequences/delivery-status` | `autotouch sequences delivery-status` |
|
|
142
|
+
| `POST /api/sequences` | `autotouch sequences create --data-file sequence.json` |
|
|
143
|
+
| `PUT /api/sequences/{sequence_id}` | `autotouch sequences update --sequence-id <SEQUENCE_ID> --data-file sequence.json` |
|
|
144
|
+
| `DELETE /api/sequences/{sequence_id}` | `autotouch sequences delete --sequence-id <SEQUENCE_ID> --yes` |
|
|
145
|
+
| `POST /api/sequences/{sequence_id}/clone` | `autotouch sequences clone --sequence-id <SEQUENCE_ID>` |
|
|
146
|
+
| `PATCH /api/sequences/{sequence_id}/status` | `autotouch sequences status --sequence-id <SEQUENCE_ID> --status ACTIVE` |
|
|
147
|
+
| `POST /api/sequences/{sequence_id}/enroll` | `autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID>` |
|
|
148
|
+
| `POST /api/sequences/{sequence_id}/enrollments/pause` | `autotouch sequences pause-enrollment --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID>` |
|
|
149
|
+
| `GET /api/leads/{lead_id}` | `autotouch leads get --lead-id <LEAD_ID>` |
|
|
150
|
+
| `POST /api/leads` | `autotouch leads create --data-file lead.json` |
|
|
151
|
+
| `PUT /api/leads/{lead_id}` | `autotouch leads update --lead-id <LEAD_ID> --data-file patch.json` |
|
|
152
|
+
| `POST /api/leads/{lead_id}/contact-channels` | `autotouch leads upsert-contact-channels --lead-id <LEAD_ID> --data-file contacts.json` |
|
|
153
|
+
| `POST /api/leads/bulk_update_status` | `autotouch leads update-status --lead-id <LEAD_ID> --status contacting` |
|
|
154
|
+
| `POST /api/leads/bulk_reassign_owner` | `autotouch leads reassign-owner --lead-id <LEAD_ID> --user-id <USER_ID>` |
|
|
132
155
|
| `POST /api/leads/query` | `autotouch leads query --filter-file lead-filter.json --limit 50` |
|
|
133
156
|
| `POST /api/leads/query/count` | `autotouch leads count --filter-file lead-filter.json` |
|
|
134
157
|
| `POST /api/leads/query/stats` | `autotouch leads stats --filter-file lead-filter.json` |
|
|
@@ -138,6 +161,15 @@ Notes:
|
|
|
138
161
|
| `GET /api/tables/{table_id}/webhook` | `autotouch webhooks get --table-id <TABLE_ID>` |
|
|
139
162
|
| `POST /api/tables/{table_id}/webhook` | `autotouch webhooks rotate --table-id <TABLE_ID>` |
|
|
140
163
|
| `POST /api/webhooks/tables/{table_id}/ingest` | `autotouch webhooks ingest --table-id <TABLE_ID> --records-file records.json --webhook-token <WEBHOOK_TOKEN>` |
|
|
164
|
+
| `GET /api/webhook-subscriptions` | `autotouch webhooks subscriptions list --limit 100` |
|
|
165
|
+
| `POST /api/webhook-subscriptions` | `autotouch webhooks subscriptions create --data-file subscription.json` |
|
|
166
|
+
| `GET /api/webhook-subscriptions/{subscription_id}` | `autotouch webhooks subscriptions get --subscription-id <SUBSCRIPTION_ID>` |
|
|
167
|
+
| `PATCH /api/webhook-subscriptions/{subscription_id}` | `autotouch webhooks subscriptions update --subscription-id <SUBSCRIPTION_ID> --data-file patch.json` |
|
|
168
|
+
| `DELETE /api/webhook-subscriptions/{subscription_id}` | `autotouch webhooks subscriptions delete --subscription-id <SUBSCRIPTION_ID>` |
|
|
169
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/pause` | `autotouch webhooks subscriptions pause --subscription-id <SUBSCRIPTION_ID>` |
|
|
170
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/resume` | `autotouch webhooks subscriptions resume --subscription-id <SUBSCRIPTION_ID>` |
|
|
171
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/rotate-secret` | `autotouch webhooks subscriptions rotate-secret --subscription-id <SUBSCRIPTION_ID>` |
|
|
172
|
+
| `POST /api/webhook-subscriptions/{subscription_id}/test` | `autotouch webhooks subscriptions test --subscription-id <SUBSCRIPTION_ID>` |
|
|
141
173
|
| `POST /api/auth/agent-bootstrap` | HTTP-only bootstrap (no direct CLI wrapper yet) |
|
|
142
174
|
|
|
143
175
|
## Delete column
|
|
@@ -153,19 +185,81 @@ CLI:
|
|
|
153
185
|
autotouch columns delete --table-id <TABLE_ID> --column-id <COLUMN_ID> --yes
|
|
154
186
|
```
|
|
155
187
|
|
|
156
|
-
##
|
|
188
|
+
## Sequence commands
|
|
157
189
|
|
|
158
|
-
|
|
190
|
+
The CLI now exposes the public Sequences endpoints under `autotouch sequences`.
|
|
191
|
+
Tasks still use raw HTTP plus `docs/platform/external-workflows-api.md`.
|
|
159
192
|
|
|
160
|
-
|
|
161
|
-
- `
|
|
162
|
-
- `
|
|
163
|
-
- `
|
|
164
|
-
- `
|
|
165
|
-
- `
|
|
166
|
-
- `
|
|
167
|
-
- `
|
|
168
|
-
- `
|
|
193
|
+
Common commands:
|
|
194
|
+
- `autotouch sequences recipe --type create --out-file sequence.json`
|
|
195
|
+
- `autotouch sequences recipe --type bulk_automated --out-file sequence.json`
|
|
196
|
+
- `autotouch sequences create --data-file sequence.json`
|
|
197
|
+
- `autotouch sequences update --sequence-id <SEQUENCE_ID> --data-file sequence.json`
|
|
198
|
+
- `autotouch sequences activate --sequence-id <SEQUENCE_ID>`
|
|
199
|
+
- `autotouch sequences pause --sequence-id <SEQUENCE_ID>`
|
|
200
|
+
- `autotouch sequences archive --sequence-id <SEQUENCE_ID>`
|
|
201
|
+
- `autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID> --wait`
|
|
202
|
+
- `autotouch sequences pause-enrollment --sequence-id <SEQUENCE_ID> --lead-id <LEAD_ID>`
|
|
203
|
+
- `autotouch sequences delivery-status`
|
|
204
|
+
- `autotouch sequences list --include-stats`
|
|
205
|
+
|
|
206
|
+
Important contract notes:
|
|
207
|
+
- Create/update via developer key still requires `sourceTableId`.
|
|
208
|
+
- Mutating sequence commands accept `--actor-user-id` for explicit actor resolution.
|
|
209
|
+
- Recommended default: personal delivery plus `EMAIL` steps with `emailSendMode=MANUAL` and `aiDraft=true`.
|
|
210
|
+
- Use `bulk_automated` only when the provider should send email automatically at scale. `aiDraft` does not apply to bulk automated email steps.
|
|
211
|
+
- Personal delivery uses the connected inbox for the enrolled owner (`assignedToUserId`, else the enrolling actor); there is no per-sequence personal sender picker yet.
|
|
212
|
+
- If that user has multiple connected personal inboxes for the same provider, the most recently updated one is used. Gmail is tried before Microsoft. Sender stays pinned after the first personal email in that enrollment.
|
|
213
|
+
- Bulk delivery uses `emailDelivery.bulkProvider`; Instantly can also narrow sending accounts via `emailDelivery.providerConfig.instantly.selectedAccounts`.
|
|
214
|
+
- `activate`, `pause`, and `archive` are convenience wrappers around `autotouch sequences status`.
|
|
215
|
+
- `autotouch sequences enroll --wait` polls `/api/bulk-jobs/{job_id}` and preserves the API response `task_id` as the bulk job id.
|
|
216
|
+
- Research-table `add_to_sequence` is still available through `autotouch columns create/update/run` and still targets an existing sequence.
|
|
217
|
+
- Real enrollment requires the target sequence to be `ACTIVE` unless direct enroll uses `reviewOnly=true`.
|
|
218
|
+
- Tasks remain HTTP-only.
|
|
219
|
+
|
|
220
|
+
AI draft outputs:
|
|
221
|
+
- Manual new email: subject + body
|
|
222
|
+
- Manual reply email: reply body
|
|
223
|
+
- LinkedIn connect: connection note
|
|
224
|
+
- LinkedIn message: message copy
|
|
225
|
+
- Call: call script
|
|
226
|
+
|
|
227
|
+
Example:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
autotouch sequences recipe --type create --out-file sequence.json
|
|
231
|
+
autotouch sequences create --data-file sequence.json
|
|
232
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Cookbooks:
|
|
236
|
+
|
|
237
|
+
1. Recommended personal AI-assisted outreach
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
autotouch sequences recipe --type create --out-file sequence.json
|
|
241
|
+
autotouch sequences create --data-file sequence.json
|
|
242
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
243
|
+
autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-ids-file lead_ids.json --wait
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Notes:
|
|
247
|
+
- `recipe --type create` is the recommended default.
|
|
248
|
+
- It starts with personal delivery, a manual AI-drafted email, then AI-drafted call and LinkedIn follow-up steps.
|
|
249
|
+
- Favorite/starred research fields are the default grounding context when explicit `fieldIds` are not provided.
|
|
250
|
+
|
|
251
|
+
2. Bulk automated email sequence
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
autotouch sequences recipe --type bulk_automated --out-file sequence.json
|
|
255
|
+
autotouch sequences create --data-file sequence.json
|
|
256
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
257
|
+
autotouch sequences enroll --sequence-id <SEQUENCE_ID> --lead-ids-file lead_ids.json --wait
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Notes:
|
|
261
|
+
- Use this when Instantly or Smartlead should send email automatically.
|
|
262
|
+
- Bulk automated email steps do not support `aiDraft`; author the templates directly in `subjectTemplate` and `bodyTemplate`.
|
|
169
263
|
|
|
170
264
|
Reference contract (actor model + manual/automated/AI-draft nuances):
|
|
171
265
|
- `docs/platform/external-workflows-api.md`
|
|
@@ -177,16 +271,25 @@ Signature controls for sequence payloads:
|
|
|
177
271
|
|
|
178
272
|
## Leads API coverage
|
|
179
273
|
|
|
180
|
-
The CLI now exposes the public read
|
|
274
|
+
The CLI now exposes the public leads read + write endpoints under `autotouch leads`.
|
|
181
275
|
|
|
182
276
|
Use this pattern:
|
|
183
277
|
|
|
184
|
-
1. `autotouch leads
|
|
185
|
-
2. `autotouch leads
|
|
186
|
-
3. `autotouch leads
|
|
278
|
+
1. `autotouch leads create` when you need to create one lead from canonical JSON input.
|
|
279
|
+
2. `autotouch leads recipe` when you want a ready-to-edit payload for create, update, or contact upsert.
|
|
280
|
+
3. `autotouch leads update` for scalar or partial lead updates.
|
|
281
|
+
4. `autotouch leads upsert-contact-channels` when you need to add or merge emails/phones without replacing the full arrays.
|
|
282
|
+
5. `autotouch leads update-status` / `autotouch leads reassign-owner` for operational bulk changes by explicit IDs or descriptor selection.
|
|
283
|
+
6. `autotouch leads query` to page through leads, apply descriptor filters, and inspect `related_tables` / `research_summary`.
|
|
284
|
+
7. `autotouch leads research` when you need actual research field values for specific lead IDs from one source table.
|
|
187
285
|
|
|
188
286
|
Important contract notes:
|
|
189
287
|
- External callers should use `POST /api/leads/query` rather than the older `GET /api/leads` list route.
|
|
288
|
+
- `autotouch leads get` is the direct single-lead lookup path.
|
|
289
|
+
- Use `autotouch leads update` for scalar lead fields only.
|
|
290
|
+
- `autotouch leads update` rejects email/phone fields and points callers to `autotouch leads upsert-contact-channels`.
|
|
291
|
+
- Contact upsert merges into canonical `email_addresses` and `phone_numbers` instead of replacing those arrays.
|
|
292
|
+
- `update-status` and `reassign-owner` accept either explicit lead IDs or descriptor selection input (`--filter-json`, `--search`, `--scope`, etc.).
|
|
190
293
|
- `autotouch leads query` accepts the same descriptor payload shape as the backend:
|
|
191
294
|
- `filter`
|
|
192
295
|
- `search`
|
|
@@ -200,6 +303,52 @@ Important contract notes:
|
|
|
200
303
|
|
|
201
304
|
Examples:
|
|
202
305
|
|
|
306
|
+
```bash
|
|
307
|
+
autotouch leads recipe --type create --out-file lead.json
|
|
308
|
+
autotouch leads create --data-file lead.json
|
|
309
|
+
autotouch leads get --lead-id <LEAD_ID>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
autotouch leads recipe --type update --out-file lead-patch.json
|
|
314
|
+
autotouch leads update \
|
|
315
|
+
--lead-id <LEAD_ID> \
|
|
316
|
+
--data-file lead-patch.json
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
autotouch leads recipe --type contact_upsert --out-file contacts.json
|
|
321
|
+
autotouch leads upsert-contact-channels \
|
|
322
|
+
--lead-id <LEAD_ID> \
|
|
323
|
+
--data-file contacts.json
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
`contacts.json` example:
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"emails": [
|
|
331
|
+
{ "address": "john@acme.com", "type": "work", "primary": true }
|
|
332
|
+
],
|
|
333
|
+
"phones": [
|
|
334
|
+
{ "number": "+14155551234", "type": "mobile", "primary": true }
|
|
335
|
+
]
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
autotouch leads update-status \
|
|
341
|
+
--filter-json '{"root":{"kind":"rule","field":"lead_status","operator":"eq","value":"new"}}' \
|
|
342
|
+
--status contacting
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
autotouch leads reassign-owner \
|
|
347
|
+
--lead-id <LEAD_ID_1> \
|
|
348
|
+
--lead-id <LEAD_ID_2> \
|
|
349
|
+
--user-id <USER_ID>
|
|
350
|
+
```
|
|
351
|
+
|
|
203
352
|
```bash
|
|
204
353
|
autotouch leads query \
|
|
205
354
|
--filter-json '{"root":{"kind":"rule","field":"status","operator":"eq","value":"new"}}' \
|
|
@@ -246,6 +395,7 @@ Important fields:
|
|
|
246
395
|
- `total_rows`: scoped row count for the run
|
|
247
396
|
- `pending_batches`: derived remaining batches
|
|
248
397
|
- `terminal_reason`: terminal classifier
|
|
398
|
+
- timing checkpoints: `enqueued_at`, `orchestrator_started_at`, `provider_started_at`, `provider_completed_at`
|
|
249
399
|
|
|
250
400
|
Terminal states:
|
|
251
401
|
- `completed`
|
|
@@ -497,11 +647,13 @@ Notes:
|
|
|
497
647
|
}
|
|
498
648
|
```
|
|
499
649
|
|
|
500
|
-
Add-to-Leads note:
|
|
650
|
+
Add-to-Leads note: `companyDomain` is required; LinkedIn is optional. Each row still needs at least one usable hard identity signal (LinkedIn, email, or phone). Names and location fields are metadata only for this flow. Run is non-billable.
|
|
501
651
|
If `companyDomain` is missing in the table, derive or enrich that domain column first, then rerun `add_to_crm`.
|
|
652
|
+
Queued lifecycle: the CLI/API accepts the run immediately, then the backend hands off `ops -> data_io` for execution.
|
|
502
653
|
|
|
503
654
|
CRM data model expectations (recommended before `add_to_crm`):
|
|
504
|
-
- Lead identity/dedupe expects `
|
|
655
|
+
- Lead identity/dedupe expects `company_domain` plus one usable hard identity signal. `linkedin_url` is a strong optional signal, not a requirement.
|
|
656
|
+
- Placeholder or malformed hard identifiers are treated as missing during research-table export. Rows without any surviving LinkedIn/email/phone signal are skipped instead of erroring.
|
|
505
657
|
- `company_domain` is required; `company_name` is only a display hint and is applied to the linked Company record when provided.
|
|
506
658
|
- Lead records link to Company via `company_id`; company names live on Company docs, not as canonical lead fields.
|
|
507
659
|
- Canonical contact fields are arrays (`email_addresses[]`, `phone_numbers[]`); top-level `email`/`mobile_number` may exist on legacy rows but should not be treated as source of truth.
|
|
@@ -558,7 +710,7 @@ Notes:
|
|
|
558
710
|
```
|
|
559
711
|
|
|
560
712
|
Notes:
|
|
561
|
-
- `sourceLeadColumn` must
|
|
713
|
+
- `sourceLeadColumn` must be the source column key that stores lead IDs (for example `add_to_leads` or another lead-id column key from `lead_finder` output), not the provider name `add_to_crm`.
|
|
562
714
|
- `sequenceId` is the target sequence workflow ID.
|
|
563
715
|
- The target sequence must already be `ACTIVE` for real enrollment. Table `add_to_sequence` runs and direct `POST /api/sequences/{id}/enroll` share the same activation check.
|
|
564
716
|
- `add_to_sequence` runs auto-attach `research_context.source_table_id` (and table name when available). Field selection stays implicit so sequence drafts/audience resolve favorites from current starred columns by default.
|
|
@@ -573,12 +725,21 @@ autotouch tables create --name "CLI Contacts"
|
|
|
573
725
|
autotouch rows import-csv --table-id <TABLE_ID> --file contacts.csv
|
|
574
726
|
autotouch columns recipe --type add_to_crm --out-file column.json
|
|
575
727
|
autotouch columns create --table-id <TABLE_ID> --data-file column.json
|
|
728
|
+
autotouch sequences recipe --type create --out-file sequence.json
|
|
729
|
+
autotouch sequences create --data-file sequence.json
|
|
730
|
+
autotouch sequences activate --sequence-id <SEQUENCE_ID>
|
|
576
731
|
autotouch columns recipe --type add_to_sequence --out-file add-to-sequence.json
|
|
577
732
|
autotouch columns create --table-id <TABLE_ID> --data-file add-to-sequence.json
|
|
578
733
|
autotouch columns run-next --table-id <TABLE_ID> --column-id <COLUMN_ID> --count 25 --filters-file filters.json --show-estimate --wait
|
|
579
734
|
autotouch jobs get --job-id <JOB_ID>
|
|
580
735
|
```
|
|
581
736
|
|
|
737
|
+
Sequence creation note:
|
|
738
|
+
- The CLI can create/update/activate sequence definitions directly with `autotouch sequences ...`.
|
|
739
|
+
- Research-table `add_to_sequence` columns and direct `autotouch sequences enroll` both target an existing sequence.
|
|
740
|
+
- Real enrollment still requires that sequence to be `ACTIVE` unless direct enroll uses `reviewOnly=true`.
|
|
741
|
+
- Tasks still use raw HTTP.
|
|
742
|
+
|
|
582
743
|
## Safe run patterns (`firstN` + `--unprocessed-only`)
|
|
583
744
|
|
|
584
745
|
Use this pattern for progressive rollouts.
|
|
@@ -49,6 +49,7 @@ scripts/migrations/20260113_set_user_permissions_user_admin.py
|
|
|
49
49
|
scripts/migrations/20260204_sync_lead_owner_from_tasks.py
|
|
50
50
|
scripts/migrations/20260303_add_webhook_subscription_collections.py
|
|
51
51
|
scripts/migrations/20260305_force_formatter_autorun_on_source_update.py
|
|
52
|
+
scripts/migrations/20260306_migrate_lead_identity_v1.py
|
|
52
53
|
scripts/migrations/migrate_org_user_credits.py
|
|
53
54
|
scripts/migrations/set_default_lead_status.py
|
|
54
55
|
scripts/migrations/update_lead_owner_from_tasks.py
|