autotouch-cli 0.2.72__tar.gz → 0.2.74__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.72 → autotouch_cli-0.2.74}/PKG-INFO +4 -1
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/README.md +3 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/cli.py +6 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/linkedin.py +252 -1
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/data/CLI_REFERENCE.md +165 -5
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/data/cli-manifest.json +977 -3
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/parser.py +3 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli.egg-info/PKG-INFO +4 -1
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_shared/linkedin_contract.py +68 -1
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_shared/linkedin_filters.py +151 -3
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/pyproject.toml +1 -1
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/MANIFEST.in +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/__init__.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/cli_contracts.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/__init__.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/agents.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/auth.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/cells.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/columns.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/jobs.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/leads.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/prompts.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/rows.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/search.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/sequences.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/tables.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/tasks.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/webhooks.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/commands/workspace_secrets.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/__init__.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/auth.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/config.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/csv_import.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/http.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/io.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/output.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/polling.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/run.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/core/validation.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/exceptions.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/mongo_status.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/parser_groups.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/sequence_support.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli/templates.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli.egg-info/SOURCES.txt +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli.egg-info/dependency_links.txt +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli.egg-info/entry_points.txt +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli.egg-info/requires.txt +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_cli.egg-info/top_level.txt +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_shared/__init__.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_shared/provider_registry.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/autotouch_shared/search_contract.py +0 -0
- {autotouch_cli-0.2.72 → autotouch_cli-0.2.74}/setup.cfg +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.74
|
|
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
|
|
@@ -134,6 +134,7 @@ autotouch rows get --table-id "$TABLE_ID" --row-id "$ROW_ID" --output json
|
|
|
134
134
|
- Create a workflow column: `autotouch columns recipe`, `autotouch columns create`
|
|
135
135
|
- Run provider-hidden search: `autotouch search companies`, `autotouch search people`
|
|
136
136
|
- Inspect LinkedIn/Sales Nav filters: `autotouch linkedin filters --api sales_navigator --category people`
|
|
137
|
+
- Build a paced LinkedIn people list on Smart Table workers: `autotouch linkedin list-build create --company-query 'SaaS startups' --headcount 1-10 --people-query 'Account Executive OR SDR' --num-results 250 --wait`
|
|
137
138
|
- Run one LinkedIn search page/debug replay: `autotouch linkedin search`
|
|
138
139
|
- Run controlled slices: `autotouch columns run-next`
|
|
139
140
|
- Poll authoritative state: `autotouch jobs get`
|
|
@@ -148,6 +149,8 @@ For automation or agent-driven setup, use:
|
|
|
148
149
|
- `autotouch cli-reference` for the shipped parser-generated reference
|
|
149
150
|
- `autotouch capabilities --output json` for provider/workflow contracts
|
|
150
151
|
- `autotouch linkedin filters --output json` for LinkedIn/Sales Navigator filter tokens such as headcount, industry, location, role, function, and seniority
|
|
152
|
+
- `autotouch linkedin list-build create` for durable LinkedIn/Sales Navigator list building with Smart Table-owned paced provider requests, visible progress, and cooldown status
|
|
153
|
+
- `autotouch linkedin search` for one-page LinkedIn/Sales Navigator replay/debug searches; it is not the recommended path for large lists
|
|
151
154
|
- `autotouch rows list` / `autotouch rows get` / `autotouch cells get` for read-back and audit
|
|
152
155
|
- `autotouch sequences ...` and `autotouch tasks ...` for sequence/task workflows
|
|
153
156
|
- `pip install 'autotouch-cli[mongo]'` if you need the Mongo-backed `status` / `watch` commands
|
|
@@ -109,6 +109,7 @@ autotouch rows get --table-id "$TABLE_ID" --row-id "$ROW_ID" --output json
|
|
|
109
109
|
- Create a workflow column: `autotouch columns recipe`, `autotouch columns create`
|
|
110
110
|
- Run provider-hidden search: `autotouch search companies`, `autotouch search people`
|
|
111
111
|
- Inspect LinkedIn/Sales Nav filters: `autotouch linkedin filters --api sales_navigator --category people`
|
|
112
|
+
- Build a paced LinkedIn people list on Smart Table workers: `autotouch linkedin list-build create --company-query 'SaaS startups' --headcount 1-10 --people-query 'Account Executive OR SDR' --num-results 250 --wait`
|
|
112
113
|
- Run one LinkedIn search page/debug replay: `autotouch linkedin search`
|
|
113
114
|
- Run controlled slices: `autotouch columns run-next`
|
|
114
115
|
- Poll authoritative state: `autotouch jobs get`
|
|
@@ -123,6 +124,8 @@ For automation or agent-driven setup, use:
|
|
|
123
124
|
- `autotouch cli-reference` for the shipped parser-generated reference
|
|
124
125
|
- `autotouch capabilities --output json` for provider/workflow contracts
|
|
125
126
|
- `autotouch linkedin filters --output json` for LinkedIn/Sales Navigator filter tokens such as headcount, industry, location, role, function, and seniority
|
|
127
|
+
- `autotouch linkedin list-build create` for durable LinkedIn/Sales Navigator list building with Smart Table-owned paced provider requests, visible progress, and cooldown status
|
|
128
|
+
- `autotouch linkedin search` for one-page LinkedIn/Sales Navigator replay/debug searches; it is not the recommended path for large lists
|
|
126
129
|
- `autotouch rows list` / `autotouch rows get` / `autotouch cells get` for read-back and audit
|
|
127
130
|
- `autotouch sequences ...` and `autotouch tasks ...` for sequence/task workflows
|
|
128
131
|
- `pip install 'autotouch-cli[mongo]'` if you need the Mongo-backed `status` / `watch` commands
|
|
@@ -95,6 +95,9 @@ from autotouch_cli.commands.linkedin import (
|
|
|
95
95
|
cmd_linkedin_comments as cmd_linkedin_comments_impl,
|
|
96
96
|
cmd_linkedin_filters as cmd_linkedin_filters_impl,
|
|
97
97
|
cmd_linkedin_limits as cmd_linkedin_limits_impl,
|
|
98
|
+
cmd_linkedin_list_build_create as cmd_linkedin_list_build_create_impl,
|
|
99
|
+
cmd_linkedin_list_build_results as cmd_linkedin_list_build_results_impl,
|
|
100
|
+
cmd_linkedin_list_build_status as cmd_linkedin_list_build_status_impl,
|
|
98
101
|
cmd_linkedin_post as cmd_linkedin_post_impl,
|
|
99
102
|
cmd_linkedin_posts as cmd_linkedin_posts_impl,
|
|
100
103
|
cmd_linkedin_reactions as cmd_linkedin_reactions_impl,
|
|
@@ -1546,6 +1549,9 @@ _register("linkedin_limits", cmd_linkedin_limits_impl, _linkedin_command_runtime
|
|
|
1546
1549
|
_register("linkedin_search", cmd_linkedin_search_impl, _linkedin_command_runtime)
|
|
1547
1550
|
_register("linkedin_search_params", cmd_linkedin_search_params_impl, _linkedin_command_runtime)
|
|
1548
1551
|
_register("linkedin_filters", cmd_linkedin_filters_impl, _linkedin_command_runtime)
|
|
1552
|
+
_register("linkedin_list_build_create", cmd_linkedin_list_build_create_impl, _linkedin_command_runtime)
|
|
1553
|
+
_register("linkedin_list_build_status", cmd_linkedin_list_build_status_impl, _linkedin_command_runtime)
|
|
1554
|
+
_register("linkedin_list_build_results", cmd_linkedin_list_build_results_impl, _linkedin_command_runtime)
|
|
1549
1555
|
_register("linkedin_posts", cmd_linkedin_posts_impl, _linkedin_command_runtime)
|
|
1550
1556
|
_register("linkedin_post", cmd_linkedin_post_impl, _linkedin_command_runtime)
|
|
1551
1557
|
_register("linkedin_comments", cmd_linkedin_comments_impl, _linkedin_command_runtime)
|
|
@@ -2,8 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
import json
|
|
5
|
+
import time
|
|
5
6
|
from dataclasses import dataclass
|
|
6
|
-
from typing import Any, Callable, Dict, Optional, Sequence
|
|
7
|
+
from typing import Any, Callable, Dict, List, Optional, Sequence
|
|
7
8
|
|
|
8
9
|
from autotouch_shared.linkedin_filters import linkedin_filter_catalog
|
|
9
10
|
from autotouch_cli.exceptions import AutotouchInputError
|
|
@@ -118,6 +119,208 @@ def cmd_linkedin_search_params(args: argparse.Namespace, *, runtime: LinkedInCom
|
|
|
118
119
|
runtime.print_json(data, args.compact)
|
|
119
120
|
|
|
120
121
|
|
|
122
|
+
def _load_optional_json_object(raw: Optional[str], *, context: str) -> Optional[Dict[str, Any]]:
|
|
123
|
+
if not raw:
|
|
124
|
+
return None
|
|
125
|
+
try:
|
|
126
|
+
parsed = json.loads(raw)
|
|
127
|
+
except Exception as exc:
|
|
128
|
+
raise AutotouchInputError(f"invalid JSON for {context}: {exc}") from exc
|
|
129
|
+
if not isinstance(parsed, dict):
|
|
130
|
+
raise AutotouchInputError(f"{context} must be a JSON object")
|
|
131
|
+
return parsed
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _split_repeated_values(values: Optional[List[str]]) -> List[str]:
|
|
135
|
+
output: List[str] = []
|
|
136
|
+
for raw in values or []:
|
|
137
|
+
for part in str(raw).replace("\n", ",").split(","):
|
|
138
|
+
value = part.strip()
|
|
139
|
+
if value:
|
|
140
|
+
output.append(value)
|
|
141
|
+
return output
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _coerce_filter_arg_value(raw: str) -> Any:
|
|
145
|
+
value = str(raw or "").strip()
|
|
146
|
+
if not value:
|
|
147
|
+
return ""
|
|
148
|
+
if value[0] in "[{\"" or value.lower() in {"true", "false", "null"}:
|
|
149
|
+
try:
|
|
150
|
+
return json.loads(value)
|
|
151
|
+
except Exception:
|
|
152
|
+
pass
|
|
153
|
+
if "," in value:
|
|
154
|
+
return [part.strip() for part in value.split(",") if part.strip()]
|
|
155
|
+
return value
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _parse_filter_pairs(values: Optional[List[str]], *, context: str) -> Dict[str, Any]:
|
|
159
|
+
filters: Dict[str, Any] = {}
|
|
160
|
+
for raw in values or []:
|
|
161
|
+
item = str(raw or "").strip()
|
|
162
|
+
if not item:
|
|
163
|
+
continue
|
|
164
|
+
if "=" not in item:
|
|
165
|
+
raise AutotouchInputError(f"{context} filters must use FIELD=VALUE")
|
|
166
|
+
field, value = item.split("=", 1)
|
|
167
|
+
field = field.strip()
|
|
168
|
+
if not field:
|
|
169
|
+
raise AutotouchInputError(f"{context} filter field is empty")
|
|
170
|
+
filters[field] = _coerce_filter_arg_value(value)
|
|
171
|
+
return filters
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _add_repeated_filter(filters: Dict[str, Any], field: str, values: Optional[List[str]]) -> None:
|
|
175
|
+
parsed = _split_repeated_values(values)
|
|
176
|
+
if parsed:
|
|
177
|
+
filters[field] = parsed
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _normalize_linkedin_list_build_payload(args: argparse.Namespace, *, runtime: LinkedInCommandRuntime) -> Dict[str, Any]:
|
|
181
|
+
explicit = runtime.load_json_input(
|
|
182
|
+
inline_json=getattr(args, "data_json", None),
|
|
183
|
+
file_path=getattr(args, "data_file", None),
|
|
184
|
+
context="data",
|
|
185
|
+
default=None,
|
|
186
|
+
)
|
|
187
|
+
if explicit is not None:
|
|
188
|
+
if not isinstance(explicit, dict):
|
|
189
|
+
raise AutotouchInputError("linkedin list-build payload must be a JSON object")
|
|
190
|
+
return explicit
|
|
191
|
+
|
|
192
|
+
company_query = str(getattr(args, "company_query", "") or "").strip()
|
|
193
|
+
if not company_query:
|
|
194
|
+
raise AutotouchInputError("linkedin list-build create requires --company-query or --data-file")
|
|
195
|
+
|
|
196
|
+
payload: Dict[str, Any] = {
|
|
197
|
+
"mode": str(getattr(args, "mode", "company-first-people") or "company-first-people").strip(),
|
|
198
|
+
"company_query": company_query,
|
|
199
|
+
"headcount": str(getattr(args, "headcount", "1-10") or "1-10").strip(),
|
|
200
|
+
"num_results": max(1, min(int(getattr(args, "num_results", 100) or 100), 1000)),
|
|
201
|
+
}
|
|
202
|
+
people_query = str(getattr(args, "people_query", "") or "").strip()
|
|
203
|
+
if people_query:
|
|
204
|
+
payload["people_query"] = people_query
|
|
205
|
+
linkedin_api = str(getattr(args, "linkedin_api", "auto") or "auto").strip()
|
|
206
|
+
if linkedin_api and linkedin_api != "auto":
|
|
207
|
+
payload["linkedin_api"] = linkedin_api
|
|
208
|
+
excluded_titles = _split_repeated_values(getattr(args, "excluded_title", None))
|
|
209
|
+
if excluded_titles:
|
|
210
|
+
payload["excluded_titles"] = excluded_titles
|
|
211
|
+
company_filters = _parse_filter_pairs(getattr(args, "company_filter", None), context="company")
|
|
212
|
+
people_filters = _parse_filter_pairs(getattr(args, "people_filter", None), context="people")
|
|
213
|
+
_add_repeated_filter(company_filters, "location", getattr(args, "company_location_id", None) or getattr(args, "location_id", None))
|
|
214
|
+
_add_repeated_filter(people_filters, "location", getattr(args, "people_location_id", None) or getattr(args, "location_id", None))
|
|
215
|
+
_add_repeated_filter(company_filters, "industry", getattr(args, "company_industry_id", None))
|
|
216
|
+
_add_repeated_filter(people_filters, "industry", getattr(args, "people_industry_id", None))
|
|
217
|
+
_add_repeated_filter(people_filters, "role", getattr(args, "role_id", None))
|
|
218
|
+
_add_repeated_filter(people_filters, "function", getattr(args, "function_id", None))
|
|
219
|
+
_add_repeated_filter(people_filters, "seniority", getattr(args, "seniority", None))
|
|
220
|
+
_add_repeated_filter(people_filters, "profile_language", getattr(args, "profile_language", None))
|
|
221
|
+
_add_repeated_filter(company_filters, "technologies", getattr(args, "technology_id", None))
|
|
222
|
+
if getattr(args, "has_job_offers", False):
|
|
223
|
+
company_filters["has_job_offers"] = True
|
|
224
|
+
if company_filters:
|
|
225
|
+
payload["company_filters"] = company_filters
|
|
226
|
+
if people_filters:
|
|
227
|
+
payload["people_filters"] = people_filters
|
|
228
|
+
for arg_name, payload_key, context in (
|
|
229
|
+
("extra_params_json", "extra_params", "extra-params"),
|
|
230
|
+
("company_extra_params_json", "company_extra_params", "company-extra-params"),
|
|
231
|
+
("people_extra_params_json", "people_extra_params", "people-extra-params"),
|
|
232
|
+
):
|
|
233
|
+
parsed = _load_optional_json_object(getattr(args, arg_name, None), context=context)
|
|
234
|
+
if parsed is not None:
|
|
235
|
+
payload[payload_key] = parsed
|
|
236
|
+
return payload
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def _wait_for_linkedin_list_build(
|
|
240
|
+
job_id: str,
|
|
241
|
+
args: argparse.Namespace,
|
|
242
|
+
*,
|
|
243
|
+
runtime: LinkedInCommandRuntime,
|
|
244
|
+
token: Optional[str],
|
|
245
|
+
) -> Dict[str, Any]:
|
|
246
|
+
started = time.time()
|
|
247
|
+
interval = max(1, int(getattr(args, "poll_interval", 5) or 5))
|
|
248
|
+
timeout = max(0, int(getattr(args, "wait_timeout", 0) or 0))
|
|
249
|
+
terminal = {"completed", "error", "cancelled"}
|
|
250
|
+
latest: Dict[str, Any] = {}
|
|
251
|
+
|
|
252
|
+
while True:
|
|
253
|
+
latest = runtime.request_api(
|
|
254
|
+
"GET",
|
|
255
|
+
f"/api/integrations/linkedin/list-builds/{job_id}",
|
|
256
|
+
base_url=args.base_url,
|
|
257
|
+
token=token,
|
|
258
|
+
use_x_api_key=args.use_x_api_key,
|
|
259
|
+
timeout=args.timeout,
|
|
260
|
+
verbose=args.verbose,
|
|
261
|
+
)
|
|
262
|
+
status = str(latest.get("status") or "").strip().lower() if isinstance(latest, dict) else ""
|
|
263
|
+
if status in terminal:
|
|
264
|
+
return latest
|
|
265
|
+
if timeout and (time.time() - started) >= timeout:
|
|
266
|
+
return latest
|
|
267
|
+
time.sleep(interval)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def cmd_linkedin_list_build_create(args: argparse.Namespace, *, runtime: LinkedInCommandRuntime) -> None:
|
|
271
|
+
token = runtime.resolve_token(args.token, required=True)
|
|
272
|
+
payload = _normalize_linkedin_list_build_payload(args, runtime=runtime)
|
|
273
|
+
data = runtime.request_api(
|
|
274
|
+
"POST",
|
|
275
|
+
"/api/integrations/linkedin/list-builds",
|
|
276
|
+
base_url=args.base_url,
|
|
277
|
+
token=token,
|
|
278
|
+
use_x_api_key=args.use_x_api_key,
|
|
279
|
+
payload=payload,
|
|
280
|
+
timeout=args.timeout,
|
|
281
|
+
verbose=args.verbose,
|
|
282
|
+
)
|
|
283
|
+
if getattr(args, "wait", False) and isinstance(data, dict) and data.get("job_id"):
|
|
284
|
+
data = _wait_for_linkedin_list_build(str(data["job_id"]), args, runtime=runtime, token=token)
|
|
285
|
+
runtime.print_json(data, args.compact)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def cmd_linkedin_list_build_status(args: argparse.Namespace, *, runtime: LinkedInCommandRuntime) -> None:
|
|
289
|
+
token = runtime.resolve_token(args.token, required=True)
|
|
290
|
+
job_id = str(args.job_id).strip()
|
|
291
|
+
data = runtime.request_api(
|
|
292
|
+
"GET",
|
|
293
|
+
f"/api/integrations/linkedin/list-builds/{job_id}",
|
|
294
|
+
base_url=args.base_url,
|
|
295
|
+
token=token,
|
|
296
|
+
use_x_api_key=args.use_x_api_key,
|
|
297
|
+
timeout=args.timeout,
|
|
298
|
+
verbose=args.verbose,
|
|
299
|
+
)
|
|
300
|
+
runtime.print_json(data, args.compact)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def cmd_linkedin_list_build_results(args: argparse.Namespace, *, runtime: LinkedInCommandRuntime) -> None:
|
|
304
|
+
token = runtime.resolve_token(args.token, required=True)
|
|
305
|
+
job_id = str(args.job_id).strip()
|
|
306
|
+
params: Dict[str, Any] = {
|
|
307
|
+
"type": str(getattr(args, "type", "people") or "people"),
|
|
308
|
+
"page": max(1, int(getattr(args, "page", 1) or 1)),
|
|
309
|
+
"page_size": max(1, min(int(getattr(args, "page_size", 50) or 50), 500)),
|
|
310
|
+
}
|
|
311
|
+
data = runtime.request_api(
|
|
312
|
+
"GET",
|
|
313
|
+
f"/api/integrations/linkedin/list-builds/{job_id}/results",
|
|
314
|
+
base_url=args.base_url,
|
|
315
|
+
token=token,
|
|
316
|
+
use_x_api_key=args.use_x_api_key,
|
|
317
|
+
params=params,
|
|
318
|
+
timeout=args.timeout,
|
|
319
|
+
verbose=args.verbose,
|
|
320
|
+
)
|
|
321
|
+
runtime.print_json(data, args.compact)
|
|
322
|
+
|
|
323
|
+
|
|
121
324
|
def cmd_linkedin_filters(args: argparse.Namespace, *, runtime: LinkedInCommandRuntime) -> None:
|
|
122
325
|
output = linkedin_filter_catalog(
|
|
123
326
|
api_mode=getattr(args, "api", None),
|
|
@@ -293,6 +496,54 @@ def register_linkedin_subcommands(
|
|
|
293
496
|
add_api_common_arguments(filters_parser)
|
|
294
497
|
filters_parser.set_defaults(func=handlers["filters"])
|
|
295
498
|
|
|
499
|
+
list_build_parser = linkedin_sub.add_parser("list-build", help="Create and inspect paced LinkedIn list-build jobs")
|
|
500
|
+
list_build_sub = list_build_parser.add_subparsers(dest="linkedin_list_build_cmd", required=True)
|
|
501
|
+
|
|
502
|
+
list_build_create = list_build_sub.add_parser("create", help="Create a paced background LinkedIn list-build job")
|
|
503
|
+
list_build_create.add_argument("--data-json", help="Explicit list-build payload JSON (overrides individual flags)")
|
|
504
|
+
list_build_create.add_argument("--data-file", help="Path to list-build payload JSON file")
|
|
505
|
+
list_build_create.add_argument("--mode", choices=["company-first-people"], default="company-first-people", help="List build mode")
|
|
506
|
+
list_build_create.add_argument("--linkedin-api", choices=["auto", "classic", "sales_navigator"], default="auto", help="API mode (default: auto; uses connected account mode)")
|
|
507
|
+
list_build_create.add_argument("--company-query", help="Company-search query used to build the seed account set")
|
|
508
|
+
list_build_create.add_argument("--people-query", help="People-search query/title terms")
|
|
509
|
+
list_build_create.add_argument("--headcount", default="1-10", help="Company headcount range, e.g. 1-10 or 11-50")
|
|
510
|
+
list_build_create.add_argument("--num-results", type=int, default=100, help="Target number of people results, 1-1000")
|
|
511
|
+
list_build_create.add_argument("--excluded-title", action="append", help="Title to exclude after results return; repeat or comma-separate")
|
|
512
|
+
list_build_create.add_argument("--location-id", action="append", help="LinkedIn location/region ID applied to company and people search")
|
|
513
|
+
list_build_create.add_argument("--company-location-id", action="append", help="LinkedIn location/region ID applied only to company search")
|
|
514
|
+
list_build_create.add_argument("--people-location-id", action="append", help="LinkedIn location/region ID applied only to people search")
|
|
515
|
+
list_build_create.add_argument("--company-industry-id", action="append", help="LinkedIn industry ID applied to company search")
|
|
516
|
+
list_build_create.add_argument("--people-industry-id", action="append", help="LinkedIn industry ID applied to people search")
|
|
517
|
+
list_build_create.add_argument("--role-id", action="append", help="Resolved LinkedIn job-title ID for people search; repeat or comma-separate")
|
|
518
|
+
list_build_create.add_argument("--function-id", action="append", help="Resolved LinkedIn department/function ID for Sales Nav people search")
|
|
519
|
+
list_build_create.add_argument("--seniority", action="append", help="Sales Nav seniority filter value; repeat or comma-separate")
|
|
520
|
+
list_build_create.add_argument("--profile-language", action="append", help="Profile language code, e.g. en")
|
|
521
|
+
list_build_create.add_argument("--technology-id", action="append", help="Sales Nav technology ID applied to company search")
|
|
522
|
+
list_build_create.add_argument("--has-job-offers", action="store_true", help="Filter companies currently hiring on LinkedIn")
|
|
523
|
+
list_build_create.add_argument("--company-filter", action="append", help="Catalog company filter as FIELD=VALUE; repeat for multiple filters")
|
|
524
|
+
list_build_create.add_argument("--people-filter", action="append", help="Catalog people filter as FIELD=VALUE; repeat for multiple filters")
|
|
525
|
+
list_build_create.add_argument("--extra-params-json", help="JSON object applied to both company and people searches")
|
|
526
|
+
list_build_create.add_argument("--company-extra-params-json", help="JSON object applied only to company search")
|
|
527
|
+
list_build_create.add_argument("--people-extra-params-json", help="JSON object applied only to people search")
|
|
528
|
+
list_build_create.add_argument("--wait", action="store_true", help="Poll until the job reaches completed, error, or cancelled")
|
|
529
|
+
list_build_create.add_argument("--poll-interval", type=int, default=5, help="Polling interval seconds for --wait")
|
|
530
|
+
list_build_create.add_argument("--wait-timeout", type=int, default=0, help="Max seconds to wait (0 = no timeout)")
|
|
531
|
+
add_api_common_arguments(list_build_create)
|
|
532
|
+
list_build_create.set_defaults(func=handlers["list_build_create"])
|
|
533
|
+
|
|
534
|
+
list_build_status = list_build_sub.add_parser("status", help="Get LinkedIn list-build job status")
|
|
535
|
+
list_build_status.add_argument("--job-id", required=True, help="LinkedIn list-build job id")
|
|
536
|
+
add_api_common_arguments(list_build_status)
|
|
537
|
+
list_build_status.set_defaults(func=handlers["list_build_status"])
|
|
538
|
+
|
|
539
|
+
list_build_results = list_build_sub.add_parser("results", help="Get LinkedIn list-build results")
|
|
540
|
+
list_build_results.add_argument("--job-id", required=True, help="LinkedIn list-build job id")
|
|
541
|
+
list_build_results.add_argument("--type", choices=["people", "companies", "all"], default="people", help="Result type")
|
|
542
|
+
list_build_results.add_argument("--page", type=int, default=1, help="Results page")
|
|
543
|
+
list_build_results.add_argument("--page-size", type=int, default=50, help="Results per page, 1-500")
|
|
544
|
+
add_api_common_arguments(list_build_results)
|
|
545
|
+
list_build_results.set_defaults(func=handlers["list_build_results"])
|
|
546
|
+
|
|
296
547
|
posts_parser = linkedin_sub.add_parser("posts", help="List LinkedIn posts for a user")
|
|
297
548
|
posts_parser.add_argument("--identifier", required=True, help="LinkedIn profile URL, public ID, or URN")
|
|
298
549
|
posts_parser.add_argument("--cursor", help="Pagination cursor from previous response")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Autotouch CLI Reference
|
|
2
2
|
|
|
3
|
-
Generated from the installed parser for `autotouch-cli` `0.2.
|
|
3
|
+
Generated from the installed parser for `autotouch-cli` `0.2.74`.
|
|
4
4
|
Manifest schema version: `2`.
|
|
5
5
|
|
|
6
6
|
## Output Modes
|
|
@@ -2243,10 +2243,10 @@ LinkedIn list-building operations
|
|
|
2243
2243
|
- Auth: `varies_by_subcommand`
|
|
2244
2244
|
- Stability: `stable`
|
|
2245
2245
|
- Destructive: `no`
|
|
2246
|
-
- Subcommands: `recipe, status, limits, search, search-params, filters, posts, post, comments, reactions`
|
|
2246
|
+
- Subcommands: `recipe, status, limits, search, search-params, filters, list-build, posts, post, comments, reactions`
|
|
2247
2247
|
- Example:
|
|
2248
2248
|
- `autotouch linkedin [-h]
|
|
2249
|
-
{recipe,status,limits,search,search-params,filters,posts,post,comments,reactions} ...`
|
|
2249
|
+
{recipe,status,limits,search,search-params,filters,list-build,posts,post,comments,reactions} ...`
|
|
2250
2250
|
|
|
2251
2251
|
#### `autotouch linkedin comments`
|
|
2252
2252
|
|
|
@@ -2336,6 +2336,166 @@ View LinkedIn send limits and usage
|
|
|
2336
2336
|
- `--json-pointer` (kind=string): Extract a JSON pointer from the final result (for example: /id)
|
|
2337
2337
|
- `--verbose` (kind=boolean; when omitted=False; when present=True): Print request metadata to stderr
|
|
2338
2338
|
|
|
2339
|
+
#### `autotouch linkedin list-build`
|
|
2340
|
+
|
|
2341
|
+
Create and inspect paced LinkedIn list-build jobs
|
|
2342
|
+
|
|
2343
|
+
- Auth: `varies_by_subcommand`
|
|
2344
|
+
- Stability: `stable`
|
|
2345
|
+
- Destructive: `no`
|
|
2346
|
+
- Subcommands: `create, status, results`
|
|
2347
|
+
- Example:
|
|
2348
|
+
- `autotouch linkedin list-build [-h] {create,status,results} ...`
|
|
2349
|
+
|
|
2350
|
+
#### `autotouch linkedin list-build create`
|
|
2351
|
+
|
|
2352
|
+
Create a paced background LinkedIn list-build job
|
|
2353
|
+
|
|
2354
|
+
- Auth: `developer_key_or_user_session`
|
|
2355
|
+
- Stability: `stable`
|
|
2356
|
+
- Destructive: `no`
|
|
2357
|
+
- Output modes: `json, ndjson, human`
|
|
2358
|
+
- Example:
|
|
2359
|
+
- `autotouch linkedin list-build create [-h] [--data-json DATA_JSON]
|
|
2360
|
+
[--data-file DATA_FILE]
|
|
2361
|
+
[--mode {company-first-people}]
|
|
2362
|
+
[--linkedin-api {auto,classic,sales_navigator}]
|
|
2363
|
+
[--company-query COMPANY_QUERY]
|
|
2364
|
+
[--people-query PEOPLE_QUERY]
|
|
2365
|
+
[--headcount HEADCOUNT]
|
|
2366
|
+
[--num-results NUM_RESULTS]
|
|
2367
|
+
[--excluded-title EXCLUDED_TITLE]
|
|
2368
|
+
[--location-id LOCATION_ID]
|
|
2369
|
+
[--company-location-id COMPANY_LOCATION_ID]
|
|
2370
|
+
[--people-location-id PEOPLE_LOCATION_ID]
|
|
2371
|
+
[--company-industry-id COMPANY_INDUSTRY_ID]
|
|
2372
|
+
[--people-industry-id PEOPLE_INDUSTRY_ID]
|
|
2373
|
+
[--role-id ROLE_ID]
|
|
2374
|
+
[--function-id FUNCTION_ID]
|
|
2375
|
+
[--seniority SENIORITY]
|
|
2376
|
+
[--profile-language PROFILE_LANGUAGE]
|
|
2377
|
+
[--technology-id TECHNOLOGY_ID]
|
|
2378
|
+
[--has-job-offers]
|
|
2379
|
+
[--company-filter COMPANY_FILTER]
|
|
2380
|
+
[--people-filter PEOPLE_FILTER]
|
|
2381
|
+
[--extra-params-json EXTRA_PARAMS_JSON]
|
|
2382
|
+
[--company-extra-params-json COMPANY_EXTRA_PARAMS_JSON]
|
|
2383
|
+
[--people-extra-params-json PEOPLE_EXTRA_PARAMS_JSON]
|
|
2384
|
+
[--wait]
|
|
2385
|
+
[--poll-interval POLL_INTERVAL]
|
|
2386
|
+
[--wait-timeout WAIT_TIMEOUT]
|
|
2387
|
+
[--base-url BASE_URL]
|
|
2388
|
+
[--token TOKEN] [--use-x-api-key]
|
|
2389
|
+
[--timeout TIMEOUT]
|
|
2390
|
+
[--output {json,ndjson,human}]
|
|
2391
|
+
[--compact] [--select SELECT |
|
|
2392
|
+
--json-pointer JSON_POINTER]
|
|
2393
|
+
[--verbose]`
|
|
2394
|
+
- Options:
|
|
2395
|
+
- `--data-json` (kind=json; input=json): Explicit list-build payload JSON (overrides individual flags)
|
|
2396
|
+
- `--data-file` (kind=file; input=file): Path to list-build payload JSON file
|
|
2397
|
+
- `--mode` (kind=string; choices=company-first-people; default=company-first-people): List build mode
|
|
2398
|
+
- `--linkedin-api` (kind=string; choices=auto,classic,sales_navigator; default=auto): API mode (default: auto; uses connected account mode)
|
|
2399
|
+
- `--company-query` (kind=string): Company-search query used to build the seed account set
|
|
2400
|
+
- `--people-query` (kind=string): People-search query/title terms
|
|
2401
|
+
- `--headcount` (kind=string; default=1-10): Company headcount range, e.g. 1-10 or 11-50
|
|
2402
|
+
- `--num-results` (kind=integer; default=100): Target number of people results, 1-1000
|
|
2403
|
+
- `--excluded-title` (kind=string; repeatable): Title to exclude after results return; repeat or comma-separate
|
|
2404
|
+
- `--location-id` (kind=string; repeatable): LinkedIn location/region ID applied to company and people search
|
|
2405
|
+
- `--company-location-id` (kind=string; repeatable): LinkedIn location/region ID applied only to company search
|
|
2406
|
+
- `--people-location-id` (kind=string; repeatable): LinkedIn location/region ID applied only to people search
|
|
2407
|
+
- `--company-industry-id` (kind=string; repeatable): LinkedIn industry ID applied to company search
|
|
2408
|
+
- `--people-industry-id` (kind=string; repeatable): LinkedIn industry ID applied to people search
|
|
2409
|
+
- `--role-id` (kind=string; repeatable): Resolved LinkedIn job-title ID for people search; repeat or comma-separate
|
|
2410
|
+
- `--function-id` (kind=string; repeatable): Resolved LinkedIn department/function ID for Sales Nav people search
|
|
2411
|
+
- `--seniority` (kind=string; repeatable): Sales Nav seniority filter value; repeat or comma-separate
|
|
2412
|
+
- `--profile-language` (kind=string; repeatable): Profile language code, e.g. en
|
|
2413
|
+
- `--technology-id` (kind=string; repeatable): Sales Nav technology ID applied to company search
|
|
2414
|
+
- `--has-job-offers` (kind=boolean; when omitted=False; when present=True): Filter companies currently hiring on LinkedIn
|
|
2415
|
+
- `--company-filter` (kind=string; repeatable): Catalog company filter as FIELD=VALUE; repeat for multiple filters
|
|
2416
|
+
- `--people-filter` (kind=string; repeatable): Catalog people filter as FIELD=VALUE; repeat for multiple filters
|
|
2417
|
+
- `--extra-params-json` (kind=json; input=json): JSON object applied to both company and people searches
|
|
2418
|
+
- `--company-extra-params-json` (kind=json; input=json): JSON object applied only to company search
|
|
2419
|
+
- `--people-extra-params-json` (kind=json; input=json): JSON object applied only to people search
|
|
2420
|
+
- `--wait` (kind=boolean; when omitted=False; when present=True): Poll until the job reaches completed, error, or cancelled
|
|
2421
|
+
- `--poll-interval` (kind=integer; default=5): Polling interval seconds for --wait
|
|
2422
|
+
- `--wait-timeout` (kind=integer; default=0): Max seconds to wait (0 = no timeout)
|
|
2423
|
+
- `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
|
|
2424
|
+
- `--token` (kind=string; sensitive): Developer API key / JWT token
|
|
2425
|
+
- `--use-x-api-key` (kind=boolean; when omitted=False; when present=True): Send token via X-API-Key header
|
|
2426
|
+
- `--timeout` (kind=integer; default=30): HTTP timeout in seconds
|
|
2427
|
+
- `--output` (kind=string; choices=json,ndjson,human; default=json): Output mode
|
|
2428
|
+
- `--compact` (kind=boolean; when omitted=False; when present=True): Print compact JSON
|
|
2429
|
+
- `--select` (kind=string): Extract a dotted field path from the final result (for example: id or items.0.id)
|
|
2430
|
+
- `--json-pointer` (kind=string): Extract a JSON pointer from the final result (for example: /id)
|
|
2431
|
+
- `--verbose` (kind=boolean; when omitted=False; when present=True): Print request metadata to stderr
|
|
2432
|
+
|
|
2433
|
+
#### `autotouch linkedin list-build results`
|
|
2434
|
+
|
|
2435
|
+
Get LinkedIn list-build results
|
|
2436
|
+
|
|
2437
|
+
- Auth: `developer_key_or_user_session`
|
|
2438
|
+
- Stability: `stable`
|
|
2439
|
+
- Destructive: `no`
|
|
2440
|
+
- Required flags: `--job-id`
|
|
2441
|
+
- Output modes: `json, ndjson, human`
|
|
2442
|
+
- Example:
|
|
2443
|
+
- `autotouch linkedin list-build results [-h] --job-id JOB_ID
|
|
2444
|
+
[--type {people,companies,all}]
|
|
2445
|
+
[--page PAGE]
|
|
2446
|
+
[--page-size PAGE_SIZE]
|
|
2447
|
+
[--base-url BASE_URL]
|
|
2448
|
+
[--token TOKEN] [--use-x-api-key]
|
|
2449
|
+
[--timeout TIMEOUT]
|
|
2450
|
+
[--output {json,ndjson,human}]
|
|
2451
|
+
[--compact] [--select SELECT |
|
|
2452
|
+
--json-pointer JSON_POINTER]
|
|
2453
|
+
[--verbose]`
|
|
2454
|
+
- Options:
|
|
2455
|
+
- `--job-id` (required; kind=string): LinkedIn list-build job id
|
|
2456
|
+
- `--type` (kind=string; choices=people,companies,all; default=people): Result type
|
|
2457
|
+
- `--page` (kind=integer; default=1): Results page
|
|
2458
|
+
- `--page-size` (kind=integer; default=50): Results per page, 1-500
|
|
2459
|
+
- `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
|
|
2460
|
+
- `--token` (kind=string; sensitive): Developer API key / JWT token
|
|
2461
|
+
- `--use-x-api-key` (kind=boolean; when omitted=False; when present=True): Send token via X-API-Key header
|
|
2462
|
+
- `--timeout` (kind=integer; default=30): HTTP timeout in seconds
|
|
2463
|
+
- `--output` (kind=string; choices=json,ndjson,human; default=json): Output mode
|
|
2464
|
+
- `--compact` (kind=boolean; when omitted=False; when present=True): Print compact JSON
|
|
2465
|
+
- `--select` (kind=string): Extract a dotted field path from the final result (for example: id or items.0.id)
|
|
2466
|
+
- `--json-pointer` (kind=string): Extract a JSON pointer from the final result (for example: /id)
|
|
2467
|
+
- `--verbose` (kind=boolean; when omitted=False; when present=True): Print request metadata to stderr
|
|
2468
|
+
|
|
2469
|
+
#### `autotouch linkedin list-build status`
|
|
2470
|
+
|
|
2471
|
+
Get LinkedIn list-build job status
|
|
2472
|
+
|
|
2473
|
+
- Auth: `developer_key_or_user_session`
|
|
2474
|
+
- Stability: `stable`
|
|
2475
|
+
- Destructive: `no`
|
|
2476
|
+
- Required flags: `--job-id`
|
|
2477
|
+
- Output modes: `json, ndjson, human`
|
|
2478
|
+
- Example:
|
|
2479
|
+
- `autotouch linkedin list-build status [-h] --job-id JOB_ID
|
|
2480
|
+
[--base-url BASE_URL]
|
|
2481
|
+
[--token TOKEN] [--use-x-api-key]
|
|
2482
|
+
[--timeout TIMEOUT]
|
|
2483
|
+
[--output {json,ndjson,human}]
|
|
2484
|
+
[--compact] [--select SELECT |
|
|
2485
|
+
--json-pointer JSON_POINTER]
|
|
2486
|
+
[--verbose]`
|
|
2487
|
+
- Options:
|
|
2488
|
+
- `--job-id` (required; kind=string): LinkedIn list-build job id
|
|
2489
|
+
- `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
|
|
2490
|
+
- `--token` (kind=string; sensitive): Developer API key / JWT token
|
|
2491
|
+
- `--use-x-api-key` (kind=boolean; when omitted=False; when present=True): Send token via X-API-Key header
|
|
2492
|
+
- `--timeout` (kind=integer; default=30): HTTP timeout in seconds
|
|
2493
|
+
- `--output` (kind=string; choices=json,ndjson,human; default=json): Output mode
|
|
2494
|
+
- `--compact` (kind=boolean; when omitted=False; when present=True): Print compact JSON
|
|
2495
|
+
- `--select` (kind=string): Extract a dotted field path from the final result (for example: id or items.0.id)
|
|
2496
|
+
- `--json-pointer` (kind=string): Extract a JSON pointer from the final result (for example: /id)
|
|
2497
|
+
- `--verbose` (kind=boolean; when omitted=False; when present=True): Print request metadata to stderr
|
|
2498
|
+
|
|
2339
2499
|
#### `autotouch linkedin post`
|
|
2340
2500
|
|
|
2341
2501
|
Get full details for a single LinkedIn post
|
|
@@ -2436,7 +2596,7 @@ Print LinkedIn payload recipes for search and list-building
|
|
|
2436
2596
|
- Output modes: `json, ndjson, human`
|
|
2437
2597
|
- Example:
|
|
2438
2598
|
- `autotouch linkedin recipe [-h]
|
|
2439
|
-
[--type {all,search,search_url,search_params,posts,comments,reactions}]
|
|
2599
|
+
[--type {all,list_build_company_first_people,search,search_url,search_params,posts,comments,reactions}]
|
|
2440
2600
|
[--out-file OUT_FILE] [--base-url BASE_URL]
|
|
2441
2601
|
[--token TOKEN] [--use-x-api-key]
|
|
2442
2602
|
[--timeout TIMEOUT]
|
|
@@ -2444,7 +2604,7 @@ Print LinkedIn payload recipes for search and list-building
|
|
|
2444
2604
|
[--select SELECT |
|
|
2445
2605
|
--json-pointer JSON_POINTER] [--verbose]`
|
|
2446
2606
|
- Options:
|
|
2447
|
-
- `--type` (kind=string; choices=all,search,search_url,search_params,posts,comments,reactions; default=all)
|
|
2607
|
+
- `--type` (kind=string; choices=all,list_build_company_first_people,search,search_url,search_params,posts,comments,reactions; default=all)
|
|
2448
2608
|
- `--out-file` (kind=file; input=file): Optional path to save the selected payload JSON
|
|
2449
2609
|
- `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
|
|
2450
2610
|
- `--token` (kind=string; sensitive): Developer API key / JWT token
|