From gtm-skills
Runs Extruct API tasks via bundled CLI: Deep Search, semantic/lookalike search, company/people tables, column operations, enrichment, contact finding.
npx claudepluginhub extruct-ai/gtm-skills --plugin gtm-skillsThis skill uses the workspace's default tool permissions.
Use `<extruct_api_cli>` for supported Extruct operations. Do not construct raw HTTP requests for operations the CLI already supports.
Parses company data from pasted lists, CSVs, or tables to create or update Extruct tables, uploads domains in batches, adds optional enrichment columns, and triggers agents.
Researches B2B leads and decision makers by role, company, location; enriches organizations by domain and people by email using Apollo.io API.
Generates leads via LinkedIn prospect discovery, email finding, website contact extraction, company research, and data enrichment using anysite MCP server. For building sales, recruiting, or business development prospect lists.
Share bugs, ideas, or general feedback.
Use <extruct_api_cli> for supported Extruct operations. Do not construct raw HTTP requests for operations the CLI already supports.
Extruct AI is a company discovery and research platform for finding, enriching, and evaluating companies. Its core workflows are semantic search, lookalike search, and Deep Search for company discovery, plus AI Tables for repeatable company and people enrichment, scoring, and contact-finding workflows.
Use the bundled CLI and the instructions in this skill as the default path.
When behavior is unclear, when the user asks for a capability that may not be covered here, or when the request may depend on recently changed API behavior, consult the official Extruct API reference as the source of truth:
Decision rule:
<extruct_api_cli> means the absolute path to the bundled CLI script for this skill.
SKILL.md.scripts/extruct-api relative to the workspace root.<extruct_api_cli> as shorthand for that resolved absolute path.Example:
/absolute/path/to/skills/extruct-api/scripts/extruct-api auth user
This section covers the default operating intent of the skill: identify the Extruct object the user is working with, choose the right execution path, inspect before mutating, and use the CLI to carry the task through to completion.
<extruct_api_cli> first, then establish API access. Before the first authenticated CLI call in a conversation, run <extruct_api_cli> auth user. If it fails, run <extruct_api_cli> healthcheck to distinguish credential problems from connectivity issues.tables get, columns list, and a small tables data page. When you only need a surgical read, add --columns on the first tables data call instead of fetching the full row payload.--payload-file. Read references/column-guide.md before designing or changing columns.tables poll or deep-search poll, then summarize the final result or API error in plain language, including IDs, counts, and the next relevant object when it matters.If any request shape, field name, response contract, or endpoint capability is uncertain while executing this workflow, re-check the official API reference before proceeding:
Users may provide Extruct objects as raw IDs or as dashboard URLs.
Interpret them as follows:
https://app.extruct.ai/tables/<table_id> or http://app.extruct.ai/tables/<table_id>, treat the path segment after /tables/ as the table idhttps://app.extruct.ai/tasks/<task_id> or http://app.extruct.ai/tasks/<task_id>, treat the path segment after /tasks/ as the Deep Search task id/tables/<table_id> or /tasks/<task_id> segmentExample:
User request:
Add a funding column to http://app.extruct.ai/tables/0a1a669a-9a40-497c-bb00-d49dd8ee5b74
Resulting table id:
0a1a669a-9a40-497c-bb00-d49dd8ee5b74
First CLI reads:
<extruct_api_cli> tables get 0a1a669a-9a40-497c-bb00-d49dd8ee5b74
<extruct_api_cli> columns list 0a1a669a-9a40-497c-bb00-d49dd8ee5b74
<extruct_api_cli> tables data 0a1a669a-9a40-497c-bb00-d49dd8ee5b74 --limit 20 --offset 0
User request:
Check results for https://app.extruct.ai/tasks/d530c3ad-626c-4d7b-ab15-181d4058e4f8
Resulting task id:
d530c3ad-626c-4d7b-ab15-181d4058e4f8
First CLI reads:
<extruct_api_cli> deep-search get d530c3ad-626c-4d7b-ab15-181d4058e4f8
<extruct_api_cli> deep-search results d530c3ad-626c-4d7b-ab15-181d4058e4f8 --limit 20 --offset 0
Use semantic search when the user describes a market, ICP, category, product, or use case in natural language.
Typical asks:
Commands:
<extruct_api_cli> companies search --query "vertical SaaS for logistics procurement" --limit 20
<extruct_api_cli> companies search --query "enterprise sales AI" \
--filters '{"include":{"country":["United States"]},"range":{"founded":{"min":2018}}}' \
--offset 20 --limit 20
Use --filters when the user specifies geography, city, company size, or founded range. Pass a JSON object like one of these as the --filters value.
{
"include": {
"country": ["United States"],
"size": ["51-200", "201-500"]
}
}
{
"range": {
"founded": {
"min": 2018,
"max": 2024
}
}
}
If search filters or pagination behavior appear different from the guidance here, verify current request and response details in the official API reference before guessing.
Use lookalike search when the user already has a reference company and wants similar companies. Prefer domains or URLs for --company-identifier unless a prior Extruct response already gives you a UUID.
Typical asks:
Commands:
<extruct_api_cli> companies similar --company-identifier extruct.ai --limit 20
<extruct_api_cli> companies similar --company-identifier stripe.com \
--filters '{"include":{"country":["United Kingdom"]}}'
Pagination uses the same --offset and --limit behavior as semantic search.
If identifier handling is unclear for a specific seed company or the live API behavior differs, verify the current lookalike-search request contract in the official API reference.
Use Deep Search when the user wants a higher-precision asynchronous company search, wants explicit criteria, or is comfortable waiting for a task.
Typical asks:
Create a task:
<extruct_api_cli> deep-search create --payload '{"query":"AI procurement startups serving enterprise finance teams","desired_num_results":25}'
Create a task with explicit criteria:
<extruct_api_cli> deep-search create --payload-file criteria.json
criteria.json:
{
"query": "vertical SaaS companies serving freight forwarding",
"desired_num_results": 25,
"criteria": [
{
"key": "has_logistics_focus",
"name": "Logistics Focus",
"criterion": "Company serves freight forwarding or logistics operations."
},
{
"key": "b2b_fit",
"name": "B2B Fit",
"criterion": "Company sells primarily to business buyers."
}
]
}
Inspect, poll, read results, or request more:
<extruct_api_cli> deep-search list --limit 20
<extruct_api_cli> deep-search get <task_id>
<extruct_api_cli> deep-search poll <task_id>
<extruct_api_cli> deep-search results <task_id> --limit 20 --offset 0
<extruct_api_cli> deep-search resume <task_id> --payload '{"desired_new_results":25}'
Deep Search notes:
deep-search results can be read while the task is still runningdeep-search poll completes when status == "done" or is_exhausted == truecriteria, prefer --payload-file over inline --payloadIf Deep Search payload fields, task states, or resume behavior are unclear, verify them against the official API reference before constructing raw fallback requests.
Read references/finding-companies.md when the task is a fuller company-discovery workflow instead of a single search command.
Use these commands when the user already has a table and wants to inspect it, change rows or columns, run new work, or read results.
Typical asks:
If table payload shape, row schema, or run behavior is unclear, check the official API reference before mutating live tables:
Use this when the user needs a new table before doing anything else.
<extruct_api_cli> tables create --payload '{
"name":"Target Accounts",
"kind":"company"
}'
If the user supplied a table URL, extract the table id first and use that id for all CLI commands below.
<extruct_api_cli> tables list --limit 20
<extruct_api_cli> tables get <table_id>
<extruct_api_cli> columns list <table_id>
<extruct_api_cli> tables data <table_id> --limit 20 --offset 0
<extruct_api_cli> tables data <table_id> --limit 20 --offset 0 --columns company_name,company_website
<extruct_api_cli> rows get <table_id> <row_id>
Update metadata:
<extruct_api_cli> tables update <table_id> --payload '{
"name":"Target Accounts - Updated",
"description":"High-priority accounts for enrichment"
}'
Clone or delete:
<extruct_api_cli> tables clone <table_id> --schema-only
<extruct_api_cli> tables delete <table_id> --yes
--schema-only clones the columns and structure without copying row data.
Without --schema-only, clone copies both schema and rows.
Use company domains or URLs as the safest input on company tables.
Default to "run": false while iterating so you can inspect rows and columns before spending more work. Only switch to "run": true when the user explicitly wants add-and-run in one step.
Before deleting, inspect either the specific row with rows get or a small tables data page so you only remove the intended records.
Create rows:
<extruct_api_cli> rows create <table_id> --payload '{
"rows":[
{"data":{"input":"extruct.ai"}},
{"data":{"input":"stripe.com"}}
],
"run":false
}'
Update rows:
<extruct_api_cli> rows update <table_id> --payload '{
"rows":[
{
"id":"<row_id>",
"data":{"input":"https://extruct.ai"}
}
],
"run":false
}'
Delete rows:
<extruct_api_cli> rows delete <table_id> --yes --payload '{
"rows":[
"<row_id_1>",
"<row_id_2>"
]
}'
Row-deletion notes:
rows delete requires --yesRead references/column-guide.md before designing or changing columns. Prefer built-in column kinds before custom prompts.
If a column kind, payload field, or validation rule in this skill looks stale, verify the current table and column contract in the official API reference before retrying.
Add a simple research column:
<extruct_api_cli> columns add <table_id> --payload '{
"column_configs":[
{
"kind":"agent",
"name":"Latest Funding",
"key":"latest_funding",
"value":{
"agent_type":"research_pro",
"prompt":"What is the latest funding round for the company? Return round type, amount, date, and lead investors when available.",
"output_format":"text"
}
}
]
}'
Update a column:
<extruct_api_cli> columns update <table_id> <column_id> --payload '{
"kind":"agent",
"name":"Latest Funding",
"key":"latest_funding",
"value":{
"agent_type":"research_pro",
"prompt":"What is the latest funding round for the company? Return round type, amount, date, and lead investors when available.",
"output_format":"text"
}
}'
Delete a column:
<extruct_api_cli> columns delete <table_id> <column_id> --yes
Default incremental run:
<extruct_api_cli> tables run <table_id>
<extruct_api_cli> tables run <table_id> --payload '{
"mode":"new",
"columns":["<column_id_1>","<column_id_2>"]
}'
Poll and then read a small result page:
<extruct_api_cli> tables poll <table_id>
<extruct_api_cli> tables data <table_id> --limit 20 --offset 0
<extruct_api_cli> tables data <table_id> --limit 20 --offset 0 --columns company_name,latest_funding
Table-operation defaults:
mode: "new" when iterating on an existing tabletables run <table_id> is shorthand for {"mode":"new"}new, all, and failed--columns whenever you only need a surgical slice of the dataWhen creating a table, choose the kind from the entity the rows represent:
company: use when rows are companies and the user wants company research, enrichment, scoring, or company-to-people branchingpeople: use when rows are people or contacts and the user wants email, phone, LinkedIn, or derived people fieldsgeneric: use only when rows are neither companies nor peopleFor generic tables:
references/column-guide.md more directly and design prompts, dependencies, and output formats explicitlyUse company tables when the user wants custom enrichment over a set of companies or wants to run repeatable company research workflows.
Company table notes:
company tables automatically include input, company_profile, company_name, and company_websiteIf the user needs a fresh company table, create one:
<extruct_api_cli> tables create --payload '{
"name":"Target Accounts",
"kind":"company"
}'
Then use the existing-table commands above to:
references/column-guide.mdmode: "new"Read references/researching-companies.md when the task is a full company-research workflow instead of a single table operation.
Use this path when the user starts from companies and wants decision-makers, leadership, or contactable people.
If child-table behavior, finder output shape, or workflow handoff details differ from what this skill expects, verify the current API behavior in the official API reference.
Start from a company table, then add a company_people_finder column:
<extruct_api_cli> columns add <company_table_id> --payload '{
"column_configs":[
{
"kind":"company_people_finder",
"name":"Decision Makers",
"key":"decision_makers",
"value":{
"roles":["VP Sales","sales leadership","revenue operations"]
}
}
]
}'
Run only the new finder column and poll:
<extruct_api_cli> tables run <company_table_id> --payload '{
"mode":"new",
"columns":["<people_finder_column_id>"]
}'
<extruct_api_cli> tables poll <company_table_id>
Then inspect the parent table to find the generated child people table in child_relationships, and continue there:
<extruct_api_cli> tables get <company_table_id>
The parent company table will also show the people-finder cell result, but the child people table is the place to continue downstream enrichment.
Use broader role families for coverage, such as sales leadership, and exact titles for narrower targeting, such as VP Sales. Read references/finding-people-at-companies.md when the task is a full company-to-people workflow.
Use this path when the user already has people rows or already has a generated child people table and now wants enrichment, contact data, or derived fields.
Typical asks:
People-table notes:
people tables automatically include input, full_name, role, and profile_urlinputemail_finder or phone_finder, company_website must exist under the exact key company_websitepeople tables, custom agent columns can use llm, research_reasoning, and linkedin; research_pro is not allowedIf people-table capabilities, supported column kinds, or enrichment requirements appear to have changed, verify them in the official API reference before proceeding.
Create a standalone people table with local website context:
<extruct_api_cli> tables create --payload '{
"name":"Target Contacts",
"kind":"people",
"column_configs":[
{
"kind":"input",
"name":"Company Website",
"key":"company_website"
}
]
}'
Add people rows:
<extruct_api_cli> rows create <people_table_id> --payload '{
"rows":[
{
"data":{
"input":"Jane Doe, VP Sales, https://linkedin.com/in/jane-doe",
"company_website":"extruct.ai"
}
}
],
"run":false
}'
Add contact or derived columns:
<extruct_api_cli> columns add <people_table_id> --payload '{
"column_configs":[
{
"kind":"email_finder",
"name":"Work Email",
"key":"work_email"
},
{
"kind":"phone_finder",
"name":"Direct Phone",
"key":"direct_phone"
}
]
}'
Run, poll, and inspect:
<extruct_api_cli> tables run <people_table_id> --payload '{
"mode":"new",
"columns":["<column_id_1>","<column_id_2>"]
}'
<extruct_api_cli> tables poll <people_table_id>
<extruct_api_cli> tables data <people_table_id> --limit 20 --offset 0
Read references/researching-people.md when the task is a full people-research workflow.
Run:
<extruct_api_cli> auth user
<extruct_api_cli> healthcheck
If auth user fails, the token or account context is wrong. If healthcheck fails too, treat it as connectivity or service health.
If the auth flow, expected status codes, or healthcheck contract has changed, defer to the official API reference.
--filters for country, city, size, or founded rangeCommon causes:
{pricing_notes} pointing at a missing keyjson columns without an output_schemaCheck references/column-guide.md before retrying.
Common causes:
Checks:
done cells in any upstream dependency columnsmode: "new"Check that:
inputcompany_website exists under the exact key company_websiteselect, multiselect, numeric, money, date, grade, or json instead of defaulting to textjson unless the user explicitly wants those fields as table datallm after researching the source fact once429, treat it as billing or quota rejection, not a tight-loop retry signal5xx, wait 5-10 seconds and retry once--pretty for human-readable JSON--timeout <seconds> to override request timeout--base-url <url> to override the API base URL<extruct_api_cli> tables list --limit 20 --prettyreferences/column-guide.md: column design rules plus a comprehensive library of good column configsreferences/finding-companies.md: choose and operate semantic search, lookalike, and Deep Searchreferences/researching-companies.md: build or extend company research tables safelyreferences/finding-people-at-companies.md: branch from company tables into people workflowsreferences/researching-people.md: enrich standalone or generated people tables