autotouch-cli 0.2.97__tar.gz → 0.2.100__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.
Files changed (58) hide show
  1. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/PKG-INFO +34 -3
  2. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/README.md +33 -2
  3. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/webhooks.py +2 -2
  4. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/data/CLI_REFERENCE.md +10 -10
  5. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/data/cli-manifest.json +11 -8
  6. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/parser_groups.py +6 -3
  7. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/templates.py +173 -1
  8. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/workflows/registry.py +51 -0
  9. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli.egg-info/PKG-INFO +34 -3
  10. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/pyproject.toml +1 -1
  11. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/MANIFEST.in +0 -0
  12. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/__init__.py +0 -0
  13. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/cli.py +0 -0
  14. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/cli_contracts.py +0 -0
  15. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/__init__.py +0 -0
  16. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/agents.py +0 -0
  17. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/auth.py +0 -0
  18. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/cells.py +0 -0
  19. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/columns.py +0 -0
  20. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/integrations.py +0 -0
  21. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/jobs.py +0 -0
  22. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/leads.py +0 -0
  23. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/linkedin.py +0 -0
  24. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/list_build.py +0 -0
  25. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/prompts.py +0 -0
  26. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/rows.py +0 -0
  27. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/search.py +0 -0
  28. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/sequences.py +0 -0
  29. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/tables.py +0 -0
  30. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/tasks.py +0 -0
  31. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/commands/workspace_secrets.py +0 -0
  32. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/__init__.py +0 -0
  33. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/auth.py +0 -0
  34. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/config.py +0 -0
  35. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/csv_import.py +0 -0
  36. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/http.py +0 -0
  37. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/io.py +0 -0
  38. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/output.py +0 -0
  39. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/polling.py +0 -0
  40. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/run.py +0 -0
  41. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/core/validation.py +0 -0
  42. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/exceptions.py +0 -0
  43. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/mongo_status.py +0 -0
  44. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/parser.py +0 -0
  45. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/sequence_support.py +0 -0
  46. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli/workflows/__init__.py +0 -0
  47. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli.egg-info/SOURCES.txt +0 -0
  48. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli.egg-info/dependency_links.txt +0 -0
  49. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli.egg-info/entry_points.txt +0 -0
  50. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli.egg-info/requires.txt +0 -0
  51. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_cli.egg-info/top_level.txt +0 -0
  52. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_shared/__init__.py +0 -0
  53. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_shared/linkedin_contract.py +0 -0
  54. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_shared/linkedin_filters.py +0 -0
  55. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_shared/list_build_contract.py +0 -0
  56. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_shared/provider_registry.py +0 -0
  57. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/autotouch_shared/search_contract.py +0 -0
  58. {autotouch_cli-0.2.97 → autotouch_cli-0.2.100}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autotouch-cli
3
- Version: 0.2.97
3
+ Version: 0.2.100
4
4
  Summary: Autotouch Smart Table CLI
5
5
  Project-URL: Homepage, https://app.autotouch.ai
6
6
  Project-URL: Documentation, https://github.com/nicolonic/autotouch_main/tree/main/docs/research-table/reference
@@ -153,6 +153,7 @@ autotouch rows get --table-id "$TABLE_ID" --row-id "$ROW_ID" --output json
153
153
  - Create/activate sequences: `autotouch sequences recipe`, `autotouch sequences create`, `autotouch sequences activate`
154
154
  - Query leads: `autotouch leads query`
155
155
  - Find a lead by email or phone: `autotouch leads query --search '<email-or-phone>' --limit 10`
156
+ - Create table webhook ingest tokens: `autotouch webhooks rotate`, `autotouch webhooks configure-ingest`, `autotouch webhooks ingest`
156
157
 
157
158
  ## Sequence Automation Choices
158
159
 
@@ -197,7 +198,7 @@ discover -> plan -> scaffold -> run primitives -> inspect
197
198
  - `autotouch workflows scaffold --type <TYPE> --out-dir <DIR>` writes payload files and a command runbook.
198
199
  - `autotouch columns recipe` and `autotouch sequences recipe` remain leaf-level templates.
199
200
 
200
- Goal-level workflow types include `bulk-outreach`, `company-table-to-people`, `table-to-outreach`, `research-to-sequence`, `account-research`, `signal-outreach`, and `list-build-to-table`. These keep CRM, outreach providers, Autotouch Leads, and Autotouch Sequences as sources/destinations inside one organized workflow layer instead of creating one-off top-level commands.
201
+ Goal-level workflow types include `bulk-outreach`, `company-table-to-people`, `table-to-outreach`, `research-to-sequence`, `account-research`, `signal-outreach`, `website-visitors`, and `list-build-to-table`. These keep CRM, outreach providers, Autotouch Leads, Autotouch Sequences, webhooks, visitor sources, and external intent sources as sources/destinations inside one organized workflow layer instead of creating one-off top-level commands.
201
202
 
202
203
  ## Sources And Destinations
203
204
 
@@ -211,6 +212,35 @@ Use `autotouch integrations list` before wiring data movement. It returns connec
211
212
 
212
213
  Use the direction in the user's wording. "Pull from HubSpot" means `from_crm`. "Push to HubSpot" means `to_crm`. "Add these leads to this Autotouch sequence" means `to_leads` first when lead IDs do not exist, then `to_sequence`.
213
214
 
215
+ ## Table Webhook Ingest
216
+
217
+ Use table webhooks when an external source should push records directly into a Smart Table.
218
+
219
+ ```bash
220
+ WEBHOOK_TOKEN=$(autotouch webhooks rotate --table-id "$TABLE_ID" --output json --select token)
221
+
222
+ autotouch webhooks configure-ingest \
223
+ --table-id "$TABLE_ID" \
224
+ --match-rule-id linkedin_url \
225
+ --match-strategy linkedin_url \
226
+ --duplicate-mode upsert
227
+
228
+ autotouch webhooks ingest \
229
+ --table-id "$TABLE_ID" \
230
+ --webhook-token "$WEBHOOK_TOKEN" \
231
+ --records-json '{"records":[{"first_name":"Jane","last_name":"Doe","linkedin_url":"https://www.linkedin.com/in/jane-doe"}]}'
232
+ ```
233
+
234
+ For external providers, prefer the `X-Autotouch-Token: <WEBHOOK_TOKEN>` header. If the provider cannot send custom headers and only accepts one webhook URL, use the compatibility URL:
235
+
236
+ ```text
237
+ https://app.autotouch.ai/api/webhooks/tables/<TABLE_ID>/ingest?token=<WEBHOOK_TOKEN>
238
+ ```
239
+
240
+ Use query-token URLs only for no-header providers because URLs may appear in provider logs or history. Rotate the table token if it is exposed.
241
+
242
+ Webhook ingest stores the raw provider object in the `Webhook Payload` JSON column. For website visitor and external intent provider workflows, use `autotouch workflows plan --type website-visitors` first. The recommended shape is usually two starter tables: one for company-level events and one for person-level events. After a sample payload lands, use `autotouch columns projections` to split provider-specific JSON into stable columns such as `company_domain`, `linkedin_url`, `email`, `page_url`, `event_type`, and `last_seen_at`, then continue with enrichment, email finding, and the chosen destination.
243
+
214
244
  CRM round trip:
215
245
 
216
246
  ```bash
@@ -238,10 +268,11 @@ For automation or agent-driven setup, use:
238
268
  - `autotouch cli-manifest --output json` for the local machine-readable command contract
239
269
  - `autotouch cli-reference` for the shipped parser-generated reference
240
270
  - `autotouch capabilities --output json` for provider/workflow contracts
241
- - `autotouch --version` should be `0.2.97` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, research-table sequence handoff assignee config, backend-owned directional source/destination helpers, and goal-level workflow plans
271
+ - `autotouch --version` should be `0.2.100` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, research-table sequence handoff assignee config, backend-owned directional source/destination helpers, goal-level workflow plans, and website visitor/external intent webhook workflow guidance
242
272
  - `autotouch capabilities --output json --select list_builds` for documented list-build inputs such as geography IDs, company size buckets, profile language, and company IDs
243
273
  - `autotouch integrations list` and `autotouch integrations status --provider <provider>` before choosing source/destination workflows
244
274
  - `autotouch workflows plan --type bulk-outreach` and `autotouch workflows scaffold --type bulk-outreach --out-dir workflow` for goal-level workflow planning
275
+ - `autotouch workflows plan --type website-visitors` and `autotouch workflows scaffold --type website-visitors --out-dir workflow` for website visitor or external intent provider webhook workflows
245
276
  - `autotouch integrations recipe --type from_crm --provider hubspot` for CRM-to-research-table imports
246
277
  - `autotouch columns recipe --type to_crm|to_outreach|to_leads|to_sequence` for research-table destination workflows
247
278
  - `autotouch list-build inputs` and `autotouch list-build pricing` before creating durable list-build jobs
@@ -128,6 +128,7 @@ autotouch rows get --table-id "$TABLE_ID" --row-id "$ROW_ID" --output json
128
128
  - Create/activate sequences: `autotouch sequences recipe`, `autotouch sequences create`, `autotouch sequences activate`
129
129
  - Query leads: `autotouch leads query`
130
130
  - Find a lead by email or phone: `autotouch leads query --search '<email-or-phone>' --limit 10`
131
+ - Create table webhook ingest tokens: `autotouch webhooks rotate`, `autotouch webhooks configure-ingest`, `autotouch webhooks ingest`
131
132
 
132
133
  ## Sequence Automation Choices
133
134
 
@@ -172,7 +173,7 @@ discover -> plan -> scaffold -> run primitives -> inspect
172
173
  - `autotouch workflows scaffold --type <TYPE> --out-dir <DIR>` writes payload files and a command runbook.
173
174
  - `autotouch columns recipe` and `autotouch sequences recipe` remain leaf-level templates.
174
175
 
175
- Goal-level workflow types include `bulk-outreach`, `company-table-to-people`, `table-to-outreach`, `research-to-sequence`, `account-research`, `signal-outreach`, and `list-build-to-table`. These keep CRM, outreach providers, Autotouch Leads, and Autotouch Sequences as sources/destinations inside one organized workflow layer instead of creating one-off top-level commands.
176
+ Goal-level workflow types include `bulk-outreach`, `company-table-to-people`, `table-to-outreach`, `research-to-sequence`, `account-research`, `signal-outreach`, `website-visitors`, and `list-build-to-table`. These keep CRM, outreach providers, Autotouch Leads, Autotouch Sequences, webhooks, visitor sources, and external intent sources as sources/destinations inside one organized workflow layer instead of creating one-off top-level commands.
176
177
 
177
178
  ## Sources And Destinations
178
179
 
@@ -186,6 +187,35 @@ Use `autotouch integrations list` before wiring data movement. It returns connec
186
187
 
187
188
  Use the direction in the user's wording. "Pull from HubSpot" means `from_crm`. "Push to HubSpot" means `to_crm`. "Add these leads to this Autotouch sequence" means `to_leads` first when lead IDs do not exist, then `to_sequence`.
188
189
 
190
+ ## Table Webhook Ingest
191
+
192
+ Use table webhooks when an external source should push records directly into a Smart Table.
193
+
194
+ ```bash
195
+ WEBHOOK_TOKEN=$(autotouch webhooks rotate --table-id "$TABLE_ID" --output json --select token)
196
+
197
+ autotouch webhooks configure-ingest \
198
+ --table-id "$TABLE_ID" \
199
+ --match-rule-id linkedin_url \
200
+ --match-strategy linkedin_url \
201
+ --duplicate-mode upsert
202
+
203
+ autotouch webhooks ingest \
204
+ --table-id "$TABLE_ID" \
205
+ --webhook-token "$WEBHOOK_TOKEN" \
206
+ --records-json '{"records":[{"first_name":"Jane","last_name":"Doe","linkedin_url":"https://www.linkedin.com/in/jane-doe"}]}'
207
+ ```
208
+
209
+ For external providers, prefer the `X-Autotouch-Token: <WEBHOOK_TOKEN>` header. If the provider cannot send custom headers and only accepts one webhook URL, use the compatibility URL:
210
+
211
+ ```text
212
+ https://app.autotouch.ai/api/webhooks/tables/<TABLE_ID>/ingest?token=<WEBHOOK_TOKEN>
213
+ ```
214
+
215
+ Use query-token URLs only for no-header providers because URLs may appear in provider logs or history. Rotate the table token if it is exposed.
216
+
217
+ Webhook ingest stores the raw provider object in the `Webhook Payload` JSON column. For website visitor and external intent provider workflows, use `autotouch workflows plan --type website-visitors` first. The recommended shape is usually two starter tables: one for company-level events and one for person-level events. After a sample payload lands, use `autotouch columns projections` to split provider-specific JSON into stable columns such as `company_domain`, `linkedin_url`, `email`, `page_url`, `event_type`, and `last_seen_at`, then continue with enrichment, email finding, and the chosen destination.
218
+
189
219
  CRM round trip:
190
220
 
191
221
  ```bash
@@ -213,10 +243,11 @@ For automation or agent-driven setup, use:
213
243
  - `autotouch cli-manifest --output json` for the local machine-readable command contract
214
244
  - `autotouch cli-reference` for the shipped parser-generated reference
215
245
  - `autotouch capabilities --output json` for provider/workflow contracts
216
- - `autotouch --version` should be `0.2.97` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, research-table sequence handoff assignee config, backend-owned directional source/destination helpers, and goal-level workflow plans
246
+ - `autotouch --version` should be `0.2.100` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, research-table sequence handoff assignee config, backend-owned directional source/destination helpers, goal-level workflow plans, and website visitor/external intent webhook workflow guidance
217
247
  - `autotouch capabilities --output json --select list_builds` for documented list-build inputs such as geography IDs, company size buckets, profile language, and company IDs
218
248
  - `autotouch integrations list` and `autotouch integrations status --provider <provider>` before choosing source/destination workflows
219
249
  - `autotouch workflows plan --type bulk-outreach` and `autotouch workflows scaffold --type bulk-outreach --out-dir workflow` for goal-level workflow planning
250
+ - `autotouch workflows plan --type website-visitors` and `autotouch workflows scaffold --type website-visitors --out-dir workflow` for website visitor or external intent provider webhook workflows
220
251
  - `autotouch integrations recipe --type from_crm --provider hubspot` for CRM-to-research-table imports
221
252
  - `autotouch columns recipe --type to_crm|to_outreach|to_leads|to_sequence` for research-table destination workflows
222
253
  - `autotouch list-build inputs` and `autotouch list-build pricing` before creating durable list-build jobs
@@ -296,8 +296,8 @@ def cmd_webhooks_configure_ingest(args: argparse.Namespace, *, runtime: WebhookC
296
296
  merge_mode = str(getattr(args, "merge_mode", None) or "").strip()
297
297
  if match_rule_id:
298
298
  payload["match_rule_id"] = match_rule_id
299
- if match_column:
300
- payload["match_column"] = match_column
299
+ elif match_column:
300
+ payload["match_rule_id"] = match_column
301
301
  if match_strategy:
302
302
  payload["match_strategy"] = match_strategy
303
303
  if duplicate_mode:
@@ -1,6 +1,6 @@
1
1
  # Autotouch CLI Reference
2
2
 
3
- Generated from the installed parser for `autotouch-cli` `0.2.97`.
3
+ Generated from the installed parser for `autotouch-cli` `0.2.100`.
4
4
  Manifest schema version: `2`.
5
5
 
6
6
  ## Output Modes
@@ -5506,8 +5506,8 @@ Persist ingest identity settings on a table's webhook config
5506
5506
  [--verbose]`
5507
5507
  - Options:
5508
5508
  - `--table-id` (required; kind=string)
5509
- - `--match-rule-id` (kind=string): Use a pre-configured table identity rule by ID
5510
- - `--match-column` (kind=string): Column key to match on (when no rule-id)
5509
+ - `--match-rule-id` (kind=string): Identity rule id or column key to match on
5510
+ - `--match-column` (kind=string): Column key to match on; alias for --match-rule-id when no rule id is set
5511
5511
  - `--match-strategy` (kind=string; choices=email,domain,linkedin_url,external_id,exact_text): Normalisation strategy for the match column
5512
5512
  - `--duplicate-mode` (kind=string; choices=allow,skip,upsert; default=upsert): Duplicate handling: allow / skip / upsert (default: upsert)
5513
5513
  - `--merge-mode` (kind=string; choices=fill_empty,overwrite_mapped; default=fill_empty): Cell merge strategy when upserting (default: fill_empty)
@@ -5650,7 +5650,7 @@ Ingest records using table webhook token
5650
5650
  --json-pointer JSON_POINTER] [--verbose]`
5651
5651
  - Options:
5652
5652
  - `--table-id` (required; kind=string)
5653
- - `--webhook-token` (kind=string; sensitive): x-autotouch-token (or AUTOTOUCH_WEBHOOK_TOKEN)
5653
+ - `--webhook-token` (kind=string; sensitive): Table webhook token for CLI/header auth; no-header providers may use the ingest URL with ?token=<WEBHOOK_TOKEN>
5654
5654
  - `--records-json` (kind=json; input=json): Object, list, or {records:[...]} payload JSON
5655
5655
  - `--records-file` (kind=file; input=file): Path to JSON file containing records payload
5656
5656
  - `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
@@ -6097,13 +6097,13 @@ Plan the workflow before creating files or running side effects. Use this to cho
6097
6097
  - Output modes: `json, ndjson, human`
6098
6098
  - Example:
6099
6099
  - `autotouch workflows plan [-h]
6100
- --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table}
6100
+ --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table}
6101
6101
  [--out-file OUT_FILE]
6102
6102
  [--output {json,ndjson,human}] [--compact]
6103
6103
  [--select SELECT |
6104
6104
  --json-pointer JSON_POINTER]`
6105
6105
  - Options:
6106
- - `--type` (required; kind=string; choices=bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table): Workflow blueprint type
6106
+ - `--type` (required; kind=string; choices=bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table): Workflow blueprint type
6107
6107
  - `--out-file` (kind=file; input=file): Save raw workflow payload to file
6108
6108
  - `--output` (kind=string; choices=json,ndjson,human; default=json): Output mode
6109
6109
  - `--compact` (kind=boolean; when omitted=False; when present=True): Print compact JSON
@@ -6121,13 +6121,13 @@ Alias for `workflows plan`
6121
6121
  - Output modes: `json, ndjson, human`
6122
6122
  - Example:
6123
6123
  - `autotouch workflows recipe [-h]
6124
- --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table}
6124
+ --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table}
6125
6125
  [--out-file OUT_FILE]
6126
6126
  [--output {json,ndjson,human}] [--compact]
6127
6127
  [--select SELECT |
6128
6128
  --json-pointer JSON_POINTER]`
6129
6129
  - Options:
6130
- - `--type` (required; kind=string; choices=bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table): Workflow blueprint type
6130
+ - `--type` (required; kind=string; choices=bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table): Workflow blueprint type
6131
6131
  - `--out-file` (kind=file; input=file): Save raw workflow payload to file
6132
6132
  - `--output` (kind=string; choices=json,ndjson,human; default=json): Output mode
6133
6133
  - `--compact` (kind=boolean; when omitted=False; when present=True): Print compact JSON
@@ -6145,13 +6145,13 @@ Emit ordered workflow files and commands for a blueprint
6145
6145
  - Output modes: `json, ndjson, human`
6146
6146
  - Example:
6147
6147
  - `autotouch workflows scaffold [-h]
6148
- --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table}
6148
+ --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table}
6149
6149
  [--out-dir OUT_DIR]
6150
6150
  [--output {json,ndjson,human}] [--compact]
6151
6151
  [--select SELECT |
6152
6152
  --json-pointer JSON_POINTER]`
6153
6153
  - Options:
6154
- - `--type` (required; kind=string; choices=bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table): Workflow blueprint type
6154
+ - `--type` (required; kind=string; choices=bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table): Workflow blueprint type
6155
6155
  - `--out-dir` (kind=string): Directory to save scaffold payload files
6156
6156
  - `--output` (kind=string; choices=json,ndjson,human; default=json): Output mode
6157
6157
  - `--compact` (kind=boolean; when omitted=False; when present=True): Print compact JSON
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.2.97",
2
+ "version": "0.2.100",
3
3
  "manifest_schema_version": 2,
4
4
  "entry_points": {
5
5
  "autotouch": "autotouch_cli.cli:main",
@@ -9135,6 +9135,7 @@
9135
9135
  "research-to-sequence",
9136
9136
  "account-research",
9137
9137
  "signal-outreach",
9138
+ "website-visitors",
9138
9139
  "list-build-to-table"
9139
9140
  ],
9140
9141
  "flags": [
@@ -9241,7 +9242,7 @@
9241
9242
  },
9242
9243
  "availability": null,
9243
9244
  "examples": [
9244
- "autotouch workflows plan [-h]\n --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table}\n [--out-file OUT_FILE]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT |\n --json-pointer JSON_POINTER]"
9245
+ "autotouch workflows plan [-h]\n --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table}\n [--out-file OUT_FILE]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT |\n --json-pointer JSON_POINTER]"
9245
9246
  ],
9246
9247
  "stability": "stable",
9247
9248
  "handler": "_fn"
@@ -9275,6 +9276,7 @@
9275
9276
  "research-to-sequence",
9276
9277
  "account-research",
9277
9278
  "signal-outreach",
9279
+ "website-visitors",
9278
9280
  "list-build-to-table"
9279
9281
  ],
9280
9282
  "flags": [
@@ -9381,7 +9383,7 @@
9381
9383
  },
9382
9384
  "availability": null,
9383
9385
  "examples": [
9384
- "autotouch workflows recipe [-h]\n --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table}\n [--out-file OUT_FILE]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT |\n --json-pointer JSON_POINTER]"
9386
+ "autotouch workflows recipe [-h]\n --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table}\n [--out-file OUT_FILE]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT |\n --json-pointer JSON_POINTER]"
9385
9387
  ],
9386
9388
  "stability": "stable",
9387
9389
  "handler": "_fn"
@@ -9415,6 +9417,7 @@
9415
9417
  "research-to-sequence",
9416
9418
  "account-research",
9417
9419
  "signal-outreach",
9420
+ "website-visitors",
9418
9421
  "list-build-to-table"
9419
9422
  ],
9420
9423
  "flags": [
@@ -9520,7 +9523,7 @@
9520
9523
  },
9521
9524
  "availability": null,
9522
9525
  "examples": [
9523
- "autotouch workflows scaffold [-h]\n --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,list-build-to-table}\n [--out-dir OUT_DIR]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT |\n --json-pointer JSON_POINTER]"
9526
+ "autotouch workflows scaffold [-h]\n --type {bulk-outreach,company-table-to-people,table-to-outreach,research-to-sequence,account-research,signal-outreach,website-visitors,list-build-to-table}\n [--out-dir OUT_DIR]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT |\n --json-pointer JSON_POINTER]"
9524
9527
  ],
9525
9528
  "stability": "stable",
9526
9529
  "handler": "_fn"
@@ -30696,7 +30699,7 @@
30696
30699
  {
30697
30700
  "dest": "webhook_token",
30698
30701
  "required": false,
30699
- "help": "x-autotouch-token (or AUTOTOUCH_WEBHOOK_TOKEN)",
30702
+ "help": "Table webhook token for CLI/header auth; no-header providers may use the ingest URL with ?token=<WEBHOOK_TOKEN>",
30700
30703
  "kind": "string",
30701
30704
  "action": "store",
30702
30705
  "sensitive": true,
@@ -30917,7 +30920,7 @@
30917
30920
  {
30918
30921
  "dest": "match_rule_id",
30919
30922
  "required": false,
30920
- "help": "Use a pre-configured table identity rule by ID",
30923
+ "help": "Identity rule id or column key to match on",
30921
30924
  "kind": "string",
30922
30925
  "action": "store",
30923
30926
  "flags": [
@@ -30928,7 +30931,7 @@
30928
30931
  {
30929
30932
  "dest": "match_column",
30930
30933
  "required": false,
30931
- "help": "Column key to match on (when no rule-id)",
30934
+ "help": "Column key to match on; alias for --match-rule-id when no rule id is set",
30932
30935
  "kind": "string",
30933
30936
  "action": "store",
30934
30937
  "flags": [
@@ -39804,4 +39807,4 @@
39804
39807
  "handler": "cmd_sop"
39805
39808
  }
39806
39809
  }
39807
- }
39810
+ }
@@ -183,7 +183,10 @@ def add_webhooks_subcommands(
183
183
 
184
184
  pwhi = wh_sub.add_parser("ingest", help="Ingest records using table webhook token")
185
185
  pwhi.add_argument("--table-id", required=True)
186
- pwhi.add_argument("--webhook-token", help="x-autotouch-token (or AUTOTOUCH_WEBHOOK_TOKEN)")
186
+ pwhi.add_argument(
187
+ "--webhook-token",
188
+ help="Table webhook token for CLI/header auth; no-header providers may use the ingest URL with ?token=<WEBHOOK_TOKEN>",
189
+ )
187
190
  pwhi.add_argument("--records-json", help="Object, list, or {records:[...]} payload JSON")
188
191
  pwhi.add_argument("--records-file", help="Path to JSON file containing records payload")
189
192
  add_api_common_arguments(pwhi)
@@ -195,8 +198,8 @@ def add_webhooks_subcommands(
195
198
 
196
199
  pwhci = wh_sub.add_parser("configure-ingest", help="Persist ingest identity settings on a table's webhook config")
197
200
  pwhci.add_argument("--table-id", required=True)
198
- pwhci.add_argument("--match-rule-id", default=None, help="Use a pre-configured table identity rule by ID")
199
- pwhci.add_argument("--match-column", default=None, help="Column key to match on (when no rule-id)")
201
+ pwhci.add_argument("--match-rule-id", default=None, help="Identity rule id or column key to match on")
202
+ pwhci.add_argument("--match-column", default=None, help="Column key to match on; alias for --match-rule-id when no rule id is set")
200
203
  pwhci.add_argument(
201
204
  "--match-strategy",
202
205
  choices=_MATCH_STRATEGIES,
@@ -241,6 +241,28 @@ _CONTACT_ITEM_FIELDS: List[Tuple[str, str]] = [
241
241
  ("company_domain", "Company Domain"),
242
242
  ("linkedin_url", "LinkedIn URL"),
243
243
  ]
244
+ _WEBSITE_VISITOR_COMPANY_PROJECTION_FIELDS: List[Tuple[str, str, str, str]] = [
245
+ ("company_domain", "Company Domain", "company.domain", "text"),
246
+ ("company_name", "Company Name", "company.name", "text"),
247
+ ("provider_company_id", "Provider Company ID", "company.id", "text"),
248
+ ("event_type", "Event Type", "event.type", "text"),
249
+ ("page_url", "Page URL", "event.url", "url"),
250
+ ("last_seen_at", "Last Seen At", "event.timestamp", "date"),
251
+ ]
252
+ _WEBSITE_VISITOR_PERSON_PROJECTION_FIELDS: List[Tuple[str, str, str, str]] = [
253
+ ("first_name", "First Name", "person.first_name", "text"),
254
+ ("last_name", "Last Name", "person.last_name", "text"),
255
+ ("full_name", "Full Name", "person.name", "text"),
256
+ ("title", "Title", "person.title", "text"),
257
+ ("linkedin_url", "LinkedIn URL", "person.linkedin_url", "url"),
258
+ ("email", "Email", "person.email", "email"),
259
+ ("company_domain", "Company Domain", "company.domain", "text"),
260
+ ("company_name", "Company Name", "company.name", "text"),
261
+ ("provider_person_id", "Provider Person ID", "person.id", "text"),
262
+ ("event_type", "Event Type", "event.type", "text"),
263
+ ("page_url", "Page URL", "event.url", "url"),
264
+ ("last_seen_at", "Last Seen At", "event.timestamp", "date"),
265
+ ]
244
266
 
245
267
 
246
268
  def _build_column_recipe_catalog() -> Tuple[Dict[str, Dict[str, Any]], Dict[str, List[str]]]:
@@ -1032,6 +1054,12 @@ WEBHOOK_RECIPES: Dict[str, Dict[str, Any]] = {
1032
1054
  WEBHOOK_RECIPE_NOTES: Dict[str, List[str]] = {
1033
1055
  "ingest": [
1034
1056
  "Use this with webhooks ingest when writing rows through a table webhook token.",
1057
+ "Recommended auth for external providers is the X-Autotouch-Token header.",
1058
+ "For providers that cannot send custom headers, use the compatibility URL https://app.autotouch.ai/api/webhooks/tables/<TABLE_ID>/ingest?token=<WEBHOOK_TOKEN>.",
1059
+ "Use query-token URLs only for no-header providers because URLs may appear in provider logs or history; rotate the table token if it is exposed.",
1060
+ "Webhook ingest stores the raw provider object in the Webhook Payload JSON column. Use autotouch columns projections to split provider-specific JSON into stable columns for mapping/filtering.",
1061
+ "Company-level and person-level external events usually belong in separate starter tables because they use different identity fields and downstream steps.",
1062
+ "Configure ingest identity before going live when the provider sends a flat identity field, for example: autotouch webhooks configure-ingest --table-id <TABLE_ID> --match-rule-id linkedin_url --match-strategy linkedin_url --duplicate-mode upsert.",
1035
1063
  ],
1036
1064
  "subscription_create": [
1037
1065
  "retryPolicy is optional, but including it makes the request contract explicit for agents.",
@@ -1396,6 +1424,21 @@ def _projection_payload(*, source_column_id: str, fields: List[Tuple[str, str]])
1396
1424
  }
1397
1425
 
1398
1426
 
1427
+ def _visitor_projection_payload(*, source_column_id: str, fields: List[Tuple[str, str, str, str]]) -> Dict[str, Any]:
1428
+ return {
1429
+ "items": [
1430
+ {
1431
+ "key": field_key,
1432
+ "label": field_label,
1433
+ "sourceColumnId": source_column_id,
1434
+ "path": json_path,
1435
+ "dataType": data_type,
1436
+ }
1437
+ for field_key, field_label, json_path, data_type in fields
1438
+ ]
1439
+ }
1440
+
1441
+
1399
1442
  def _single_buyer_instructions(*, include_company_domain: bool) -> str:
1400
1443
  keys = ["first_name", "last_name", "title", "company_name", "company_website"]
1401
1444
  if include_company_domain:
@@ -1841,6 +1884,134 @@ def _workflow_scaffold_signal_outreach() -> Dict[str, Any]:
1841
1884
  }
1842
1885
 
1843
1886
 
1887
+ def _workflow_scaffold_website_visitors() -> Dict[str, Any]:
1888
+ artifacts = [
1889
+ _workflow_artifact(
1890
+ step=1,
1891
+ provider="json_projections",
1892
+ filename="01-company-event-projections.json",
1893
+ payload=_visitor_projection_payload(
1894
+ source_column_id="<COMPANY_WEBHOOK_PAYLOAD_COLUMN_ID>",
1895
+ fields=_WEBSITE_VISITOR_COMPANY_PROJECTION_FIELDS,
1896
+ ),
1897
+ table_scope="company_event_table",
1898
+ kind="projection_payload",
1899
+ notes=[
1900
+ "Edit path values to match the provider payload. These defaults assume company.domain, company.name, and event.* paths.",
1901
+ "Use after a sample webhook row has created/populated the Webhook Payload JSON column.",
1902
+ ],
1903
+ ),
1904
+ _workflow_artifact(
1905
+ step=2,
1906
+ provider="json_projections",
1907
+ filename="02-person-event-projections.json",
1908
+ payload=_visitor_projection_payload(
1909
+ source_column_id="<PERSON_WEBHOOK_PAYLOAD_COLUMN_ID>",
1910
+ fields=_WEBSITE_VISITOR_PERSON_PROJECTION_FIELDS,
1911
+ ),
1912
+ table_scope="person_event_table",
1913
+ kind="projection_payload",
1914
+ notes=[
1915
+ "Edit path values to match the provider payload. These defaults assume person.*, company.*, and event.* paths.",
1916
+ "Person event tables usually dedupe on email, linkedin_url, or provider_person_id.",
1917
+ ],
1918
+ ),
1919
+ _workflow_artifact(
1920
+ step=3,
1921
+ provider="llm",
1922
+ recipe_type="llm_enrichment",
1923
+ filename="03-company-event-find-people.json",
1924
+ payload=_items_agent_payload(),
1925
+ table_scope="company_event_table",
1926
+ notes=[
1927
+ "Use this for company-level visitor events that do not already include a person.",
1928
+ "Adjust instructions/persona before creating the column.",
1929
+ ],
1930
+ ),
1931
+ _workflow_artifact(
1932
+ step=4,
1933
+ provider="sync_to_table",
1934
+ recipe_type="sync_to_table",
1935
+ filename="04-sync-visitor-contacts-to-table.json",
1936
+ payload=_items_sync_to_table_payload(),
1937
+ table_scope="company_event_table",
1938
+ notes=[
1939
+ "Create a contacts/person table first, then set destinationTableId and listSourceColumnId.",
1940
+ ],
1941
+ ),
1942
+ _workflow_artifact(
1943
+ step=5,
1944
+ provider="email_finder",
1945
+ recipe_type="email_finder",
1946
+ filename="05-email-finder.json",
1947
+ payload=_recipe_payload("email_finder"),
1948
+ table_scope="person_or_contacts_table",
1949
+ notes=["Use on the person event table or the contacts table created from company events."],
1950
+ ),
1951
+ _workflow_artifact(
1952
+ step=6,
1953
+ provider="to_outreach",
1954
+ recipe_type="to_outreach",
1955
+ filename="06-push-to-outreach.json",
1956
+ payload=_recipe_payload("to_outreach"),
1957
+ table_scope="person_or_contacts_table",
1958
+ notes=["Optional destination. Set outreachProvider, campaignId, emailColumnKey, and variableMappings."],
1959
+ ),
1960
+ _workflow_artifact(
1961
+ step=7,
1962
+ provider="to_leads",
1963
+ recipe_type="to_leads",
1964
+ filename="07-sync-to-leads.json",
1965
+ payload=_items_sync_to_leads_payload(),
1966
+ table_scope="person_or_contacts_table",
1967
+ notes=["Optional destination step before Autotouch Sequence enrollment."],
1968
+ ),
1969
+ _workflow_artifact(
1970
+ step=8,
1971
+ provider="to_sequence",
1972
+ recipe_type="to_sequence",
1973
+ filename="08-add-to-sequence.json",
1974
+ payload=_to_sequence_payload(source_lead_column="sync_to_leads"),
1975
+ table_scope="person_or_contacts_table",
1976
+ notes=[
1977
+ "Optional destination. Set sequenceId and assignedToUserId before creating the column.",
1978
+ "Use manual AI-draft review by default for researched website visitor or external intent campaigns.",
1979
+ ],
1980
+ ),
1981
+ ]
1982
+ return {
1983
+ "artifacts": artifacts,
1984
+ "commands": [
1985
+ "autotouch tables create --name 'Website Visitor Companies' --output json",
1986
+ "autotouch tables create --name 'Website Visitor People' --output json",
1987
+ "autotouch webhooks rotate --table-id <COMPANY_EVENTS_TABLE_ID> --output json",
1988
+ "autotouch webhooks rotate --table-id <PERSON_EVENTS_TABLE_ID> --output json",
1989
+ "autotouch webhooks recipe --type ingest --output json",
1990
+ "autotouch webhooks configure-ingest --table-id <COMPANY_EVENTS_TABLE_ID> --match-rule-id company_domain --match-strategy domain --duplicate-mode upsert --merge-mode fill_empty",
1991
+ "autotouch webhooks configure-ingest --table-id <PERSON_EVENTS_TABLE_ID> --match-rule-id email --match-strategy email --duplicate-mode upsert --merge-mode fill_empty",
1992
+ "autotouch columns projections --table-id <COMPANY_EVENTS_TABLE_ID> --after-column-id <COMPANY_WEBHOOK_PAYLOAD_COLUMN_ID> --data-file 01-company-event-projections.json",
1993
+ "autotouch columns projections --table-id <PERSON_EVENTS_TABLE_ID> --after-column-id <PERSON_WEBHOOK_PAYLOAD_COLUMN_ID> --data-file 02-person-event-projections.json",
1994
+ "autotouch columns create --table-id <COMPANY_EVENTS_TABLE_ID> --data-file 03-company-event-find-people.json",
1995
+ "autotouch columns run-next --table-id <COMPANY_EVENTS_TABLE_ID> --column-id <CONTACT_ITEMS_COLUMN_ID> --count 25 --show-estimate --wait --output json",
1996
+ "autotouch tables create --name '<VISITOR_CONTACTS_TABLE_NAME>' --output json",
1997
+ "autotouch columns create --table-id <COMPANY_EVENTS_TABLE_ID> --data-file 04-sync-visitor-contacts-to-table.json",
1998
+ "autotouch columns run --table-id <COMPANY_EVENTS_TABLE_ID> --column-id <SYNC_CONTACTS_TO_TABLE_COLUMN_ID> --wait --output json",
1999
+ "autotouch columns create --table-id <PERSON_OR_CONTACTS_TABLE_ID> --data-file 05-email-finder.json",
2000
+ "autotouch columns run-next --table-id <PERSON_OR_CONTACTS_TABLE_ID> --column-id <EMAIL_FINDER_COLUMN_ID> --count 25 --show-estimate --wait --output json",
2001
+ "autotouch integrations list --select destinations --output json",
2002
+ "autotouch workflows scaffold --type table-to-outreach --out-dir outreach-handoff",
2003
+ "autotouch workflows scaffold --type research-to-sequence --out-dir sequence-handoff",
2004
+ ],
2005
+ "notes": [
2006
+ "Keep company-level and person-level webhook events in separate starter tables unless the provider has one clean event shape.",
2007
+ "Webhook ingest stores the raw provider object in Webhook Payload. Use columns projections to split that JSON into stable columns before downstream mapping/filtering.",
2008
+ "For ingest-time upsert, the identity field must be present as a mapped flat field on the incoming row. If the provider sends only nested JSON, split a sample first and configure the provider or payload mapping to send a flat identity field such as company_domain, email, or linkedin_url.",
2009
+ "Header auth is preferred. Use the query-token URL only for providers that cannot send custom headers.",
2010
+ "This scaffold stops at common handoff points; use the destination-specific scaffolds for provider upload or Autotouch Sequence enrollment.",
2011
+ ],
2012
+ }
2013
+
2014
+
1844
2015
  def _workflow_scaffold_list_build_to_table() -> Dict[str, Any]:
1845
2016
  return {
1846
2017
  "artifacts": [],
@@ -2091,6 +2262,7 @@ def _workflow_scaffold_bundle(workflow_type: str) -> Dict[str, Any]:
2091
2262
  "research-to-sequence": _workflow_scaffold_research_to_sequence,
2092
2263
  "account-research": _workflow_scaffold_account_research,
2093
2264
  "signal-outreach": _workflow_scaffold_signal_outreach,
2265
+ "website-visitors": _workflow_scaffold_website_visitors,
2094
2266
  "list-build-to-table": _workflow_scaffold_list_build_to_table,
2095
2267
  "lead_finder_to_sequence": _workflow_scaffold_lead_finder_to_sequence,
2096
2268
  "llm_items_to_contacts_then_sequence": _workflow_scaffold_items_to_contacts_then_sequence,
@@ -2425,7 +2597,7 @@ def emit_webhooks_recipe(args: argparse.Namespace, runtime: TemplateRuntime) ->
2425
2597
  payload_getter=_webhook_recipe_payload,
2426
2598
  notes_lookup=WEBHOOK_RECIPE_NOTES,
2427
2599
  usage_lookup={
2428
- "ingest": "autotouch webhooks ingest --table-id <TABLE_ID> --records-file <payload.json>",
2600
+ "ingest": "autotouch webhooks ingest --table-id <TABLE_ID> --webhook-token <WEBHOOK_TOKEN> --records-file <payload.json>",
2429
2601
  "subscription_create": "autotouch webhooks subscriptions create --data-file <payload.json>",
2430
2602
  "subscription_update": "autotouch webhooks subscriptions update --subscription-id <SUB_ID> --data-file <payload.json>",
2431
2603
  "subscription_test": "autotouch webhooks subscriptions test --subscription-id <SUB_ID> --data-file <payload.json>",
@@ -138,6 +138,57 @@ _GOAL_WORKFLOW_BLUEPRINTS: Dict[str, Dict[str, Any]] = {
138
138
  {"provider": "to_outreach", "purpose": "optionally push qualified table rows to Instantly or Smartlead"},
139
139
  ],
140
140
  },
141
+ "website-visitors": {
142
+ "goal": "Ingest website visitor or external intent provider webhooks, split payload JSON into usable columns, then enrich and route company/person intent to outreach destinations.",
143
+ "use_case": "website_visitor_external_intent_webhook",
144
+ "supported_starting_points": ["website_visitor_provider", "external_intent_provider_webhook", "company_event", "person_event"],
145
+ "recommended_when": [
146
+ "an external provider sends website visitor, account intent, or person intent events by webhook",
147
+ "the workflow should start from raw provider payloads and turn them into Smart Table columns before automation",
148
+ "company-level events and person-level events may arrive as different event types or payload shapes",
149
+ ],
150
+ "default_safety": {
151
+ "separate_event_grain_tables": True,
152
+ "header_auth_preferred": True,
153
+ "query_token_only_for_no_header_providers": True,
154
+ "sample_first": True,
155
+ "dedupe_before_downstream_runs": True,
156
+ },
157
+ "event_grain": {
158
+ "company_events": {
159
+ "starter_table": "Website Visitor Companies",
160
+ "identity_preference": ["company_domain", "provider_company_id"],
161
+ "dedupe": "match company_domain with domain strategy when available; otherwise match provider_company_id with external_id strategy",
162
+ "next_steps": ["split webhook_payload JSON", "enrich company", "find people", "find email", "route destination"],
163
+ },
164
+ "person_events": {
165
+ "starter_table": "Website Visitor People",
166
+ "identity_preference": ["email", "linkedin_url", "provider_person_id"],
167
+ "dedupe": "match email when available; otherwise linkedin_url; otherwise provider_person_id with external_id strategy",
168
+ "next_steps": ["split webhook_payload JSON", "find or verify email if missing", "route destination"],
169
+ },
170
+ },
171
+ "docs": {
172
+ "webhook_ingest": "autotouch webhooks recipe --type ingest",
173
+ "json_split": "autotouch columns projections --help",
174
+ "json_split_concept": "docs/research-table/concepts/projection-columns.md",
175
+ "destinations": "autotouch integrations list --select destinations",
176
+ },
177
+ "steps": [
178
+ {"provider": "webhooks", "purpose": "create a table webhook token and ingest raw provider payloads"},
179
+ {"provider": "webhooks.configure-ingest", "purpose": "persist identity/upsert behavior separately for company and person event tables"},
180
+ {"provider": "columns.projections", "purpose": "split webhook_payload JSON into stable columns such as company_domain, linkedin_url, email, page_url, event_type, and last_seen_at"},
181
+ {"provider": "llm_enrichment", "purpose": "for company events, enrich the account or find likely people when the event has no person"},
182
+ {"provider": "email_finder", "purpose": "find or verify email addresses before outreach destinations"},
183
+ {"provider": "to_outreach|to_leads|to_sequence|to_crm", "purpose": "route qualified rows to the user's chosen destination"},
184
+ ],
185
+ "inspect_commands": [
186
+ "autotouch webhooks get --table-id <TABLE_ID> --output json",
187
+ "autotouch rows list --table-id <TABLE_ID> --page-size 5 --output json",
188
+ "autotouch cells get --table-id <TABLE_ID> --row-id <ROW_ID> --column-id <COLUMN_ID> --output json",
189
+ "autotouch jobs get --job-id <JOB_ID> --output json",
190
+ ],
191
+ },
141
192
  "list-build-to-table": {
142
193
  "goal": "Build a company or lead list and land the results in a Smart Table for enrichment.",
143
194
  "use_case": "new_list_acquisition",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autotouch-cli
3
- Version: 0.2.97
3
+ Version: 0.2.100
4
4
  Summary: Autotouch Smart Table CLI
5
5
  Project-URL: Homepage, https://app.autotouch.ai
6
6
  Project-URL: Documentation, https://github.com/nicolonic/autotouch_main/tree/main/docs/research-table/reference
@@ -153,6 +153,7 @@ autotouch rows get --table-id "$TABLE_ID" --row-id "$ROW_ID" --output json
153
153
  - Create/activate sequences: `autotouch sequences recipe`, `autotouch sequences create`, `autotouch sequences activate`
154
154
  - Query leads: `autotouch leads query`
155
155
  - Find a lead by email or phone: `autotouch leads query --search '<email-or-phone>' --limit 10`
156
+ - Create table webhook ingest tokens: `autotouch webhooks rotate`, `autotouch webhooks configure-ingest`, `autotouch webhooks ingest`
156
157
 
157
158
  ## Sequence Automation Choices
158
159
 
@@ -197,7 +198,7 @@ discover -> plan -> scaffold -> run primitives -> inspect
197
198
  - `autotouch workflows scaffold --type <TYPE> --out-dir <DIR>` writes payload files and a command runbook.
198
199
  - `autotouch columns recipe` and `autotouch sequences recipe` remain leaf-level templates.
199
200
 
200
- Goal-level workflow types include `bulk-outreach`, `company-table-to-people`, `table-to-outreach`, `research-to-sequence`, `account-research`, `signal-outreach`, and `list-build-to-table`. These keep CRM, outreach providers, Autotouch Leads, and Autotouch Sequences as sources/destinations inside one organized workflow layer instead of creating one-off top-level commands.
201
+ Goal-level workflow types include `bulk-outreach`, `company-table-to-people`, `table-to-outreach`, `research-to-sequence`, `account-research`, `signal-outreach`, `website-visitors`, and `list-build-to-table`. These keep CRM, outreach providers, Autotouch Leads, Autotouch Sequences, webhooks, visitor sources, and external intent sources as sources/destinations inside one organized workflow layer instead of creating one-off top-level commands.
201
202
 
202
203
  ## Sources And Destinations
203
204
 
@@ -211,6 +212,35 @@ Use `autotouch integrations list` before wiring data movement. It returns connec
211
212
 
212
213
  Use the direction in the user's wording. "Pull from HubSpot" means `from_crm`. "Push to HubSpot" means `to_crm`. "Add these leads to this Autotouch sequence" means `to_leads` first when lead IDs do not exist, then `to_sequence`.
213
214
 
215
+ ## Table Webhook Ingest
216
+
217
+ Use table webhooks when an external source should push records directly into a Smart Table.
218
+
219
+ ```bash
220
+ WEBHOOK_TOKEN=$(autotouch webhooks rotate --table-id "$TABLE_ID" --output json --select token)
221
+
222
+ autotouch webhooks configure-ingest \
223
+ --table-id "$TABLE_ID" \
224
+ --match-rule-id linkedin_url \
225
+ --match-strategy linkedin_url \
226
+ --duplicate-mode upsert
227
+
228
+ autotouch webhooks ingest \
229
+ --table-id "$TABLE_ID" \
230
+ --webhook-token "$WEBHOOK_TOKEN" \
231
+ --records-json '{"records":[{"first_name":"Jane","last_name":"Doe","linkedin_url":"https://www.linkedin.com/in/jane-doe"}]}'
232
+ ```
233
+
234
+ For external providers, prefer the `X-Autotouch-Token: <WEBHOOK_TOKEN>` header. If the provider cannot send custom headers and only accepts one webhook URL, use the compatibility URL:
235
+
236
+ ```text
237
+ https://app.autotouch.ai/api/webhooks/tables/<TABLE_ID>/ingest?token=<WEBHOOK_TOKEN>
238
+ ```
239
+
240
+ Use query-token URLs only for no-header providers because URLs may appear in provider logs or history. Rotate the table token if it is exposed.
241
+
242
+ Webhook ingest stores the raw provider object in the `Webhook Payload` JSON column. For website visitor and external intent provider workflows, use `autotouch workflows plan --type website-visitors` first. The recommended shape is usually two starter tables: one for company-level events and one for person-level events. After a sample payload lands, use `autotouch columns projections` to split provider-specific JSON into stable columns such as `company_domain`, `linkedin_url`, `email`, `page_url`, `event_type`, and `last_seen_at`, then continue with enrichment, email finding, and the chosen destination.
243
+
214
244
  CRM round trip:
215
245
 
216
246
  ```bash
@@ -238,10 +268,11 @@ For automation or agent-driven setup, use:
238
268
  - `autotouch cli-manifest --output json` for the local machine-readable command contract
239
269
  - `autotouch cli-reference` for the shipped parser-generated reference
240
270
  - `autotouch capabilities --output json` for provider/workflow contracts
241
- - `autotouch --version` should be `0.2.97` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, research-table sequence handoff assignee config, backend-owned directional source/destination helpers, and goal-level workflow plans
271
+ - `autotouch --version` should be `0.2.100` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, research-table sequence handoff assignee config, backend-owned directional source/destination helpers, goal-level workflow plans, and website visitor/external intent webhook workflow guidance
242
272
  - `autotouch capabilities --output json --select list_builds` for documented list-build inputs such as geography IDs, company size buckets, profile language, and company IDs
243
273
  - `autotouch integrations list` and `autotouch integrations status --provider <provider>` before choosing source/destination workflows
244
274
  - `autotouch workflows plan --type bulk-outreach` and `autotouch workflows scaffold --type bulk-outreach --out-dir workflow` for goal-level workflow planning
275
+ - `autotouch workflows plan --type website-visitors` and `autotouch workflows scaffold --type website-visitors --out-dir workflow` for website visitor or external intent provider webhook workflows
245
276
  - `autotouch integrations recipe --type from_crm --provider hubspot` for CRM-to-research-table imports
246
277
  - `autotouch columns recipe --type to_crm|to_outreach|to_leads|to_sequence` for research-table destination workflows
247
278
  - `autotouch list-build inputs` and `autotouch list-build pricing` before creating durable list-build jobs
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "autotouch-cli"
7
- version = "0.2.97"
7
+ version = "0.2.100"
8
8
  description = "Autotouch Smart Table CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"