# AI Tables Basics Source: https://docs.extruct.ai/api-guides/ai-tables/ai-table-basics Create a table, add rows, run agents, and read results. ## Overview This guide walks through a repeatable company-table workflow: create a table, add rows, run enrichment, and read the results. You can start with companies discovered in Extruct or with your own list of company domains or URLs. ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Create table (`POST /v1/tables`)](/api-reference/tables/create-table) * [Add rows (`POST /v1/tables/:table_id/rows`)](/api-reference/tables/create-table-rows) * [Run table (`POST /v1/tables/:table_id/run`)](/api-reference/tables/run-table) * [Get table (`GET /v1/tables/:table_id`)](/api-reference/tables/get-table) * [Get table data (`GET /v1/tables/:table_id/data`)](/api-reference/tables/get-table-data) ## Workflow ### 1) Create a table The create-table response includes `id`, which you will reuse as `TABLE_ID`. ```bash theme={null} TABLE_RESPONSE=$(curl -sS -X POST "https://api.extruct.ai/v1/tables" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "name": "Company Research", "kind": "company", "column_configs": [ { "kind": "input", "name": "Company", "key": "input" }, { "kind": "agent", "name": "Description", "key": "description", "value": { "agent_type": "research_pro", "prompt": "Describe what the company does in 2 short sentences.", "output_format": "text" } } ] }') TABLE_ID=$(echo "${TABLE_RESPONSE}" | jq -r '.id') echo "${TABLE_ID}" ``` Requires `jq`. If unavailable, copy `id` manually from response. ### 2) Add rows These rows can come from Extruct search results, Deep Search output, or your own company list. For `company` tables, the most reliable `input` value is the company's official website domain or URL. ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/rows" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "rows": [ {"data": {"input": "https://extruct.ai"}}, {"data": {"input": "https://openai.com"}} ], "run": false }' ``` After rows are added, Extruct can populate built-in company fields such as `company_profile`, `company_name`, and `company_website`. Use [Column Guide](/api-guides/ai-tables/column-guide) for minimum working shapes, column-selection rules, and prompt guidance. Use [Column Library](/api-guides/ai-tables/column-library) when you want fuller reusable templates and common chains. ### 3) Run the table ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/run" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{"mode": "new"}' ``` ### 4) Check status ```bash theme={null} curl --get "https://api.extruct.ai/v1/tables/${TABLE_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` Proceed when `run_status` is `idle` and `num_cells_in_progress` is `0`. ### 5) Read enriched rows ```bash theme={null} curl --get "https://api.extruct.ai/v1/tables/${TABLE_ID}/data" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=50" ``` ## Troubleshooting ### `401 Unauthorized` The token is missing or invalid. Check that `EXTRUCT_API_TOKEN` is set and the header is exactly `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `422 Unprocessable Entity` The payload shape is invalid. Common issues: * `rows` must be an array of row objects with `data`. * `column_configs` entries must include required fields by column type. * `run` must be boolean when provided. Validate your payload JSON before sending: `echo '' | jq empty`. # Column Guide Source: https://docs.extruct.ai/api-guides/ai-tables/column-guide Choose the right column kind, agent type, and output format for AI Tables. ## Overview This guide explains how to choose and configure AI Tables columns for company research, people discovery, contact enrichment, and scoring. It is actionable on its own: each supported column kind below includes the minimum working shape, required context, and the most common mistake. ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Create columns (`POST /v1/tables/:table_id/columns`)](/api-reference/tables/create-table-columns) * [Update column (`PATCH /v1/tables/:table_id/columns/:column_id`)](/api-reference/tables/update-table-column) * [Delete column (`DELETE /v1/tables/:table_id/columns/:column_id`)](/api-reference/tables/delete-table-column) * [Run table (`POST /v1/tables/:table_id/run`)](/api-reference/tables/run-table) * [Get table (`GET /v1/tables/:table_id`)](/api-reference/tables/get-table) * [Get table data (`GET /v1/tables/:table_id/data`)](/api-reference/tables/get-table-data) ## Column Guide in 60 Seconds A column is one field Extruct fills for each row. Every column has `kind`, `name`, and `key`. Some kinds also have `value`. If `kind` is `agent`, you also choose `agent_type`, `output_format`, and a prompt. Typical shape: ```json theme={null} { "kind": "agent", "name": "Description", "key": "company_description", "value": { "agent_type": "research_pro", "prompt": "Describe what the company does in under 25 words.", "output_format": "text" } } ``` Exceptions: * `input`, `email_finder`, and `phone_finder` do not need a `value` block * `reverse_email_lookup` uses top-level `email_column_key` instead of `value` ### Column kinds at a glance All column kinds require `kind`, `name`, and `key`. | Kind | What it does | What you provide | | ------------------------------------------------- | -------------------------------------------- | --------------------------------------- | | [`input`](#input) | stores a value you already have | the row value | | [`agent`](#agent) | researches, reasons, or transforms one field | `agent_type`, `prompt`, `output_format` | | [`company_people_finder`](#company_people_finder) | finds people at each company by role | `roles` | | [`email_finder`](#email_finder) | finds a work email for a person | nothing extra | | [`phone_finder`](#phone_finder) | finds a phone number for a person | nothing extra | | [`reverse_email_lookup`](#reverse_email_lookup) | resolves profile data from a known email | `email_column_key` | ### If `kind = agent` `agent` is the core Extruct pattern. After choosing `kind: "agent"`, you choose the agent behavior, the output shape, and the prompt. | Choice | What it controls | | -------------------------------------------- | --------------------------------------- | | [`agent_type`](#agent-types) | how Extruct gets or produces the answer | | [`output_format`](#output-formats) | the shape of the returned result | | [`prompt`](#dependencies-and-prompt-writing) | the exact job the column should do | ### Agent types at a glance | Agent type | Best for | Not best for | | ------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------- | | [`research_pro`](#research_pro) | researched answers on `company` tables | `people` or `generic` tables, direct contact lookups, LinkedIn fetch from a known URL | | [`research_reasoning`](#research_reasoning) | researched answers on `people` and `generic` tables | company-table use cases that need company-context disambiguation | | [`llm`](#llm) | transforming data already in the row | web research or source discovery | | [`linkedin`](#linkedin) | LinkedIn data from a known LinkedIn URL | discovering the LinkedIn URL in the first place | ### Output formats at a glance | Format | Use for | Extra required fields | | ----------------------------- | ------------------------------------- | --------------------- | | [`text`](#text) | prose or notes | none | | [`url`](#url) | one canonical URL | none | | [`email`](#email) | one email-shaped answer from an agent | none | | [`select`](#select) | exactly one allowed option | `labels` | | [`multiselect`](#multiselect) | zero or more allowed options | `labels` | | [`numeric`](#numeric) | counts and measured values | none | | [`money`](#money) | structured financial values | none | | [`date`](#date) | exact or partial dates | none | | [`phone`](#phone) | one phone number in structured form | none | | [`grade`](#grade) | bounded scoring with explanation | none | | [`json`](#json) | nested schema-defined output | `output_schema` | ### Fast defaults * On `company` tables, start with the official website domain or URL as `input` * On `company` tables, default to `kind: "agent"` and `agent_type: "research_pro"` * On `people` and `generic` tables, use `kind: "agent"` and `agent_type: "research_reasoning"` * On `company` tables, choose `research_reasoning` only if you intentionally want to skip the company-context disambiguation step * For scoring, use `output_format: "grade"` * For people or contact workflows, prefer `company_people_finder`, `email_finder`, `phone_finder`, or `reverse_email_lookup` over generic prompts * When you add new columns, rerun only the new column IDs with `mode: "new"` ## Choose the right column kind Use the simplest column kind that matches the result you want back. ### `input` What it does: * stores a value you already have When to use it: * company website domain or URL * manual notes * internal tags or metadata * local helper fields such as `company_website` on a standalone `people` table Minimum config: ```json theme={null} { "kind": "input", "name": "Company", "key": "input" } ``` Context it needs: * none; you provide the value directly in row `data` Best practice: * on `company` tables, the preferred `input` is the company's official website domain or URL * a raw company name is a weaker fallback when you do not have the site What it returns: * exactly the row value you send Most common mistake: * using weak company names as the default company input when you already have a domain or URL ### `agent` What it does: * researches, reasons, or transforms one field When to use it: * research a company fact * classify a company or person * summarize upstream evidence * return structured output such as `select`, `money`, `grade`, or `json` Minimum config: ```json theme={null} { "kind": "agent", "name": "Description", "key": "company_description", "value": { "agent_type": "research_pro", "prompt": "Describe what the company does in under 25 words.", "output_format": "text" } } ``` Context it needs: * on `company` tables, Extruct auto-injects company context * on `people` tables, Extruct auto-injects person context * on `generic` tables, use explicit prompt references for the row fields you need What it returns: * one value in the output format you choose Most common mistake: * one prompt tries to do multiple jobs or references `{input}` unnecessarily on `company` or `people` tables ### `company_people_finder` What it does: * finds people at each company by role When to use it: * branch from company research into a people workflow * find leadership, decision-makers, or role-based contact targets Minimum config: ```json theme={null} { "kind": "company_people_finder", "name": "Decision Makers", "key": "decision_makers", "value": { "roles": ["VP Sales", "sales leadership", "revenue operations"] } } ``` Context it needs: * a `company` table with the correct company rows What it returns or creates: * fills the finder cell on the company table * creates or updates a child `people` table for downstream enrichment Good role style: * broader role families for coverage: `sales leadership`, `engineering leadership` * exact titles for narrower targeting: `CEO`, `Head of Engineering` Most common mistake: * adding it to a `people` table or using overly narrow role strings before checking coverage ### `email_finder` What it does: * finds a work email for a person When to use it: * enrich a `people` table after person rows already exist Minimum config: ```json theme={null} { "kind": "email_finder", "name": "Work Email", "key": "work_email" } ``` Context it needs: * `full_name` * `profile_url` * `company_website` `company_website` can come from: * a parent company row, or * a local `people`-table input column keyed exactly `company_website` What it returns: * one work email or no result Most common mistake: * adding the column before `company_website` exists or trying to configure it with a `value` block ### `phone_finder` What it does: * finds a phone number for a person When to use it: * enrich a `people` table after person rows already exist Minimum config: ```json theme={null} { "kind": "phone_finder", "name": "Direct Phone", "key": "direct_phone" } ``` Context it needs: * `full_name` * `profile_url` * `company_website` `company_website` can come from: * a parent company row, or * a local `people`-table input column keyed exactly `company_website` What it returns: * one phone number or no result Most common mistake: * expecting high coverage without first verifying that the person rows and company website context are strong ### `reverse_email_lookup` What it does: * resolves person or profile data from an email you already have When to use it: * you already have an email column and want profile resolution rather than company-to-people branching Minimum config: ```json theme={null} { "kind": "reverse_email_lookup", "name": "Profile from Email", "key": "profile_from_email", "email_column_key": "work_email" } ``` Context it needs: * a source email column keyed in `email_column_key` What it returns: * person or profile metadata such as name, headline, location, and profile URL Most common mistake: * putting `email_column_key` inside `value` or using this when the real job is company-to-people discovery ## Agent types Agent types change what Extruct can do for a custom `agent` column. `research_pro` and `research_reasoning` can both research, reason, and make judgments. The difference is whether Extruct first disambiguates the requested company using company context before answering. | Agent type | Best for | What it actually does | | -------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | `research_pro` | researched answers on `company` tables | web research plus Extruct DB search and similar-company retrieval, with a company-context disambiguation step | | `research_reasoning` | researched answers on `people` and `generic` tables | the same general research tool class, but without the company-context disambiguation step | | `llm` | row-local transformation | transforms existing row data only; no web research | | `linkedin` | LinkedIn data from a known LinkedIn URL | uses LinkedIn company or profile lookup behavior | Research agents cannot do these jobs directly: * fetch LinkedIn data from a known LinkedIn URL * find people at a company by role * find work emails * find phone numbers * resolve a person from an email Use these instead: * `linkedin` * `company_people_finder` * `email_finder` * `phone_finder` * `reverse_email_lookup` ### `research_pro` Use this for researched answers on `company` tables. What makes it different: * it uses the same general research and reasoning capability as `research_reasoning` * before answering, it gathers or confirms company context * it uses that company context to disambiguate whether the evidence belongs to the requested company or to some other company Good fits: * pricing and packaging * funding or valuation * target segments * recent news * product or use-case research * competitor or alternative discovery * canonical company URLs such as LinkedIn or careers pages Default role: * this is the safe default for custom `agent` columns on `company` tables * use it unless you intentionally want to skip the disambiguation step and you know the entity is already clear ### `research_reasoning` Use this for researched answers when you do not want the company-context disambiguation step. What makes it different: * it uses the same general research and reasoning capability as `research_pro` * it does not start with the company-context disambiguation step * it is the default research agent on `people` and `generic` tables * on `company` tables, it is an expert choice when the entity is already clear and you intentionally want to skip the disambiguation step Good fits: * official-site disambiguation * custom 1-5 scoring * SMB vs enterprise judgments * ranked comparisons * researched answers on `generic` tables ### `llm` Use this for row-local transformation only. What to expect: * no web research * no page visits * no source URLs * cheaper downstream transformation after a research step already happened Good fits: * turn notes into a `select` * summarize several upstream columns * normalize messy evidence * derive structured `json` from row context ### `linkedin` Use this when the row already has a known LinkedIn company or person URL and you want LinkedIn-derived data. Typical chain: 1. use `research_pro` to find the right LinkedIn URL 2. use `linkedin` to fetch LinkedIn data 3. use `llm` to summarize or classify that data Important `people`-table rule: * custom `agent` columns on `people` tables can use `llm`, `research_reasoning`, and `linkedin` * `research_pro` is not supported on custom `agent` columns on `people` tables ## Built-in company and people context ### `company` tables `company` tables automatically create and fill: * `company_profile` * `company_name` * `company_website` This is why most company-table prompts should be plain natural-language instructions. Weak: ```text theme={null} Research the company {input} and summarize what it does. ``` Strong: ```text theme={null} Describe what the company does in under 25 words. ``` ### `people` tables Custom `agent` columns on `people` tables get baseline row context automatically: * `full_name` * `profile_url` * `role` Use plain natural-language prompts when that baseline context is enough. Add explicit prompt references only when the column depends on another custom field or a local input field. Weak: ```text theme={null} Classify this person using {input}. ``` Strong: ```text theme={null} Classify this person's seniority level based on their current role. ``` Example where an explicit reference is appropriate: ```text theme={null} Choose the company's pricing model based on: Pricing Notes --- {pricing_notes} --- ``` ## Output formats Choose the output format that best matches how you will use the result. | Output format | Best for | Example | | ------------- | -------------------------------- | ------------------- | | `text` | short prose or notes | company description | | `url` | one canonical URL | careers page | | `email` | one email address | normalized email | | `select` | one allowed option | pricing model | | `multiselect` | zero or more allowed options | markets served | | `numeric` | counts or measured values | employee count | | `money` | structured financial values | annual revenue | | `date` | exact or partial dates | founded date | | `phone` | one phone number | direct phone | | `grade` | bounded scoring with explanation | ICP fit | | `json` | nested structured output | competitors list | Guidance: * use `text` for short prose meant to be read directly * use `select` or `multiselect` when the answer should stay within labels * use `money` for revenue, ARR, valuation, or funding * use `grade` for scoring * use `json` only when the structure is genuinely useful downstream For custom `agent` columns, the main result lives in `rows[].data..value.answer`. What changes by `output_format` is the shape of `answer`. Supporting fields such as `explanation` and `sources` may sit alongside it in `rows[].data..value`. ### `text` Use this for prose or short notes that will be read directly. Minimum config: ```json theme={null} { "kind": "agent", "name": "Description", "key": "company_description", "value": { "agent_type": "research_pro", "prompt": "Describe what the company does in under 25 words.", "output_format": "text" } } ``` Typical returned shape: ```json theme={null} { "answer": "AI research automation for company and people workflows.", "explanation": "Company site and product messaging describe structured research automation.", "sources": ["https://extruct.ai"] } ``` Best practice: * use `text` only when the result is meant to be read directly; if you need filtering or sorting later, prefer a structured format ### `url` Use this for one canonical URL. Minimum config: ```json theme={null} { "kind": "agent", "name": "Careers URL", "key": "careers_page_url", "value": { "agent_type": "research_pro", "prompt": "Find the company's official careers or jobs page URL.", "output_format": "url" } } ``` Typical returned shape: ```json theme={null} { "answer": "https://extruct.ai/careers", "explanation": "This is the company's official careers page.", "sources": ["https://extruct.ai/careers"] } ``` Best practice: * ask for the single best URL only; do not ask for a list unless you actually need a `json` structure ### `email` Use this when you want one email-shaped answer from a custom `agent`. Minimum config: ```json theme={null} { "kind": "agent", "name": "Support Email", "key": "support_email", "value": { "agent_type": "research_pro", "prompt": "Find the company's primary support email address.", "output_format": "email" } } ``` Typical returned shape: ```json theme={null} { "answer": "support@extruct.ai", "explanation": "The support contact is listed on the company's website.", "sources": ["https://extruct.ai"] } ``` Best practice: * if the real job is finding a work email for a person, prefer `email_finder` ### `select` Use this for exactly one allowed option. Minimum config: ```json theme={null} { "kind": "agent", "name": "Pricing Model", "key": "pricing_model", "value": { "agent_type": "llm", "prompt": "Select the company's primary pricing model.\n\nPricing Notes\n---\n{pricing_notes}\n---", "output_format": "select", "labels": ["Free", "Freemium", "Subscription", "Usage-Based", "Custom Quote"] } } ``` `labels` is required in the column config. Typical returned shape: ```json theme={null} { "answer": { "value": "Subscription" }, "explanation": "The company sells recurring subscription plans.", "sources": ["https://extruct.ai/pricing"] } ``` Best practice: * labels should be stable categories, not free-form text or sentence-length answers ### `multiselect` Use this for zero or more allowed options. Minimum config: ```json theme={null} { "kind": "agent", "name": "Markets Served", "key": "markets_served", "value": { "agent_type": "research_reasoning", "prompt": "Select the markets this company clearly serves.", "output_format": "multiselect", "labels": ["SMB", "Mid-Market", "Enterprise", "Public Sector", "Healthcare"] } } ``` `labels` is required in the column config. Typical returned shape: ```json theme={null} { "answer": { "values": ["Mid-Market", "Enterprise"] }, "explanation": "The company shows clear messaging for larger commercial customers.", "sources": ["https://extruct.ai"] } ``` Best practice: * use `multiselect` only when multiple labels can legitimately be true at the same time ### `numeric` Use this for counts, ranges, or measured values. Minimum config: ```json theme={null} { "kind": "agent", "name": "Employee Count", "key": "employee_count", "value": { "agent_type": "research_pro", "prompt": "How many employees does the company currently have?", "output_format": "numeric" } } ``` Typical returned shape: ```json theme={null} { "answer": { "value": 5234, "min_value": null, "max_value": null, "unit": "employees", "max_possible": null }, "explanation": "Recent company sources point to approximately 5,234 employees.", "sources": ["https://example.com"] } ``` Best practice: * prefer `numeric` over `text` when the result may be sorted, filtered, or bucketed later ### `money` Use this for structured financial values such as revenue, ARR, valuation, or funding. Minimum config: ```json theme={null} { "kind": "agent", "name": "Annual Revenue", "key": "annual_revenue", "value": { "agent_type": "research_pro", "prompt": "What is the company's latest annual revenue or ARR?", "output_format": "money" } } ``` Typical returned shape: ```json theme={null} { "answer": { "amount": 15000000, "min_amount": null, "max_amount": null, "currency": "USD", "period": "annual" }, "explanation": "The latest reliable figure is approximately $15M annually.", "sources": ["https://example.com"] } ``` Best practice: * prefer `money` over prose for any financial figure you may compare or score later ### `date` Use this for exact dates, partial dates, or date ranges. Minimum config: ```json theme={null} { "kind": "agent", "name": "Founded Date", "key": "founded_date", "value": { "agent_type": "research_pro", "prompt": "When was the company founded?", "output_format": "date" } } ``` Typical returned shape: ```json theme={null} { "answer": { "year": 2021, "month": null, "day": null, "end_year": null, "end_month": null, "end_day": null }, "explanation": "Only the founding year is clearly supported by the available sources.", "sources": ["https://example.com"] } ``` Best practice: * partial dates are valid and expected; do not force full day-level precision when the source does not support it ### `phone` Use this for one phone number in structured form. Minimum config: ```json theme={null} { "kind": "agent", "name": "Main Phone", "key": "main_phone", "value": { "agent_type": "research_pro", "prompt": "Find the company's primary phone number.", "output_format": "phone" } } ``` Typical returned shape: ```json theme={null} { "answer": { "number": "+14155552671", "country_code": "1", "extension": null }, "explanation": "This is the main published company phone number.", "sources": ["https://example.com"] } ``` Best practice: * if the real job is finding a phone number for a person, prefer `phone_finder` ### `grade` Use this when you want a bounded score plus an explanation. The recommended scoring pattern is a custom `agent` column with `output_format: "grade"`. Example: ```json theme={null} { "kind": "agent", "name": "Enterprise Fit", "key": "enterprise_fit", "value": { "agent_type": "research_reasoning", "prompt": "Assess this statement about the company: The company clearly sells to enterprise customers. Use the default 1-5 grade scale. If there is not enough evidence to score confidently, return Not found.", "output_format": "grade" } } ``` Default scale: * `5`: strong yes * `4`: likely yes * `3`: mixed, partial, or uncertain * `2`: likely no * `1`: strong no * `Not found`: not enough evidence to score confidently Typical returned shape: ```json theme={null} { "answer": 4, "explanation": "Strong mid-market and enterprise signals, but not purely enterprise-only.", "sources": ["https://example.com"] } ``` `Not found` shape: ```json theme={null} { "answer": "Not found", "explanation": "Not enough reliable evidence to score this confidently.", "sources": [] } ``` ### `json` Use this for user-defined nested output. Minimum config: ```json theme={null} { "kind": "agent", "name": "Competitors", "key": "competitors", "value": { "agent_type": "research_pro", "prompt": "Find the company's closest competitors and alternatives. Return one object with a competitors array. Each competitor should include name, domain, and short_reason.", "output_format": "json", "output_schema": { "type": "object", "properties": { "competitors": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "domain": { "type": "string" }, "short_reason": { "type": "string" } } } } } } } } ``` `output_schema` is required. Typical returned shape: ```json theme={null} { "answer": { "competitors": [ { "name": "Example Co", "domain": "example.com", "short_reason": "Targets the same buyer with a similar core workflow." } ] }, "explanation": "These companies are the closest alternatives based on product and buyer overlap.", "sources": ["https://example.com"] } ``` Best practice: * unlike the fixed formats above, the shape of `answer` is defined by your `output_schema` ## Dependencies and prompt writing For custom `agent` columns, dependencies come from: * prompt references such as `{pricing_notes}` * `extra_dependencies` Prompt references are usually the clearest default because the dependency is visible in the prompt itself. Use `extra_dependencies` only when you intentionally need an upstream dependency that is not referenced in the prompt. Dependency example: ```json theme={null} { "kind": "agent", "name": "Pricing Model", "key": "pricing_model", "value": { "agent_type": "llm", "prompt": "Select the company's primary pricing model.\n\nPricing Notes\n---\n{pricing_notes}\n---", "output_format": "select", "labels": ["Free", "Freemium", "Subscription", "Usage-Based", "Custom Quote"] } } ``` Prompt writing rules: * each column should do one job * say exactly what artifact should come back * prefer natural-language prompts on `company` and `people` tables * use explicit prompt references only when a column truly depends on another custom field Research prompt pattern: ```text theme={null} Find the company's official careers page URL. Return the single best URL only. ``` Competitor discovery pattern: ```text theme={null} Find the company's closest competitors and alternatives. Prefer companies that solve the same core problem for a similar buyer. Return one object with a competitors array. Each competitor should include name, domain, and short_reason. If you are not confident a company is a real competitor, leave it out. ``` ## Troubleshooting ### Unresolved column references Cause: * the prompt references a missing column key Fix: * create the source column first * or change the prompt to reference an existing key ### Column is not compatible with the table kind Common examples: * `company_people_finder` on a `people` table * `research_pro` custom `agent` columns on a `people` table ### Cells never start running Cause: * upstream dependency cells are not done Fix: * inspect the source columns first * keep dependency chains short * rerun only the new column IDs with `mode: "new"` ### Results are hard to reuse downstream Cause: * too many `text` outputs Fix: * move repeated decisions into `select`, `multiselect`, `numeric`, `money`, `date`, `phone`, `grade`, or `json` ### A column feels too expensive Cause: * web research is being used for a transformation problem Fix: * research the source fact once * derive downstream fields with `llm` ## Recommended defaults If you are unsure: * default to `company` tables * default to official website domain or URL as company-table `input` * default to built-in or purpose-built column kinds when available * default to `research_pro` on `company` tables * default to `research_reasoning` on `people` and `generic` tables * on `company` tables, switch to `research_reasoning` only when you intentionally want to skip company-context disambiguation * default to `llm` for downstream transformations * default to `agent` + `grade` for scoring * default to plain natural-language prompts on `company` and `people` tables * add explicit prompt references only for intentional chaining or on `generic` tables For fuller reusable configs and multi-step patterns, continue to [Column Library](/api-guides/ai-tables/column-library). # Column Library Source: https://docs.extruct.ai/api-guides/ai-tables/column-library Reusable AI Tables column configs and common chains. ## Overview This page collects fuller reusable column templates for AI Tables. [Column Guide](/api-guides/ai-tables/column-guide) covers how to choose and configure columns, including minimum working shapes. This page is the cookbook: copy a pattern, then adapt `name`, `key`, prompts, labels, and schemas to your workflow. ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Create columns (`POST /v1/tables/:table_id/columns`)](/api-reference/tables/create-table-columns) * [Update column (`PATCH /v1/tables/:table_id/columns/:column_id`)](/api-reference/tables/update-table-column) * [Run table (`POST /v1/tables/:table_id/run`)](/api-reference/tables/run-table) * [Get table data (`GET /v1/tables/:table_id/data`)](/api-reference/tables/get-table-data) ## How to use these templates Wrap one or more template objects in `column_configs`, then send them to [Create columns](/api-reference/tables/create-table-columns). Wrapper example: ```json theme={null} { "column_configs": [ { "kind": "agent", "name": "Description", "key": "company_description", "value": { "agent_type": "research_pro", "prompt": "Describe what the company does in under 25 words.", "output_format": "text" } } ] } ``` Before you copy: * on `company` tables, built-in company fields are created automatically * on `company` and `people` tables, custom agent columns get baseline row context automatically * most prompts on `company` and `people` tables should not mention `company_name`, `company_website`, `full_name`, `profile_url`, or `role` explicitly * if a template references another column, that dependency is intentional When you add new columns to an existing table, usually run only the new work with `mode: "new"`. ## Company research templates ### Description ```json theme={null} { "kind": "agent", "name": "Description", "key": "company_description", "value": { "agent_type": "research_pro", "prompt": "Describe what the company does in under 25 words.", "output_format": "text" } } ``` ### ICP Summary ```json theme={null} { "kind": "agent", "name": "ICP Summary", "key": "icp_summary", "value": { "agent_type": "research_pro", "prompt": "Identify the company's ideal customer profile. Summarize the primary buyer, company type, and likely use case in 2-3 short bullet points.", "output_format": "text" } } ``` ### Employee Count ```json theme={null} { "kind": "agent", "name": "Employee Count", "key": "employee_count", "value": { "agent_type": "research_pro", "prompt": "How many employees does the company currently have?", "output_format": "numeric" } } ``` ### Annual Revenue ```json theme={null} { "kind": "agent", "name": "Annual Revenue", "key": "annual_revenue", "value": { "agent_type": "research_pro", "prompt": "What is the company's latest annual revenue or ARR? Prefer the most recent reliable figure and use revenue, not total funding.", "output_format": "money" } } ``` ### Founded Date ```json theme={null} { "kind": "agent", "name": "Founded Date", "key": "founded_date", "value": { "agent_type": "research_pro", "prompt": "When was the company founded?", "output_format": "date" } } ``` ### Pricing Notes ```json theme={null} { "kind": "agent", "name": "Pricing Notes", "key": "pricing_notes", "value": { "agent_type": "research_pro", "prompt": "Summarize the company's pricing model and publicly visible price points as a short bulleted list. Include plan names and prices when available.", "output_format": "text" } } ``` ### Recent News ```json theme={null} { "kind": "agent", "name": "Recent News", "key": "recent_news", "value": { "agent_type": "research_pro", "prompt": "List the company's most important news from the last 12 months, newest first. Include date, headline, and URL.", "output_format": "json", "output_schema": { "type": "object", "properties": { "articles": { "type": "array", "items": { "type": "object", "properties": { "date": { "type": "string" }, "headline": { "type": "string" }, "url": { "type": "string" } } } } } } } } ``` ### Competitors ```json theme={null} { "kind": "agent", "name": "Competitors", "key": "competitors", "value": { "agent_type": "research_pro", "prompt": "Find the company's closest competitors and alternatives. Prefer companies that solve the same core problem for a similar buyer. Return one object with a competitors array. Each competitor should include name, domain, and short_reason. If you are not confident a company is a real competitor, leave it out.", "output_format": "json", "output_schema": { "type": "object", "properties": { "competitors": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "domain": { "type": "string" }, "short_reason": { "type": "string" } } } } } } } } ``` ### Expansion Signals ```json theme={null} { "kind": "agent", "name": "Expansion Signals", "key": "expansion_signals", "value": { "agent_type": "research_pro", "prompt": "Identify and summarize the company's expansion signals using job postings, press releases, new office mentions, executive hires, and product launches. Focus on geographic, product, or market expansion. Return a short evidence-dense summary with dates when available.", "output_format": "text" } } ``` ## URLs and LinkedIn templates ### LinkedIn Company URL ```json theme={null} { "kind": "agent", "name": "LinkedIn URL", "key": "linkedin_company_url", "value": { "agent_type": "research_pro", "prompt": "Find the company's official LinkedIn company page URL.", "output_format": "url" } } ``` ### LinkedIn Company Data Requires: * `linkedin_company_url` ```json theme={null} { "kind": "agent", "name": "LinkedIn Data", "key": "linkedin_company_data", "value": { "agent_type": "linkedin", "prompt": "{linkedin_company_url}", "output_format": "text" } } ``` ### LinkedIn Activity Summary Requires: * `linkedin_company_data` ```json theme={null} { "kind": "agent", "name": "LinkedIn Activity", "key": "linkedin_activity_summary", "value": { "agent_type": "llm", "prompt": "Summarize the recent LinkedIn activity as a bulleted list with names, dates, and links.\n\nLinkedIn Company Data\n---\n{linkedin_company_data}\n---", "output_format": "text" } } ``` ### Careers Page URL ```json theme={null} { "kind": "agent", "name": "Careers URL", "key": "careers_page_url", "value": { "agent_type": "research_pro", "prompt": "Find the company's official careers or jobs page URL.", "output_format": "url" } } ``` ### Crunchbase URL ```json theme={null} { "kind": "agent", "name": "Crunchbase URL", "key": "crunchbase_url", "value": { "agent_type": "research_pro", "prompt": "Find the company's Crunchbase profile URL.", "output_format": "url" } } ``` ## Derived `llm` templates ### Pricing Model Requires: * `pricing_notes` ```json theme={null} { "kind": "agent", "name": "Pricing Model", "key": "pricing_model", "value": { "agent_type": "llm", "prompt": "Select the company's primary pricing model.\n\nPricing Notes\n---\n{pricing_notes}\n---", "output_format": "select", "labels": [ "Free", "Freemium", "Subscription", "Usage-Based", "Custom Quote", "One-Time Purchase", "Marketplace Take Rate" ] } } ``` ### HQ Country From Company Profile Requires: * `company_profile` ```json theme={null} { "kind": "agent", "name": "HQ Country", "key": "hq_country", "value": { "agent_type": "llm", "prompt": "Extract the company's headquarters country from this company profile.\n\nCompany Profile\n---\n{company_profile}\n---", "output_format": "text" } } ``` ### Revenue Band Requires: * `annual_revenue` ```json theme={null} { "kind": "agent", "name": "Revenue Band", "key": "revenue_band", "value": { "agent_type": "llm", "prompt": "Classify the company's revenue into exactly one band based on this structured revenue data.\n\nAnnual Revenue\n---\n{annual_revenue}\n---", "output_format": "select", "labels": [ "<$1M", "$1M-$10M", "$10M-$50M", "$50M-$100M", "$100M-$500M", "$500M+" ] } } ``` ### Buyer Type Requires: * `company_description` ```json theme={null} { "kind": "agent", "name": "Buyer Type", "key": "buyer_type", "value": { "agent_type": "llm", "prompt": "Select the company's primary buyer type.\n\nDescription\n---\n{company_description}\n---", "output_format": "select", "labels": [ "SMB", "Mid-Market", "Enterprise", "Consumer", "Developer", "Public Sector", "Healthcare Providers", "Financial Institutions" ] } } ``` ### Prioritization JSON Requires: * `company_profile` * `expansion_signals` * `annual_revenue` * `recent_news` ```json theme={null} { "kind": "agent", "name": "Prioritization", "key": "prioritization", "value": { "agent_type": "llm", "prompt": "You are a go-to-market analyst. Score ICP fit and buying intent. Return ONLY valid JSON with: icp_fit_score, icp_fit_reasoning, buying_intent_score, buying_intent_reasoning, positive_signals, negative_signals, recommended_action, recommended_action_reasoning, outreach_hook.\n\nCompany Profile\n---\n{company_profile}\n---\n\nExpansion Signals\n---\n{expansion_signals}\n---\n\nAnnual Revenue\n---\n{annual_revenue}\n---\n\nRecent News\n---\n{recent_news}\n---", "output_format": "json", "output_schema": { "type": "object", "properties": { "icp_fit_score": { "type": "number" }, "icp_fit_reasoning": { "type": "string" }, "buying_intent_score": { "type": "number" }, "buying_intent_reasoning": { "type": "string" }, "positive_signals": { "type": "array", "items": { "type": "string" } }, "negative_signals": { "type": "array", "items": { "type": "string" } }, "recommended_action": { "type": "string" }, "recommended_action_reasoning": { "type": "string" }, "outreach_hook": { "type": "string" } } } } } ``` If you want people-finder evidence in downstream scoring, first create a separate `llm` summary column from the people output, then reference that summary instead of the raw `company_people_finder` result. ## People and contact templates ### Leadership Finder ```json theme={null} { "kind": "company_people_finder", "name": "Leadership", "key": "leadership", "value": { "roles": [ "CEO", "Founder", "operations leadership", "revenue leadership" ] } } ``` ### Engineering Leadership Finder ```json theme={null} { "kind": "company_people_finder", "name": "Engineering Leaders", "key": "engineering_leaders", "value": { "roles": [ "Head of Engineering", "VP Engineering", "platform leadership", "security leadership" ] } } ``` ### Decision Makers ```json theme={null} { "kind": "company_people_finder", "name": "Decision Makers", "key": "decision_makers", "value": { "roles": [ "VP Sales", "sales leadership", "revenue operations", "business development leadership" ] } } ``` ### Work Email Requires: * `full_name` * `profile_url` * `company_website` Configure with `kind`, `name`, and `key` only; no `value` field needed. ```json theme={null} { "kind": "email_finder", "name": "Work Email", "key": "work_email" } ``` ### Direct Phone Requires: * `full_name` * `profile_url` * `company_website` Configure with `kind`, `name`, and `key` only; no `value` field needed. ```json theme={null} { "kind": "phone_finder", "name": "Direct Phone", "key": "direct_phone" } ``` ### Department ```json theme={null} { "kind": "agent", "name": "Department", "key": "department", "value": { "agent_type": "llm", "prompt": "Classify this person into the most likely department based on their current role.", "output_format": "select", "labels": [ "Executive", "Engineering", "Product", "Design", "Sales", "Marketing", "Operations", "Finance", "HR", "Legal", "Customer Success", "Other" ] } } ``` ### Seniority ```json theme={null} { "kind": "agent", "name": "Seniority", "key": "seniority", "value": { "agent_type": "llm", "prompt": "Classify this person's seniority level based on their current role.", "output_format": "select", "labels": [ "C-Level", "VP", "Head", "Director", "Manager", "Individual Contributor", "Founder" ] } } ``` ### Reverse Email Lookup ```json theme={null} { "kind": "reverse_email_lookup", "name": "Profile from Email", "key": "profile_from_email", "email_column_key": "work_email" } ``` ## Scoring templates All scoring examples below use the recommended pattern: `agent` + `output_format: "grade"`. ### Market Fit Score ```json theme={null} { "kind": "agent", "name": "Market Fit", "key": "market_fit", "value": { "agent_type": "research_reasoning", "prompt": "Assess this statement about the company: The company fits a B2B fintech ICP. Use the default 1-5 grade scale. If there is not enough evidence to score confidently, return Not found.", "output_format": "grade" } } ``` ### Execution Readiness Score ```json theme={null} { "kind": "agent", "name": "Execution Readiness", "key": "execution_readiness", "value": { "agent_type": "research_reasoning", "prompt": "Assess this statement about the company: The company looks ready for near-term partnership or outreach. Use the default 1-5 grade scale. If there is not enough evidence to score confidently, return Not found.", "output_format": "grade" } } ``` ### AI-Native Score ```json theme={null} { "kind": "agent", "name": "AI Native", "key": "is_ai_native", "value": { "agent_type": "research_pro", "prompt": "Assess this statement about the company: The company is fundamentally AI-native rather than merely adding lightweight AI features. Use the default 1-5 grade scale. If there is not enough evidence to score confidently, return Not found.", "output_format": "grade" } } ``` ### Enterprise Fit Score ```json theme={null} { "kind": "agent", "name": "Enterprise Fit", "key": "enterprise_fit", "value": { "agent_type": "research_pro", "prompt": "Assess this statement about the company: The company clearly sells to enterprise customers. Use the default 1-5 grade scale. If there is not enough evidence to score confidently, return Not found.", "output_format": "grade" } } ``` ### Competitive Axis Score ```json theme={null} { "kind": "agent", "name": "SMB vs Enterprise", "key": "axis_smb_enterprise", "value": { "agent_type": "research_reasoning", "prompt": "Evaluate where this company sits on the spectrum from SMB to Enterprise. Consider pricing, sales model, product complexity, and customer size. Use this scale: 1 = pure SMB, 3 = mid-market, 5 = pure enterprise. If there is not enough evidence to score confidently, return Not found.", "output_format": "grade" } } ``` ## Common chains ### URL -> LinkedIn fetch -> summary 1. `linkedin_company_url` 2. `linkedin_company_data` 3. `linkedin_activity_summary` ### Research -> classification 1. `pricing_notes` 2. `pricing_model` ### Company -> people -> contact enrichment 1. `company_people_finder` 2. `email_finder` 3. `phone_finder` For design guidance before copying templates, go back to [Column Guide](/api-guides/ai-tables/column-guide). # Company Enrichment Source: https://docs.extruct.ai/api-guides/ai-tables/company-enrichment Enrich a company list with research columns at scale. ## Overview This guide walks through adding research columns and running structured enrichment on a company list. The inputs can come from Extruct discovery or from your own company list. ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Create table (`POST /v1/tables`)](/api-reference/tables/create-table) * [Create columns (`POST /v1/tables/:table_id/columns`)](/api-reference/tables/create-table-columns) * [Add rows (`POST /v1/tables/:table_id/rows`)](/api-reference/tables/create-table-rows) * [Run table (`POST /v1/tables/:table_id/run`)](/api-reference/tables/run-table) * [Get table data (`GET /v1/tables/:table_id/data`)](/api-reference/tables/get-table-data) ## Workflow ### 1) Create a base table The create-table response includes `id`, which you will reuse as `TABLE_ID`. ```bash theme={null} TABLE_RESPONSE=$(curl -sS -X POST "https://api.extruct.ai/v1/tables" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "name": "Enrichment Pipeline", "kind": "company", "column_configs": [ { "kind": "input", "name": "Company", "key": "input" } ] }') TABLE_ID=$(echo "${TABLE_RESPONSE}" | jq -r '.id') echo "${TABLE_ID}" ``` Requires `jq`. If unavailable, copy `id` manually from response. ### 2) Add enrichment columns Use [Column Guide](/api-guides/ai-tables/column-guide) for minimum working shapes, agent-type guidance, output formats, and prompt rules. Use [Column Library](/api-guides/ai-tables/column-library) when you want fuller reusable templates and scoring patterns. ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/columns" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "column_configs": [ { "kind": "agent", "name": "Short Description", "key": "short_description", "value": { "agent_type": "research_pro", "prompt": "Summarize what the company does in 2 sentences.", "output_format": "text" } }, { "kind": "agent", "name": "Target Audience", "key": "target_audience", "value": { "agent_type": "research_pro", "prompt": "Describe the company's core buyer or user.", "output_format": "text" } } ] }' ``` ### 3) Add company rows and run ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/rows" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "rows": [ {"data": {"input": "https://stripe.com"}}, {"data": {"input": "https://openai.com"}}, {"data": {"input": "https://anthropic.com"}} ], "run": true }' ``` ### 4) Check run status ```bash theme={null} curl --get "https://api.extruct.ai/v1/tables/${TABLE_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` Proceed when `run_status` is `idle` and `num_cells_in_progress` is `0`. ### 5) Read enriched output ```bash theme={null} curl --get "https://api.extruct.ai/v1/tables/${TABLE_ID}/data" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=100" ``` ## Troubleshooting ### `401 Unauthorized` The token is missing or invalid. Check that `EXTRUCT_API_TOKEN` is set and the header is exactly `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `422 Unprocessable Entity` Common causes: * Invalid column config shape for `agent` columns. * Missing required `data` in row payloads. * Invalid JSON body. Validate your payload JSON before sending: `echo '' | jq empty`. # Deep Research Source: https://docs.extruct.ai/api-guides/research/deep-research Run asynchronous deep research tasks that produce cited reports on companies and people. ## Overview Deep Research takes a free-text brief about one research target — a company, a person, or a team — and produces a cited report. A reasoning agent plans the research, fans out research agents that gather evidence from the web and Extruct's data sources, reviews what came back, and synthesizes the result. It is implemented through the `deep_research_tasks` endpoints in API Reference. ## This Path Works Best When * You want a deep, sourced report on one target: account planning, buyer research, initiative summaries, diligence. * You are researching a person before outreach or a meeting: who they are, what their team owns, and the best angle to open a conversation. * You need every claim backed by citations, or structured output that downstream systems can parse. * You are willing to wait minutes for an asynchronous task in exchange for depth. ## Choose Another Path If * You want to discover many companies matching criteria. Use [Deep Search](/api-guides/search/deep-search). * You want repeatable enrichment across a list of companies. Use [AI Tables](/api-guides/ai-tables/ai-table-basics). * You need one company's profile facts instantly. Use [Company Lookup](/api-reference/company-lookup). ## Prerequisites Deep Research requires a **Pro plan**, and starting a task requires the full depth budget in available credits (see Costs below). ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Create task (`POST /v1/deep_research_tasks`)](/api-reference/deep-research/create-deep-research-task) * [Get task (`GET /v1/deep_research_tasks/:task_id`)](/api-reference/deep-research/get-deep-research-task) * [List tasks (`GET /v1/deep_research_tasks`)](/api-reference/deep-research/list-deep-research-tasks) ## Workflow ### 1) Create a task Write the brief like a request to a research analyst: a detailed paragraph naming the target, your own context (what you sell or research, who your buyer is), and the decision the report should support. Detailed, specific briefs reliably produce better reports than one-liners — "Help me break into Shell" is a bad brief; the example below is a good one. ```bash theme={null} TASK_RESPONSE=$(curl -sS -X POST "https://api.extruct.ai/v1/deep_research_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "brief": "We sell a cloud cost-optimization platform to large enterprises; typical buyers are VPs of Infrastructure and FinOps leads. I am preparing outreach to Shell. Research how Shell'"'"'s IT and digital organization is structured, who owns cloud infrastructure and FinOps decisions, which cloud, data, or efficiency initiatives they announced in the last 18 months, and which vendors or system integrators they already work with. I want practical conversation angles tied to live initiatives, plus any signals of cost-cutting programs or budget pressure.", "depth": "medium" }') TASK_ID=$(echo "${TASK_RESPONSE}" | jq -r '.id') echo "${TASK_ID}" ``` Requires `jq`. If unavailable, copy `id` manually from the response. People are first-class targets too — include your own context and the profile to research: ```bash theme={null} curl -sS -X POST "https://api.extruct.ai/v1/deep_research_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "brief": "Here is my company: example.com. We sell AI-powered sales-enablement software to mid-market B2B teams. Research this person and the team they work with: https://www.linkedin.com/in/example-profile. I want their role and scope, what their team owns, recent initiatives or public statements, tools they already use, and the best angle to open a conversation.", "depth": "medium" }' ``` ### 2) Poll until done ```bash theme={null} curl --get "https://api.extruct.ai/v1/deep_research_tasks/${TASK_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` Poll every 10–15 seconds. While running, the counters show progress: `iterations` (analysis steps), `agents` (research agents completed), `sources` (unique sources collected). The task is finished when `status` is `done` or `failed`. ### 3) Read the report For a markdown task, `report.kind` is `"markdown"`: the markdown cites sources with bracketed ids like `[1]` that resolve against `report.sources` (id → URL). ```bash theme={null} curl -sS --get "https://api.extruct.ai/v1/deep_research_tasks/${TASK_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" | jq -r '.report.markdown' ``` Always check `report.degradation_reasons`. It lists, in plain language, anything that reduced coverage — research stopped at its budget or step limit, or some research agents failed. Empty for a clean run. Show these notes to your users alongside the report. If `status` is `failed`, read `failure_reason`: a rejected brief includes suggestions for fixing it, and failed tasks refund all their charges. ## Structured reports (schema mode) Pass an `output_schema` and the report comes back as JSON matching your schema instead of markdown. The schema must be a JSON Schema object (`"type": "object"`). We validate it the moment you create the task, so a bad schema fails right away with a `422` rather than wasting a run. **Keep it small** — up to 5 levels of nesting and 50 properties, with root `#/$defs/` for shared definitions. A handful of decision-relevant fields beats a sprawling schema: depth and breadth push the model to pad fields instead of grounding them in evidence. ```bash theme={null} curl -sS -X POST "https://api.extruct.ai/v1/deep_research_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "brief": "We provide fraud-prevention APIs for fintech platforms and are building an account plan for Stripe. Summarize Stripe'"'"'s enterprise product initiatives from the last 12 months, identify concrete product or partnership angles where a fraud-prevention vendor could plug in, and flag risks that could stall a deal.", "depth": "high", "output_schema": { "type": "object", "properties": { "summary": {"type": "string"}, "recommended_angles": {"type": "array", "items": {"type": "string"}}, "risks": {"type": "array", "items": {"type": "string"}} }, "required": ["summary", "recommended_angles", "risks"] } }' ``` When the task is `done`, `report.fields` holds your values, guaranteed to validate against the schema. There is no separate citations object to join back to your fields. If you want sources, ask for them in the schema (below). ### Sources and reasoning, inline Wrap any value in an **Evidenced** object to get its provenance back beside it. It has three properties: `value` (your schema for the data), `sources` (the source URLs), and `reasoning` (one sentence). We fill `sources` and `reasoning` from the research and keep only URLs we actually fetched — an invented source is dropped. Nothing to parse or join: the evidence sits next to the value. Wrap at the level you want cited — a whole object for one citation per entity, each array item for one per record, or a single field. Unwrapped fields come back as plain values. ```json theme={null} { "type": "object", "properties": { "people": { "type": "array", "items": { "type": "object", "required": ["value", "sources", "reasoning"], "properties": { "value": { "type": "object", "properties": { "name": {"type": "string"}, "role": {"type": "string"} } }, "sources": {"type": "array", "items": {"type": "string"}}, "reasoning": {"type": "string"} } } } } } ``` The evidence comes back inline with each value: ```json theme={null} { "people": [ { "value": {"name": "Juan Perez", "role": "CEO"}, "sources": ["https://www.linkedin.com/in/juan-perez"], "reasoning": "LinkedIn lists them as the current CEO." } ] } ``` ## Costs * `depth` sets the research-agent budget: `medium` = 5, `high` = 15, `xhigh` = 25. * Each research agent that runs costs 2 credits. Starting a task reserves the full budget in available credits (`medium` = 10, `high` = 30, `xhigh` = 50), but you are billed only for agents that actually run. A focused brief often finishes well under budget. * Failed tasks — rejected briefs, mid-run credit exhaustion, internal errors — refund all their charges. # Deep Search Source: https://docs.extruct.ai/api-guides/search/deep-search Run asynchronous discovery tasks for criteria-based candidate evaluation. ## Overview Deep Search is the asynchronous discovery path for cases where instant index-based search is not enough. It ranks companies against natural-language criteria using web, Extruct DB, Maps, and LinkedIn, and is implemented through the `discovery_tasks` endpoints in API Reference. ## This Path Works Best When * Ranking depends on qualitative criteria that are hard to express as firmographic filters. * You need explanations and criterion-level scoring for each result. * You are willing to wait for an asynchronous task in exchange for more deliberate evaluation. ## Choose Another Path If * You want fast recall-first exploration over the Extruct index. Use [Semantic Search](/api-guides/search/semantic-search). * You already have a strong seed company and want instant similarity expansion. Use [Lookalike Search](/api-guides/search/lookalike-search). ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Create task (`POST /v1/discovery_tasks`)](/api-reference/discover/create-company-discovery-task) * [Get task (`GET /v1/discovery_tasks/:task_id`)](/api-reference/discover/get-company-discovery-task) * [Get results (`GET /v1/discovery_tasks/:task_id/results`)](/api-reference/discover/get-company-discovery-task-results) * [Resume task (`POST /v1/discovery_tasks/:task_id/resume`)](/api-reference/discover/resume-company-discovery-task) ## Workflow ### 1) Create a Deep Search task Set `desired_num_results` to your target. Task target is capped at `250`. If you omit `criteria`, Extruct infers evaluation criteria from `query`. The create-task response includes `id`, which you will reuse as `TASK_ID`. ```bash theme={null} TASK_RESPONSE=$(curl -sS -X POST "https://api.extruct.ai/v1/discovery_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "query": "vertical SaaS companies serving freight forwarding", "desired_num_results": 150 }') TASK_ID=$(echo "${TASK_RESPONSE}" | jq -r '.id') echo "${TASK_ID}" ``` Requires `jq`. If unavailable, copy `id` manually from response. Optional: to define the scoring rubric yourself, use this alternate create request instead of the minimal one above. ```bash theme={null} TASK_RESPONSE=$(curl -sS -X POST "https://api.extruct.ai/v1/discovery_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "query": "vertical SaaS companies serving freight forwarding", "desired_num_results": 150, "criteria": [ { "key": "has_logistics_focus", "name": "Logistics Focus", "criterion": "Company serves freight forwarding or logistics operations." }, { "key": "b2b_gtm", "name": "B2B GTM Fit", "criterion": "Company sells primarily to business buyers." } ] }') TASK_ID=$(echo "${TASK_RESPONSE}" | jq -r '.id') echo "${TASK_ID}" ``` ### 2) Check task progress Use task status and counters to monitor progress (`num_results_discovered`, `num_results_enriched`, `num_results_evaluated`, `num_results`). ```bash theme={null} curl --get "https://api.extruct.ai/v1/discovery_tasks/${TASK_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` When to proceed: continue after `num_results_evaluated` starts increasing. ### 3) Retrieve results with pagination ```bash theme={null} RESULTS_RESPONSE=$(curl -sS --get "https://api.extruct.ai/v1/discovery_tasks/${TASK_ID}/results" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=50") echo "${RESULTS_RESPONSE}" | jq '.results[0]' ``` Example result fragment: ```json theme={null} { "company_name": "FreightFlow", "company_website": "https://freightflow.example", "relevance": 86, "scores": { "has_logistics_focus": { "grade": 5, "explanation": "Primary product serves freight forwarding operations.", "sources": ["https://freightflow.example/about"] }, "b2b_gtm": { "grade": 4, "explanation": "Positioning and case studies are B2B-focused.", "sources": ["https://freightflow.example/customers"] } } } ``` Rule of thumb: shortlist candidates with `grade` 4-5 on must-have criteria and no `grade` below 3 on blockers. Use `explanation` and `sources` for manual verification before enrichment. When to proceed: move forward once you have enough high-fit candidates for your workflow. ### 4) Resume discovery when needed Use resume to request additional results while staying within the task cap. ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/discovery_tasks/${TASK_ID}/resume" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{"desired_new_results": 25}' ``` ### 5) Re-run with exclusions (optional) Resume is the right tool when you want more results from the same query and criteria. When you want to **change** the query or criteria but skip companies you've already reviewed, start a new task and reference the prior one with `exclude_task_ids`. The new task's results exclude all companies returned by the referenced task at creation time. You can also pass an explicit `exclude_domains` list. ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/discovery_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d "{ \"query\": \"vertical SaaS companies serving freight forwarding in EMEA\", \"desired_num_results\": 100, \"exclude_task_ids\": [\"${TASK_ID}\"], \"exclude_domains\": [\"acme.com\"] }" ``` Up to 100 task IDs and a combined cap of 1000 unique resolved domains. Exclusions are frozen at task creation — referenced tasks aren't re-read later. ### 6) Move selected companies to AI Tables After reviewing Deep Search output, you can move shortlisted companies into AI Tables for enrichment and scoring. This is only one handoff path. AI Tables also works independently when you already have your own company list. Use this handoff snippet to map the returned `company_website` into AI Tables `rows[].data.input`: ```bash theme={null} SHORTLIST_INPUT=$(echo "${RESULTS_RESPONSE}" | jq -r '.results[0].company_website') curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/rows" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d "{\"rows\":[{\"data\":{\"input\":\"${SHORTLIST_INPUT}\"}}],\"run\":false}" ``` If you are starting fresh, create `TABLE_ID` first in [AI Tables Basics](/api-guides/ai-tables/ai-table-basics). ## When to choose Deep Search over index search Prefer Deep Search over Semantic Search or Lookalike Search when the ranking depends on criteria like: * whether a company serves a specific workflow or sub-vertical * whether it sells to a specific buyer or team * whether it meets a custom ICP definition * whether you need explicit evidence for why each company ranked well If your need is mostly "find more companies like this" or "search broadly and filter by firmographics," stay on the instant index-based paths first. ## Troubleshooting ### `401 Unauthorized` The token is missing or invalid. Check that `EXTRUCT_API_TOKEN` is set and the header is exactly `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `422 Unprocessable Entity` Common causes: * Invalid JSON body. * `desired_num_results` or `desired_new_results` out of allowed range. * Unsupported request fields. * An entry in `exclude_domains` that cannot be parsed as a domain, or the resolved exclusion set exceeds 1000 domains. Validate your request body locally before sending: `echo '' | jq empty`. ### Task progress seems slow Deep Search is asynchronous and includes criteria evaluation per candidate. Track progress through task status and counters. Poll every 15-30 seconds and continue while `num_results_evaluated` is increasing. # Lookalike Search Source: https://docs.extruct.ai/api-guides/search/lookalike-search Find companies similar to a reference company using the Lookalike endpoint. New integrations should use [`POST /v1/companies/{company_identifier}/similar`](/api-reference/lookalike-search-post), which takes `filters` as a JSON object. The `GET` form shown below still works but is deprecated. ## Overview Lookalike Search ranks companies by similarity to a reference company from the same Extruct index used by Semantic Search. It takes a company domain or UUID as input and blends what a company does, who it sells to, firmographics, and traffic into a single ranking. ## This Path Works Best When * You trust one company as a good market proxy. * You want expansion around a known winner, competitor, or target account. * Filters should refine results, but the seed company should drive ranking. ## Choose Another Path If * You do not yet have a strong seed company. Start with [Semantic Search](/api-guides/search/semantic-search). * You need custom natural-language evaluation criteria instead of index-based similarity. Use [Deep Search](/api-guides/search/deep-search). ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Company Lookup endpoint (`GET /v1/companies/:company_identifier`)](/api-reference/company-lookup) * [Lookalike endpoint (`GET /v1/companies/:company_identifier/similar`)](/api-reference/lookalike-search) * [Search endpoint (`GET /v1/companies/search`)](/api-reference/search) ## Workflow ### 1) Choose `company_identifier` `company_identifier` can be: * A domain, for example `stripe.com` * A UUID If you need a seed company first, use [Semantic Search](/api-guides/search/semantic-search) and prefer `results[].domain`. Use `results[].id` only if `domain` is missing. ```bash theme={null} COMPANY_IDENTIFIER="stripe.com" ``` ### 2) Run lookalike query ```bash theme={null} curl --get "https://api.extruct.ai/v1/companies/${COMPANY_IDENTIFIER}/similar" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ### 3) Apply filters if needed ```bash theme={null} curl --get "https://api.extruct.ai/v1/companies/${COMPANY_IDENTIFIER}/similar" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode 'filters={"include":{"country":["United States"]},"exclude":{"size":["1-10"]}}' \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` For filter rules, use [Search Filters Reference](/api-guides/search/search-filters-reference). To exclude specific companies (for example, ones you already have), add `exclude.domains` to your `filters`. For a list too large for a `GET` URL, use [`POST /v1/companies/:company_identifier/similar`](/api-reference/lookalike-search-post). ### 4) Page through results * Page 1: `offset=0&limit=20` * Page 2: `offset=20&limit=20` * Page 3: `offset=40&limit=20` Each request returns at most 250 results (the page size). Free tokens can read up to 25 results per query; paid plans (Starter, Pro) can page through up to 2,000. Keep advancing `offset` until you reach your plan ceiling or a page returns fewer rows than `limit`. ## Choosing a strong seed company Lookalike quality depends heavily on the seed. Use a company that clearly represents the market you want, not just a well-known brand in the general space. Good seeds: * Sell to the same buyer you care about. * Have similar company shape or go-to-market motion. * Are specific enough that "similar" means something useful. Weak seeds: * Very broad platforms with many unrelated products. * Household names that dominate a category but are not representative. * Companies that overlap only superficially with your target market. If you do not trust any single seed, use [Semantic Search](/api-guides/search/semantic-search) first or move to [Deep Search](/api-guides/search/deep-search) for explicit criteria. If you want the full profile for one known company instead of similar-company results, use [Company Lookup](/api-reference/company-lookup). ## Troubleshooting ### `401 Unauthorized` The token is missing or invalid. Check that `EXTRUCT_API_TOKEN` is set and the header is exactly `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The reference company is not found in the index. Try another domain/UUID. Reuse a known seed from semantic search (`results[].domain` or `results[].id`) to confirm identifier validity. ### `422 Unprocessable Entity` The `filters` JSON is malformed or includes unsupported keys. Validate your filters JSON before sending: `echo '' | jq empty`. # Search Filters Reference Source: https://docs.extruct.ai/api-guides/search/search-filters-reference Supported filters format for semantic and lookalike search. ## Overview This page documents the `filters` JSON shape supported by semantic and lookalike search. ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Search endpoint (`GET /v1/companies/search`)](/api-reference/search) * [Lookalike endpoint (`GET /v1/companies/:company_identifier/similar`)](/api-reference/lookalike-search) * [Search endpoint (`POST /v1/companies/search`)](/api-reference/search-post) * [Lookalike endpoint (`POST /v1/companies/:company_identifier/similar`)](/api-reference/lookalike-search-post) ## Filters shape On the `GET` endpoints, send `filters` as a JSON string (URL-encoded). On the `POST` endpoints, send `filters` as a native JSON object in the request body. ```json theme={null} { "include": { "country": ["United States"] }, "exclude": { "size": ["1-10"] }, "range": { "founded": { "min": 2018, "max": 2024 } } } ``` All sections are optional. `range.founded.max` shown here is an example value, not a product limit. ## Supported fields | Field path | Type | Meaning | | ------------------- | ---------- | ---------------------------------------------------------------------------------- | | `include.size` | `string[]` | Keep these company size buckets. | | `include.country` | `string[]` | Keep these countries. | | `include.city` | `string[]` | Keep these cities. | | `exclude.size` | `string[]` | Remove these company size buckets. | | `exclude.country` | `string[]` | Remove these countries. | | `exclude.city` | `string[]` | Remove these cities. | | `exclude.domains` | `string[]` | Remove companies by domain or URL (normalized server-side, alias-aware, max 1000). | | `range.founded.min` | `integer` | Keep companies founded on/after year. | | `range.founded.max` | `integer` | Keep companies founded on/before year. | `exclude.domains` accepts company domains or full URLs; each is normalized to its registered domain, so `https://www.stripe.com/pricing`, `stripe.com`, and `blog.stripe.com` all exclude `stripe.com`. A large exclusion list does not fit a `GET` URL — use the `POST` endpoints for lists beyond a few hundred domains. ## Supported size values Use exact values: * `1-10` * `11-50` * `51-200` * `201-500` * `501-1000` * `1001-5000` * `5001-10000` * `10001+` ## Copy-paste request example ```bash theme={null} curl --get "https://api.extruct.ai/v1/companies/search" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "q=fintech treasury automation" \ --data-urlencode 'filters={"include":{"country":["United States"],"size":["51-200"]},"range":{"founded":{"min":2018}}}' \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` For a large `exclude.domains` list, POST `filters` as a JSON object instead: ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/companies/search" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"q":"fintech treasury automation","filters":{"exclude":{"domains":["stripe.com","adyen.com"]}},"pagination":{"offset":0,"limit":20}}' ``` ## Troubleshooting ### `422 Unprocessable Entity` The `filters` JSON is malformed or includes unsupported keys. Validate your filters JSON before sending: `echo '' | jq empty`. ### Filter returns no results Start broad, then narrow one filter dimension at a time. Remove all but one filter group (`include`, `exclude`, or `range`) and re-run to find the limiting condition. # Semantic Search Source: https://docs.extruct.ai/api-guides/search/semantic-search Find companies from natural-language intent using the Search endpoint. New integrations should use [`POST /v1/companies/search`](/api-reference/search-post), which takes `filters` as a JSON object. The `GET` form shown below still works but is deprecated. ## Overview Semantic Search is the recall-first company search path over the Extruct index. Start with a natural-language query, then narrow with firmographic filters such as country, city, size, and founded year. ## This Path Works Best When * You want broad market coverage before narrowing. * You want to explore a category, use case, ICP, or problem space quickly. * You expect filters to do most of the refinement work. ## Choose Another Path If * You already know the company and want its full profile. Use [Company Lookup](/api-reference/company-lookup). * You already have a strong seed company and want similarity ranking instead. Use [Lookalike Search](/api-guides/search/lookalike-search). * You need custom ranking criteria and evidence-backed evaluation. Use [Deep Search](/api-guides/search/deep-search). ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Endpoints used * [Company Lookup endpoint (`GET /v1/companies/:company_identifier`)](/api-reference/company-lookup) * [Search endpoint (`GET /v1/companies/search`)](/api-reference/search) * [Lookalike endpoint (`GET /v1/companies/:company_identifier/similar`)](/api-reference/lookalike-search) ## Workflow ### 1) Run a broad semantic query ```bash theme={null} curl --get "https://api.extruct.ai/v1/companies/search" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "q=vertical SaaS for logistics procurement" \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ### 2) Narrow with filters ```bash theme={null} curl --get "https://api.extruct.ai/v1/companies/search" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "q=b2b treasury automation" \ --data-urlencode 'filters={"include":{"country":["United States"],"size":["51-200","201-500"]},"range":{"founded":{"min":2018}}}' \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` For supported filter fields and values, use [Search Filters Reference](/api-guides/search/search-filters-reference). To exclude specific companies, add `exclude.domains` to your `filters`. For a list too large for a `GET` URL, use [`POST /v1/companies/search`](/api-reference/search-post). ### 3) Page through results Use fixed increments for stable pagination: * Page 1: `offset=0&limit=20` * Page 2: `offset=20&limit=20` * Page 3: `offset=40&limit=20` Each request returns at most 250 results (the page size). Free tokens can read up to 25 results per query; paid plans (Starter, Pro) can page through up to 2,000. Keep advancing `offset` until you reach your plan ceiling or a page returns fewer rows than `limit`. ### 4) Expand top seeds with lookalike After selecting a high-quality company from search results, prefer `results[].domain` as `company_identifier` for lookalike. Use `results[].id` only if `domain` is missing. Use [Company Lookup](/api-reference/company-lookup) with the same identifier when you want the full company profile instead of similar companies. ```bash theme={null} COMPANY_IDENTIFIER="stripe.com" curl --get "https://api.extruct.ai/v1/companies/${COMPANY_IDENTIFIER}/similar" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ### 5) Escalate to Deep Search when filters are not enough Move to [Deep Search](/api-guides/search/deep-search) when you can describe the companies you want in natural language, but firmographic filters still do not produce the ranking quality you need. Typical signs: * Results are relevant but poorly ordered. * The distinction you care about is qualitative, not just firmographic. * You need explicit scoring and explanations for each candidate. ## Troubleshooting ### `401 Unauthorized` The token is missing or invalid. Check that `EXTRUCT_API_TOKEN` is set and the header is exactly `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `422 Unprocessable Entity` The `filters` JSON is malformed or includes unsupported keys. Use only keys listed in [Search Filters Reference](/api-guides/search/search-filters-reference). Validate your filters JSON before sending: `echo '' | jq empty`. # Authentication Source: https://docs.extruct.ai/api-reference/authentication Learn how to authenticate into Extruct API. ## When to use Use this page before calling any endpoint. Every Extruct API request requires a Bearer token. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/user" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` Generate and manage tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). ## Key parameters * `Authorization` header (required): `Bearer ${EXTRUCT_API_TOKEN}`. ## Success signal A successful auth check returns your user object with fields such as `email` and `available_credits`. ## Common errors ### `401 Unauthorized` Most common causes are a missing token, invalid token, or missing `Bearer ` prefix. ## Related endpoints * [Get User (`GET /v1/user`)](/api-reference/user) # Lookup Company Profile Source: https://docs.extruct.ai/api-reference/company-lookup GET /v1/companies/{company_identifier} Look up the full Extruct profile for a known company. ## Overview Company Lookup returns the canonical enriched Extruct profile for one known company. Pass a company domain or UUID. Use this endpoint when you already know the company and want its full profile context. Use [Semantic Search](/api-reference/search) to discover companies by category or market, and [Lookalike Search](/api-reference/lookalike-search) to find similar companies. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl "https://api.extruct.ai/v1/companies/stripe.com" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` ## Key parameters * `company_identifier` (required): Company domain or UUID. ## Endpoint behavior * Domain inputs resolve through the company profile lookup path. * UUID inputs fetch that specific company profile. * If a valid domain is not ready yet, Extruct may start enrichment and return `202 Accepted`. * Company Lookup currently consumes `0` credits. Successful lookups and accepted `202` lookups still appear in usage analytics. ## Success signal A successful response returns `id`, `domain`, `company_name`, and `context`. The `context` object is the rich company profile with descriptions, products, use cases, audience, firmographics, social profiles, and sources when available. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `202 Accepted` The lookup was accepted and company enrichment is in progress. Retry the same lookup later. ```json theme={null} { "status": "enriching", "domain": "stripe.com", "message": "Company information is being enriched for domain: stripe.com" } ``` ### `404 Not Found` The company profile is not available, or the identifier is invalid. ## Related endpoints * [Semantic Search (`GET /v1/companies/search`)](/api-reference/search) * [Lookalike Search (`GET /v1/companies/{company_identifier}/similar`)](/api-reference/lookalike-search) # Create Deep Research Task Source: https://docs.extruct.ai/api-reference/deep-research/create-deep-research-task post /v1/deep_research_tasks Create a Deep Research task. ## Overview This endpoint creates a Deep Research task and returns a task ID immediately. Deep Research takes a free-text brief about one research target — a company, a person or team, an account, a market question — and produces a cited report: a reasoning agent plans the research, fans out research agents that gather evidence, and synthesizes the result. Use [Deep Search](/api-reference/discover/create-company-discovery-task) instead when you want to *discover many companies* matching criteria; use Deep Research when you want a *deep, sourced report*. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl -X POST "https://api.extruct.ai/v1/deep_research_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "brief": "We sell a cloud cost-optimization platform to large enterprises; typical buyers are VPs of Infrastructure and FinOps leads. I am preparing outreach to Shell. Research how Shell'"'"'s IT and digital organization is structured, who owns cloud infrastructure and FinOps decisions, which cloud, data, or efficiency initiatives they announced in the last 18 months, and which vendors or system integrators they already work with. I want practical conversation angles tied to live initiatives, plus any signals of cost-cutting programs or budget pressure.", "depth": "medium" }' ``` Write the brief as a detailed paragraph, not a one-liner: include what you sell or research, who the target is, what decision the report should support, and time windows that matter. The more context and specifics the brief carries, the better the report. People are first-class targets — researching a lead and the team they work with is as valid as researching a company: ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/deep_research_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "brief": "Here is my company: example.com. We sell AI-powered sales-enablement software to mid-market B2B teams. Research this person and the team they work with: https://www.linkedin.com/in/example-profile. I want their role and scope, what their team owns, recent initiatives or public statements, tools they already use, and the best angle to open a conversation.", "depth": "medium" }' ``` For a structured report, pass an `output_schema`: ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/deep_research_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "brief": "We provide fraud-prevention APIs for fintech platforms and are building an account plan for Stripe. Summarize Stripe'"'"'s enterprise product initiatives from the last 12 months, identify concrete product or partnership angles where a fraud-prevention vendor could plug in, and flag risks that could stall a deal.", "depth": "high", "output_schema": { "type": "object", "properties": { "summary": {"type": "string"}, "recommended_angles": {"type": "array", "items": {"type": "string"}}, "risks": {"type": "array", "items": {"type": "string"}} }, "required": ["summary", "recommended_angles", "risks"] } }' ``` ## Key parameters * `brief` (required): free-text research brief about a company, a person, or a team, up to 20,000 characters. Write it like a request to a research analyst — a detailed paragraph naming the target(s), your own context, and the decision the report should support. Detailed, specific briefs reliably produce better reports than one-liners. * `depth` (optional, default `medium`): the maximum research-agent budget — `medium` = 5, `high` = 15, `xhigh` = 25 agents. Each research agent that runs costs 2 credits. Starting a task reserves the full budget in available credits (`medium` = 10, `high` = 30, `xhigh` = 50); you are billed only for agents that actually run. * `output_schema` (optional): a JSON Schema object (`"type": "object"`). When present, the report is structured and guaranteed to conform to it; omit for markdown. Up to 5 levels of nesting and 50 properties, with root `#/$defs/` for shared definitions. To get sources and reasoning for a value, wrap it as an Evidenced object — `value`, `sources` (URLs), and `reasoning` — and the provenance comes back beside the value. See the [Deep Research guide](/api-guides/research/deep-research#sources-and-reasoning-inline). ## Endpoint behavior * The call validates the request and schedules the task, then returns immediately. No research runs at request time; poll with [Get Task](/api-reference/deep-research/get-deep-research-task). * Creation is all-or-nothing: a success response means the system owns delivery; on a scheduling failure (`503`) nothing was created and it is safe to retry. * Billing is per completed research agent (2 credits each). A simple brief at `xhigh` that finishes after 8 agents costs 16 credits. Failed tasks refund all their charges. * Briefs that cannot produce useful research (no identifiable target, unusable input) are rejected asynchronously: the task ends `failed` with the reasons and fix-it suggestions in `failure_reason`, and nothing is charged. ## Success signal A successful response includes the task `id` with `status: "created"`. Save `id` and poll [Get Task](/api-reference/deep-research/get-deep-research-task) until `status` is `done` or `failed`. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `402 Payment Required` Two cases, distinguished by `detail.error`: * `plan_required`: Deep Research requires a Pro plan. * `insufficient_credits`: your available credits are below the full depth budget. The detail includes `required_credits` and `available_credits` — a lower `depth` may still fit. ### `422 Unprocessable Entity` Common causes: * Empty brief, or brief longer than 20,000 characters. * `depth` outside `medium` / `high` / `xhigh` (values are lowercase). * `output_schema` is not a valid JSON Schema object — the schema is validated in full at creation time, including nested property definitions. Validate body first: ```bash theme={null} echo '' | jq empty ``` ### `503 Service Unavailable` Scheduling is temporarily unavailable. No task was created and nothing was charged — retry the call. ## Related endpoints * [Get Task Endpoint](/api-reference/deep-research/get-deep-research-task) * [List Tasks Endpoint](/api-reference/deep-research/list-deep-research-tasks) ## Related guides * [Deep Research](/api-guides/research/deep-research) # Get Deep Research Task Source: https://docs.extruct.ai/api-reference/deep-research/get-deep-research-task get /v1/deep_research_tasks/{task_id} Get a Deep Research task by ID. ## Overview This endpoint returns a Deep Research task's status, progress, and — once the task is `done` — the report. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl "https://api.extruct.ai/v1/deep_research_tasks/" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` Poll every 10–15 seconds until `status` is `done` or `failed`. Tasks typically take minutes; deeper tasks take longer. ## Reading the response * `status`: `created` → `in_progress` → `done` or `failed`. * Progress counters while running: `iterations` (analysis steps), `agents` (research agents completed — this is what is billed), `sources` (unique sources collected). * `report` is `null` until `done`, then one of two shapes tagged by `kind`: * `"kind": "markdown"` — a markdown report whose bracketed citations like `[1]` resolve against the `sources` registry (id → URL). * `"kind": "schema"` — `fields` conforming to your `output_schema`. A `done` schema report always validates against your schema. Provenance, where your schema opts in with an Evidenced wrapper, is co-located inside `fields` (`value` + `sources` + `reasoning`), so there is nothing separate to reconcile. * `report.degradation_reasons`: plain-language notes when something reduced coverage (research stopped at its budget or step limit, or some research agents failed). Empty for a clean run. **Show these to your users alongside the report.** * `failure_reason` (when `status` is `failed`): why the task failed — a rejected brief includes suggestions for fixing it. Failed tasks refund all their charges. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `403 Forbidden` The task belongs to another user outside your organization. ### `404 Not Found` No task with this ID exists. ## Related endpoints * [Create Task Endpoint](/api-reference/deep-research/create-deep-research-task) * [List Tasks Endpoint](/api-reference/deep-research/list-deep-research-tasks) ## Related guides * [Deep Research](/api-guides/research/deep-research) # List Deep Research Tasks Source: https://docs.extruct.ai/api-reference/deep-research/list-deep-research-tasks get /v1/deep_research_tasks List Deep Research tasks. ## Overview This endpoint returns your Deep Research tasks, newest first, with their current statuses and progress counters. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/deep_research_tasks" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ## Key parameters * `offset` (optional): pagination offset. * `limit` (optional): page size; defaults to `50`. ## Success signal A successful response returns an array of tasks with `id`, `status`, `brief`, `depth`, progress counters, and the `report` for finished tasks. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ## Related endpoints * [Create Task Endpoint](/api-reference/deep-research/create-deep-research-task) * [Get Task Endpoint](/api-reference/deep-research/get-deep-research-task) ## Related guides * [Deep Research](/api-guides/research/deep-research) # Create Discovery Task Source: https://docs.extruct.ai/api-reference/discover/create-company-discovery-task post /v1/discovery_tasks Create a new Deep Search task. ## Overview This endpoint creates a Deep Search task and returns a task ID immediately. Deep Search is the asynchronous discovery path for when indexed similarity and firmographic filters fall short. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl -X POST "https://api.extruct.ai/v1/discovery_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "query": "vertical SaaS companies serving freight forwarding", "desired_num_results": 100 }' ``` ## Key parameters * `query` (required): Natural-language description of companies to find. * `desired_num_results` (optional): target result count; default `100`, min `1`, max `250`. * `auto_data_sources` (optional): default `true`. * `data_sources` (optional): ignored when `auto_data_sources=true`. * `criteria` (optional): explicit criterion definitions; each is graded 1-5 in results. If omitted, criteria are inferred from `query`. * `exclude_domains` (optional): domains or URLs to exclude from results. Server normalizes each entry to its registered domain (`https://www.Acme.com/about` → `acme.com`). Duplicates are collapsed. * `exclude_task_ids` (optional): up to 100 IDs of completed (`status = "done"`) Deep Search tasks. The visible (returned) companies from those tasks are added to the exclusion set at creation time. Tasks must be owned by you (or someone in your organization). The combined exclusion set (`exclude_domains` ∪ visible results of `exclude_task_ids`) is capped at **1000 unique domains**. The resolved list is stored on the task and returned in the response as `exclude_domains`. ## Endpoint behavior * This call creates the task and returns immediately. Use the task ID to poll status and read results. * Every Deep Search result includes criteria and scores. If you omit `criteria`, Extruct generates them for you. If you provide `criteria`, those are used instead. * `exclude_*` inputs are resolved once at creation time and frozen on the task. Resuming or re-reading the task uses the same resolved set — references are not re-evaluated later. * Use [Get Task](/api-reference/discover/get-company-discovery-task) to monitor progress and [Get Task Results](/api-reference/discover/get-company-discovery-task-results) to review the companies. ## Excluding prior results A common pattern is to run a follow-up Deep Search that skips companies already returned by an earlier run: ```bash theme={null} curl -X POST "https://api.extruct.ai/v1/discovery_tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "query": "vertical SaaS companies serving freight forwarding", "desired_num_results": 100, "exclude_domains": ["acme.com", "https://beta.io/about"], "exclude_task_ids": [""] }' ``` ## Success signal A successful response includes task `id` and initial `status`. Save `id` and use it with task/status/results endpoints. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `400 Bad Request` Returned when an `exclude_task_ids` entry references a task that is not in `status = "done"`. ### `403 Forbidden` Returned when an `exclude_task_ids` entry references a task you do not own (and that is not owned by your organization). ### `404 Not Found` Returned when an `exclude_task_ids` entry references a task that does not exist. ### `422 Unprocessable Entity` Common causes: * Invalid JSON or unsupported fields. * `desired_num_results` outside `1..250`. * An entry in `exclude_domains` that cannot be parsed as a domain. * The resolved exclusion set exceeds the 1000-domain cap. Reduce `exclude_domains` or `exclude_task_ids`. Validate body first: ```bash theme={null} echo '' | jq empty ``` ## Related endpoints * [Get Task Endpoint](/api-reference/discover/get-company-discovery-task) * [Get Task Results Endpoint](/api-reference/discover/get-company-discovery-task-results) ## Related guides * [Deep Search](/api-guides/search/deep-search) # Get Discovery Task Source: https://docs.extruct.ai/api-reference/discover/get-company-discovery-task get /v1/discovery_tasks/{task_id} Get a Deep Search task by ID. ## Overview This endpoint returns the current state of a Deep Search task. It is the primary status endpoint for polling progress, checking counters, and seeing whether the task is exhausted. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TASK_ID="YOUR_TASK_ID" curl --get "https://api.extruct.ai/v1/discovery_tasks/${TASK_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` ## Key parameters * `task_id` (required): Task identifier returned by create-task. Track these fields while polling: * `status` * `is_exhausted` * `num_results_discovered` * `num_results_enriched` * `num_results_evaluated` * `num_results` Interpret them like this: * `num_results_discovered`: candidates gathered from the selected data sources. * `num_results_enriched`: discovered candidates that passed the relevance pre-filter and were enriched with company profiles. * `num_results_evaluated`: enriched candidates that have been fully scored across all criteria. * `num_results`: evaluated candidates currently counted as high-fit, meaning at least 75% of criteria are graded 4 or 5. ## Success signal The task is complete when `status=done` or `is_exhausted=true`. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The task ID is invalid or unavailable in your workspace. Re-check `TASK_ID` from create-task response. ### `status=failed` The task did not complete. Inspect returned error details, then retry create-task or use resume if appropriate. ## Related endpoints * [Get Task Results Endpoint](/api-reference/discover/get-company-discovery-task-results) * [Resume Task Endpoint](/api-reference/discover/resume-company-discovery-task) ## Related guides * [Deep Search](/api-guides/search/deep-search) # Get Discovery Task Results Source: https://docs.extruct.ai/api-reference/discover/get-company-discovery-task-results get /v1/discovery_tasks/{task_id}/results Get Deep Search results by task ID. ## Overview This endpoint returns paginated Deep Search results for a task. Results can be read while the task is running or after it completes. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TASK_ID="YOUR_TASK_ID" curl --get "https://api.extruct.ai/v1/discovery_tasks/${TASK_ID}/results" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=50" ``` ## Key parameters * `task_id` (required): Task identifier. * `offset` (optional): Pagination offset. * `limit` (optional): Page size. Results are ordered by `relevance` descending. ## Endpoint behavior * `relevance` controls the overall ordering of the result list. * `scores` shows the grade and explanation for each criterion. If you did not provide `criteria` when creating the task, Deep Search generates them automatically. * Use this endpoint to review companies. Use [Get Task](/api-reference/discover/get-company-discovery-task) for progress and completion state. ## Success signal A successful response includes `results[]` with criterion `scores` details. Continue paging until returned rows are fewer than `limit`. Use task completion rules from task status endpoint: `status=done` or `is_exhausted=true`. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The task ID is invalid or unavailable in your workspace. Re-check `TASK_ID` from create-task response. ## Related endpoints * [Get Task Endpoint](/api-reference/discover/get-company-discovery-task) ## Related guides * [Deep Search](/api-guides/search/deep-search) # List Discovery Tasks Source: https://docs.extruct.ai/api-reference/discover/list-company-discovery-tasks get /v1/discovery_tasks List Deep Search tasks. ## Overview This endpoint returns paginated Deep Search tasks with their current statuses. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/discovery_tasks" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ## Key parameters * `offset` (optional): Pagination offset. * `limit` (optional): Page size. ## Success signal A successful response returns a paginated list of tasks with `id`, `status`, and progress counters. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ## Related endpoints * [Get Task Endpoint](/api-reference/discover/get-company-discovery-task) * [Create Task Endpoint](/api-reference/discover/create-company-discovery-task) ## Related guides * [Deep Search](/api-guides/search/deep-search) # Resume Discovery Task Source: https://docs.extruct.ai/api-reference/discover/resume-company-discovery-task post /v1/discovery_tasks/{task_id}/resume Request additional results for a Deep Search task. ## Overview This endpoint requests additional results for an existing Deep Search task. If the task is already exhausted, the request fails with `400 Bad Request`. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TASK_ID="YOUR_TASK_ID" curl -X POST "https://api.extruct.ai/v1/discovery_tasks/${TASK_ID}/resume" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{"desired_new_results": 25}' ``` ## Key parameters * `task_id` (required): Task identifier. * `desired_new_results` (optional): additional result count; default `25`, min `0`, max `250`. Resume requests are still constrained by the task-level 250-result cap. If `is_exhausted=true`, this request returns `400 Bad Request`. That means the task has no more candidates to return. ## Success signal A successful response returns updated task state. Track progress via task status and results endpoints. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The task ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by invalid JSON or `desired_new_results` outside `0..250`. ### `400 Bad Request` Returned when the task is already exhausted and cannot be resumed for more results. ## Related endpoints * [Get Task Endpoint](/api-reference/discover/get-company-discovery-task) * [Get Task Results Endpoint](/api-reference/discover/get-company-discovery-task-results) ## Related guides * [Deep Search](/api-guides/search/deep-search) # Healthcheck Source: https://docs.extruct.ai/api-reference/healthcheck get /v1/healthcheck Check the health of the API. ## Overview This endpoint returns the current API health status. ## Example request ```bash theme={null} curl --get "https://api.extruct.ai/v1/healthcheck" ``` ## Key parameters * None. ## Success signal A successful response returns HTTP `200`. ## Common errors ### Non-200 response Retry after a short delay and check network connectivity if failures persist. ## Related endpoints * [Get User (`GET /v1/user`)](/api-reference/user) # Introduction Source: https://docs.extruct.ai/api-reference/introduction Browse the public Extruct API reference by endpoint group. Reference for the public Extruct API endpoints. For workflow guidance and feature selection, start in the [Documentation](/). ## Start here * Authentication: [Authentication](/api-reference/authentication) * Company Search endpoints: [Company Lookup](/api-reference/company-lookup), [Search](/api-reference/search), and [Lookalike Search](/api-reference/lookalike-search) * Deep Search endpoints: [Create Task](/api-reference/discover/create-company-discovery-task) * Deep Research endpoints: [Create Task](/api-reference/deep-research/create-deep-research-task) for deep, cited research reports on companies and people * Table endpoints: [Create Table](/api-reference/tables/create-table) and [Run Table](/api-reference/tables/run-table) for reusable enrichment workflows on Extruct results or your own company list ## Notes * All endpoints use Bearer authentication. * Endpoint pages focus on inputs, outputs, and errors, not workflow walkthroughs. # Find Similar Companies Source: https://docs.extruct.ai/api-reference/lookalike-search GET /v1/companies/{company_identifier}/similar Find companies similar to a reference company. **Prefer [`POST /v1/companies/{company_identifier}/similar`](/api-reference/lookalike-search-post).** This `GET` endpoint is deprecated. It still works and returns identical results, but POST is the recommended default: it takes `filters` as a JSON object and is not limited by URL length (required for large `exclude.domains` lists). ## Overview Lookalike Search returns companies ranked by similarity to a reference company. Pass a company domain or UUID. Result quality depends heavily on how representative the seed company is. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/companies/stripe.com/similar" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode 'filters={"include":{"country":["United States"]},"exclude":{"size":["1-10"]}}' \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ## Key parameters * `company_identifier` (required): Company domain or UUID. * `filters` (optional): JSON string to narrow results. * `offset` (optional): Pagination offset. * `limit` (optional): Page size, up to `250` per request. Lookalike uses the same filter format as semantic search. See [Search Filters Reference](/api-guides/search/search-filters-reference). ## Endpoint behavior * Ranking blends what a company does, who it sells to, firmographics, and traffic. * `filters` narrow the result set, but the seed company still determines what "similar" means. * Prefer a clear, representative company domain when possible. Use a UUID when you already have one from Extruct. * A single request returns at most `250` results. Page with `offset` to read deeper: paid plans (Starter, Pro) can reach up to `2,000` results per query; the free tier is capped at `25`. ## Success signal A successful response returns `results` with company candidates. Reuse `results[].domain` or `results[].id` in follow-up workflows. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The reference company identifier is not present in the index. Try a known domain from semantic results (`results[].domain`) or a valid UUID. ### `422 Unprocessable Entity` Most often caused by malformed `filters` JSON. Validate before sending: ```bash theme={null} echo '' | jq empty ``` ## Related endpoints * [Company Lookup (`GET /v1/companies/{company_identifier}`)](/api-reference/company-lookup) * [Semantic Search (`GET /v1/companies/search`)](/api-reference/search) ## Related guides * [Lookalike Search](/api-guides/search/lookalike-search) * [Semantic Search](/api-guides/search/semantic-search) # Find Similar Companies Source: https://docs.extruct.ai/api-reference/lookalike-search-post POST /v1/companies/{company_identifier}/similar Find similar companies with filters in a JSON body (POST variant). ## Overview The `POST` variant of [Lookalike Search](/api-reference/lookalike-search) takes `filters` as a native JSON object in the body instead of a URL-encoded string. The reference company stays in the path. Use it when an `exclude.domains` list is too large to fit a `GET` URL. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl -X POST "https://api.extruct.ai/v1/companies/stripe.com/similar" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "filters": {"exclude": {"domains": ["stripe.com", "adyen.com"]}}, "pagination": {"offset": 0, "limit": 20} }' ``` ## Key parameters * `company_identifier` (path, required): Reference company UUID or domain. * `filters` (optional): SearchFilters as a JSON object. See [Search Filters Reference](/api-guides/search/search-filters-reference). * `pagination` (optional): `{ "offset": , "limit": }`; `limit` up to `250` per request. ## Endpoint behavior * Identical ranking and results to the `GET` lookalike endpoint; only the transport differs. * The reference company is excluded from its own results; `exclude.domains` is additive. * A single request returns at most `250` results. Page with `pagination.offset` to read deeper. ## Success signal Returns `results`, the `reference_company`, and request metadata, the same shape as the `GET` endpoint. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The reference company was not found in the index. Verify the UUID or domain. ### `422 Unprocessable Entity` An invalid domain in `exclude.domains`, more than `1000` domains after de-duplication, or a malformed body. ## Related endpoints * [Lookalike Search Endpoint (GET)](/api-reference/lookalike-search) * [Search Endpoint (POST)](/api-reference/search-post) ## Related guides * [Search Filters Reference](/api-guides/search/search-filters-reference) * [Lookalike Search](/api-guides/search/lookalike-search) # Search Companies Source: https://docs.extruct.ai/api-reference/search GET /v1/companies/search Find companies from a natural-language query and optional filters. **Prefer [`POST /v1/companies/search`](/api-reference/search-post).** This `GET` endpoint is deprecated. It still works and returns identical results, but POST is the recommended default: it takes `filters` as a JSON object and is not limited by URL length (required for large `exclude.domains` lists). ## Overview Semantic Search returns companies that match a natural-language query, with optional firmographic filters. It is the recall-first search endpoint over the Extruct index and the usual starting point before lookalike or Deep Search. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/companies/search" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "q=b2b treasury automation" \ --data-urlencode 'filters={"include":{"country":["United States"],"size":["51-200","201-500"]},"range":{"founded":{"min":2018}}}' \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ## Key parameters * `q` (required): Natural-language query. * `filters` (optional): JSON string used to narrow results. * `offset` (optional): Pagination offset. * `limit` (optional): Page size, up to `250` per request. For supported `filters`, see [Search Filters Reference](/api-guides/search/search-filters-reference). ## Endpoint behavior * Results are ranked by semantic match in the Extruct index. * `filters` narrow the candidate set; they do not replace the query. * A single request returns at most `250` results. Page with `offset` to read deeper: paid plans (Starter, Pro) can reach up to `2,000` results per query; the free tier is capped at `25`. * Good matches from search often become inputs for [Company Lookup](/api-reference/company-lookup), seed companies for [Lookalike Search](/api-reference/lookalike-search), or a shortlist for [Deep Search](/api-reference/discover/create-company-discovery-task). ## Success signal A successful response returns `results` and request metadata. Reuse `results[].id` or `results[].domain` as downstream identifiers, including company lookup and lookalike input. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `422 Unprocessable Entity` Most often caused by malformed `filters` JSON. Validate before sending: ```bash theme={null} echo '' | jq empty ``` ## Related endpoints * [Company Lookup Endpoint](/api-reference/company-lookup) * [Lookalike Search Endpoint](/api-reference/lookalike-search) ## Related guides * [Semantic Search](/api-guides/search/semantic-search) * [Lookalike Search](/api-guides/search/lookalike-search) # Search Companies Source: https://docs.extruct.ai/api-reference/search-post POST /v1/companies/search Search companies with filters in a JSON body (POST variant). ## Overview The `POST` variant of [Semantic Search](/api-reference/search) takes the same parameters in a JSON body, with `filters` as a native object instead of a URL-encoded string. Use it when an `exclude.domains` list is too large to fit a `GET` URL. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl -X POST "https://api.extruct.ai/v1/companies/search" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "q": "b2b treasury automation", "filters": { "include": {"country": ["United States"], "size": ["51-200"]}, "exclude": {"domains": ["stripe.com", "adyen.com"]} }, "pagination": {"offset": 0, "limit": 20} }' ``` ## Key parameters * `q` (required): Natural-language query. * `filters` (optional): SearchFilters as a JSON object. See [Search Filters Reference](/api-guides/search/search-filters-reference). * `pagination` (optional): `{ "offset": , "limit": }`; `limit` up to `250` per request. ## Endpoint behavior * Identical ranking and results to `GET /v1/companies/search`; only the transport differs. * Prefer `POST` when `exclude.domains` is large; otherwise either method works. * A single request returns at most `250` results. Page with `pagination.offset` to read deeper: paid plans (Starter, Pro) can reach up to `2,000` results per query; the free tier is capped at `25`. ## Success signal Returns `results` and request metadata, the same shape as the `GET` endpoint. Reuse `results[].id` or `results[].domain` as downstream identifiers. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `422 Unprocessable Entity` An invalid domain in `exclude.domains`, more than `1000` domains after de-duplication, or a malformed body. Validate before sending: ```bash theme={null} echo '' | jq empty ``` ## Related endpoints * [Search Endpoint (GET)](/api-reference/search) * [Lookalike Search Endpoint (POST)](/api-reference/lookalike-search-post) ## Related guides * [Search Filters Reference](/api-guides/search/search-filters-reference) * [Semantic Search](/api-guides/search/semantic-search) # Clone Table Source: https://docs.extruct.ai/api-reference/tables/clone-table post /v1/tables/{table_id}/clone Clone table by ID. Only allowed to admin users, from admin users, or users within same organization. Always clones the entire table hierarchy (parent and child tables). If schema_only=True, only schemas are cloned without data. If schema_only=False, creates an identical duplicate with all row relationships preserved. ## Overview This endpoint duplicates an existing table configuration, with optional schema-only cloning. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/clone" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "schema_only=true" ``` ## Key parameters * `table_id` (required): source table identifier. * `schema_only` (optional): defaults to `false`; set `true` to clone structure without data. ## Success signal A successful response includes a new table `id`. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The source table ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by invalid `schema_only` query value. ## Related endpoints * [Get Table Endpoint](/api-reference/tables/get-table) * [Create Table Endpoint](/api-reference/tables/create-table) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Create Table Source: https://docs.extruct.ai/api-reference/tables/create-table post /v1/tables Create a table for enrichment and scoring workflows. ## Overview This endpoint creates a table for reusable enrichment or scoring workflows. You can populate it with companies discovered in Extruct or with your own list. `kind` determines what the table is for: * Use `company` when rows represent companies you want to enrich, score, or review. * Use `people` when rows represent contacts or individual people. * Use `generic` only when rows do not fit either company or people workflows. Create the table first when you want a stable workspace for rows, columns, and runs, even if you are not ready to populate it yet. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl -X POST "https://api.extruct.ai/v1/tables" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "name": "Company Research", "kind": "company", "column_configs": [ {"kind": "input", "name": "Company", "key": "input"} ] }' ``` ## Key parameters * `name` (optional): defaults to `Untitled Table`. * `kind` (optional): `generic`, `company`, or `people`. * `column_configs` (optional): initial column definitions. ## Success signal A successful response includes a table `id`. Reuse this value as `{table_id}` in all table endpoints. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `422 Unprocessable Entity` Most often caused by invalid `column_configs` shape. ## Related endpoints * [Create Table Rows Endpoint](/api-reference/tables/create-table-rows) * [Run Table Endpoint](/api-reference/tables/run-table) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Create Table Columns Source: https://docs.extruct.ai/api-reference/tables/create-table-columns post /v1/tables/{table_id}/columns Create new columns in the table. ## Overview This endpoint adds columns to an existing table. It is the normal way to grow a workflow step by step instead of locking the full schema upfront. This works especially well when you: * start with a minimal table and add enrichment later * test a few columns before rolling out the full workflow * add new scoring or research fields to a table that already has data ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/columns" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "column_configs": [ { "kind": "agent", "name": "Description", "key": "description", "value": { "agent_type": "research_pro", "prompt": "Describe what the company does in 2 sentences.", "output_format": "text" } } ], "insert_after": true }' ``` ## Key parameters * `table_id` (required): target table identifier. * `column_configs` (required): list of new column config objects. * `insert_after` (optional): defaults to `true`; can be `true`, `false`, or a column ID string. ## Success signal A successful response includes updated column definitions for the table. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by invalid `column_configs` shape or unsupported `insert_after` value. ## Related endpoints * [Update Table Column Endpoint](/api-reference/tables/update-table-column) * [Delete Table Column Endpoint](/api-reference/tables/delete-table-column) ## Related guides * [Column Guide](/api-guides/ai-tables/column-guide) * [Column Library](/api-guides/ai-tables/column-library) # Add Input Data Source: https://docs.extruct.ai/api-reference/tables/create-table-rows post /v1/tables/{table_id}/rows Append new rows with input data to the table. ## Overview This endpoint adds rows to a table before or during enrichment workflows. Those rows can come from your own source or from earlier Extruct workflows. Each item in `rows` creates one row. Put row values inside `data`. On `company` tables, `input` is usually the main entry field and should hold the company's official website domain or URL. On `people` tables, include the row fields required by the downstream columns you plan to run. Use `run=false` when you want to load or inspect rows first. Use `run=true` when new rows should immediately start table execution. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/rows" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "rows": [ {"data": {"input": "https://stripe.com"}}, {"data": {"input": "https://openai.com"}} ], "run": false }' ``` ## Key parameters * `table_id` (required): target table identifier. * `rows` (required): array of row objects; each row must include `data`. * `run` (optional): defaults to `false`; set `true` to trigger run after insert. ## Success signal A successful response returns created row metadata and IDs. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by invalid `rows` shape or missing `data`. ## Related endpoints * [Update Table Rows Endpoint](/api-reference/tables/update-table-rows) * [Delete Table Rows Endpoint](/api-reference/tables/delete-table-rows) * [Run Table Endpoint](/api-reference/tables/run-table) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Delete Table Source: https://docs.extruct.ai/api-reference/tables/delete-table delete /v1/tables/{table_id} Delete table by ID. ## Overview This endpoint permanently removes a table. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X DELETE "https://api.extruct.ai/v1/tables/${TABLE_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` ## Key parameters * `table_id` (required): target table identifier. ## Success signal A successful response confirms table deletion. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid, already deleted, or unavailable in your workspace. ## Related endpoints * [List Tables Endpoint](/api-reference/tables/list-tables) * [Create Table Endpoint](/api-reference/tables/create-table) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Delete Table Column Source: https://docs.extruct.ai/api-reference/tables/delete-table-column delete /v1/tables/{table_id}/columns/{column_id} Delete column by ID. ## Overview This endpoint removes a column from a table. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" export COLUMN_ID="YOUR_COLUMN_ID" curl -X DELETE "https://api.extruct.ai/v1/tables/${TABLE_ID}/columns/${COLUMN_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` ## Key parameters * `table_id` (required): target table identifier. * `column_id` (required): target column identifier. ## Success signal A successful response confirms column deletion. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table or column ID is invalid, already deleted, or unavailable in your workspace. ## Related endpoints * [Create Table Columns Endpoint](/api-reference/tables/create-table-columns) * [Update Table Column Endpoint](/api-reference/tables/update-table-column) ## Related guides * [Column Guide](/api-guides/ai-tables/column-guide) * [Column Library](/api-guides/ai-tables/column-library) # Delete Table Rows Source: https://docs.extruct.ai/api-reference/tables/delete-table-rows delete /v1/tables/{table_id}/rows Delete rows by ID. ## Overview This endpoint permanently removes one or more rows from a table. Deletion is bulk and row-ID based. Send the row IDs you want to remove in `rows`. Use it when you want to clean up bad inputs, remove duplicates, or drop rows you no longer want to run or keep. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X DELETE "https://api.extruct.ai/v1/tables/${TABLE_ID}/rows" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "rows": [ "11111111-1111-1111-1111-111111111111", "22222222-2222-2222-2222-222222222222" ] }' ``` ## Key parameters * `table_id` (required): target table identifier. * `rows` (required): array of row IDs to delete. ## Success signal A successful response returns the deleted row IDs. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by missing `rows`, malformed JSON, or invalid row ID values. ## Related endpoints * [Create Table Rows Endpoint](/api-reference/tables/create-table-rows) * [Update Table Rows Endpoint](/api-reference/tables/update-table-rows) * [Get Table Data Endpoint](/api-reference/tables/get-table-data) * [Get Row Endpoint](/api-reference/tables/get-table-row) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Get Table Source: https://docs.extruct.ai/api-reference/tables/get-table get /v1/tables/{table_id} Get table header and status. ## Overview This endpoint returns table metadata and execution status. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl --get "https://api.extruct.ai/v1/tables/${TABLE_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` ## Key parameters * `table_id` (required): target table identifier. Useful status fields include `run_status`, `num_cells_in_progress`, and `num_cells_completed`. ## Success signal A successful response returns table metadata and status. Table execution is complete when `run_status=idle` and `num_cells_in_progress=0`. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid or unavailable in your workspace. ## Related endpoints * [Run Table Endpoint](/api-reference/tables/run-table) * [Get Table Data Endpoint](/api-reference/tables/get-table-data) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Get Table Data Source: https://docs.extruct.ai/api-reference/tables/get-table-data get /v1/tables/{table_id}/data Get table data with streaming response to handle large tables. ## Overview This endpoint returns paginated rows and computed values from a table. It is the main read endpoint for checking input, enrichment, or scoring output. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl --get "https://api.extruct.ai/v1/tables/${TABLE_ID}/data" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "offset=0" \ --data-urlencode "limit=50" ``` ## Key parameters * `table_id` (required): target table identifier. * `offset` (optional): pagination offset. * `limit` (optional): page size. ## Success signal A successful response returns table rows and status context. Continue paging until returned rows are fewer than `limit`. Start with a small page size when validating a new workflow, then increase `limit` once the output looks correct. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid or unavailable in your workspace. ## Related endpoints * [Get Table Endpoint](/api-reference/tables/get-table) * [Get Row Endpoint](/api-reference/tables/get-table-row) * [Delete Table Rows Endpoint](/api-reference/tables/delete-table-rows) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Get Row Data Source: https://docs.extruct.ai/api-reference/tables/get-table-row get /v1/tables/{table_id}/rows/{row_id} Get a table row by ID. ## Overview This endpoint returns a single row by ID. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" export ROW_ID="YOUR_ROW_ID" curl --get "https://api.extruct.ai/v1/tables/${TABLE_ID}/rows/${ROW_ID}" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` ## Key parameters * `table_id` (required): target table identifier. * `row_id` (required): target row identifier. ## Success signal A successful response returns one row object with `id`, `data`, and row metadata. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID or row ID is invalid or unavailable in your workspace. ## Related endpoints * [Get Table Data Endpoint](/api-reference/tables/get-table-data) * [Update Table Rows Endpoint](/api-reference/tables/update-table-rows) * [Delete Table Rows Endpoint](/api-reference/tables/delete-table-rows) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # List Tables Source: https://docs.extruct.ai/api-reference/tables/list-tables get /v1/tables List root tables visible to the authenticated user. Supports filtering by table kind, ownership scope, free-text search, and tags. Results can be sorted by creation time, name, or row count. ## Overview This endpoint returns the root tables visible to the authenticated user. You can filter by table kind, ownership scope, free-text search, and tags. Results can be sorted by creation time, name, or row count. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/tables" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ --data-urlencode "scope=organization" \ --data-urlencode "search=acme" \ --data-urlencode "tags=portfolio" \ --data-urlencode "tags=priority" \ --data-urlencode "sort=-num_rows" \ --data-urlencode "offset=0" \ --data-urlencode "limit=20" ``` ## Key parameters * `kind` (optional): filter by table kind (`generic`, `company`, `people`). * `scope` (optional): filter by ownership. `personal` returns the caller's own tables. `organization` returns all tables visible within the caller's organization, including the caller's own tables. * `search` (optional): case-insensitive search across table names and descriptions. * `tags` (optional): repeat this parameter to match tables with any of the selected tags. * `sort` (optional): one of `-created_at`, `created_at`, `name`, `-name`, `num_rows`, `-num_rows`. * `offset` (optional): number of matching tables to skip before returning results. * `limit` (optional): maximum number of tables to return. Defaults to `50`; maximum is `100`. ## Success signal A successful response returns an array of table objects. Each item includes summary fields such as `id`, `created_at`, `updated_at`, `name`, `description`, `tags`, `kind`, `settings`, `scope`, `owner`, and `num_rows`. The response also includes pagination headers: * `x-extruct-pagination-total` * `x-extruct-pagination-total-pages` * `x-extruct-pagination-limit` * `x-extruct-pagination-offset` * `x-extruct-pagination-page` ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `400 Bad Request` Most often caused by `limit` values above `100`. ### `422 Unprocessable Entity` Most often caused by unsupported query values for `kind`, `scope`, or `sort`. ## Related endpoints * [Create Table Endpoint](/api-reference/tables/create-table) * [Get Table Endpoint](/api-reference/tables/get-table) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Run Enrichment Source: https://docs.extruct.ai/api-reference/tables/run-table post /v1/tables/{table_id}/run Initiate a table run, optionally for a selected range of rows and/or columns. ## Overview This endpoint starts or reruns table execution after rows and columns are ready. It can run the whole table, rerun failures, or scope execution to specific rows or columns. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X POST "https://api.extruct.ai/v1/tables/${TABLE_ID}/run" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{"mode":"new"}' ``` ## Key parameters * `table_id` (required): target table identifier. * `mode` (optional): run mode. Allowed values: `new` (default), `all`, `failed`. * `rows` (optional): row IDs to scope the run. * `columns` (optional): column IDs to scope the run. Practical meaning of `mode`: * `new`: run cells that do not already have values * `all`: rerun every eligible cell in scope * `failed`: rerun only failed cells Use `rows` when you want to rerun only a subset of table rows. Use `columns` when you want to run only specific columns instead of the full schema. When you add new columns to an existing table, the usual pattern is `mode: "new"` with the new column IDs in `columns`. ## Success signal A successful response returns run metadata (`id`, `status`, `num_requested_cells`). Use `GET /v1/tables/{table_id}` to track `run_status` and in-progress counters. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by invalid `mode`, malformed JSON, or invalid row/column IDs. ## Related endpoints * [Get Table Endpoint](/api-reference/tables/get-table) * [Get Table Data Endpoint](/api-reference/tables/get-table-data) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Update Table Source: https://docs.extruct.ai/api-reference/tables/update-table patch /v1/tables/{table_id} Update table metadata. ## Overview This endpoint updates table metadata such as name, description, tags, or column order. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X PATCH "https://api.extruct.ai/v1/tables/${TABLE_ID}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "name": "Company Research v2", "description": "Updated enrichment scope" }' ``` ## Key parameters * `table_id` (required): target table identifier. * Body fields (all optional): `name`, `description`, `tags`, `columns_order`. ## Success signal A successful response returns the updated table metadata with the same `id`. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by invalid JSON or unsupported field shapes. ## Related endpoints * [Get Table Endpoint](/api-reference/tables/get-table) * [List Tables Endpoint](/api-reference/tables/list-tables) ## Related guides * [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) # Update Table Column Source: https://docs.extruct.ai/api-reference/tables/update-table-column patch /v1/tables/{table_id}/columns/{column_id} Update a column in the table. ## Overview This endpoint replaces a column configuration in an existing table. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" export COLUMN_ID="YOUR_COLUMN_ID" curl -X PATCH "https://api.extruct.ai/v1/tables/${TABLE_ID}/columns/${COLUMN_ID}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "kind": "input", "name": "Company", "key": "input" }' ``` ## Key parameters * `table_id` (required): target table identifier. * `column_id` (required): target column identifier. * Body (required): full column config object matching one supported column type. ## Success signal A successful response includes the updated column configuration. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table or column ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by sending an invalid/partial column config for the selected column kind. ## Related endpoints * [Create Table Columns Endpoint](/api-reference/tables/create-table-columns) * [Delete Table Column Endpoint](/api-reference/tables/delete-table-column) ## Related guides * [Column Guide](/api-guides/ai-tables/column-guide) * [Column Library](/api-guides/ai-tables/column-library) # Update Table Rows Source: https://docs.extruct.ai/api-reference/tables/update-table-rows patch /v1/tables/{table_id}/rows Update existing rows & create new ones with input data in the table. ## Overview This endpoint updates existing row data in bulk. In most workflows, you identify the row you want to change with `id` and send the new `data` payload. Use `run=false` when you want to inspect the row changes before running anything. Use `run=true` when the update should immediately trigger execution. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" export TABLE_ID="YOUR_TABLE_ID" curl -X PATCH "https://api.extruct.ai/v1/tables/${TABLE_ID}/rows" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" \ -d '{ "rows": [ { "id": "YOUR_ROW_ID", "data": {"input": "https://stripe.com"} } ], "run": false }' ``` ## Key parameters * `table_id` (required): target table identifier. * `rows` (required): array of row update objects; each requires `data` and can include `id` for the target row. * `run` (optional): defaults to `false`; set `true` to run after update. ## Success signal A successful response returns updated row objects with current values. ## Common errors ### `401 Unauthorized` Check that your header is `Authorization: Bearer ${EXTRUCT_API_TOKEN}`. ### `404 Not Found` The table or row ID is invalid or unavailable in your workspace. ### `422 Unprocessable Entity` Most often caused by invalid `rows` shape or malformed JSON. ## Related endpoints * [Get Table Data Endpoint](/api-reference/tables/get-table-data) * [Delete Table Rows Endpoint](/api-reference/tables/delete-table-rows) * [Run Table Endpoint](/api-reference/tables/run-table) ## Related guides * [Company Enrichment](/api-guides/ai-tables/company-enrichment) # Get Extruct User Source: https://docs.extruct.ai/api-reference/user get /v1/user Get details about the authenticated user. ## Overview This endpoint returns details about the authenticated user, including available credits. Use it as your first authenticated request to validate API access. ## Example request ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/user" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` ## Key parameters * `Authorization` header (required): `Bearer ${EXTRUCT_API_TOKEN}`. ## Success signal A successful response includes `email` and `available_credits`. ## Common errors ### `401 Unauthorized` Check that your token is valid and the header includes `Bearer ` prefix. ## Related guides * [Authentication](/api-reference/authentication) # Extruct API Skill Source: https://docs.extruct.ai/build-with-ai-agents/extruct-api-skill Build against the Extruct API from Claude Code, Codex, and other agent tooling with the official extruct-api skill. Official repository: [GitHub](https://github.com/extruct-ai/skills) ## Overview The `extruct-api` skill gives coding agents the Extruct API's workflows, request shapes, and operating rules. That makes it useful both for running Extruct tasks and for building against the Extruct API without re-explaining the product and endpoint mechanics in every prompt. It covers company lookup and discovery with Company Lookup, Semantic Search, Lookalike Search, and Deep Search, plus AI Tables, enrichment, scoring, and people/contact workflows. ## Extruct MCP vs this skill **[Extruct MCP](/build-with-ai-agents/extruct-mcp)** is the default, lowest-friction way to use Extruct from editors and agents that support remote MCP (OAuth through the client). The model sees **named tools**, not the raw REST API. Use this **skill** when you want the opposite tradeoff: the repo ships **deep, embedded documentation** for workflows and payloads, so the agent often handles **long or finicky multi-step** tasks that map closely to the API. It assumes an **`EXTRUCT_API_TOKEN`** and is aimed at **more technical** users and codebases that call the HTTP API directly. | | Extruct MCP | This skill | | -------- | ----------------------- | ------------------------------------------- | | Auth | OAuth in the client | `EXTRUCT_API_TOKEN` | | Surface | MCP tools | REST-shaped workflows in prompts | | Best for | Most users; quick setup | Power users; integration and API-heavy work | ## Prerequisites ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" ``` Generate tokens in [Dashboard API Tokens](https://app.extruct.ai/api-tokens). For the underlying API setup, see [Authentication](/api-reference/authentication). ## Install ### Claude Code ```bash theme={null} /plugin marketplace add extruct-ai/skills /plugin install extruct-skills ``` ### Codex ```bash theme={null} $skill-installer https://github.com/extruct-ai/skills ``` `skill-installer` is a built-in Codex skill for installing skills from GitHub repositories. Restart Codex after installation so it picks up the new skill. ### skills.sh If you use the [Skills CLI](https://skills.sh/docs/cli), install the Extruct skill from GitHub: ```bash theme={null} npx skills add extruct-ai/skills ``` ## How it works Once installed, the skill gives the agent a structured path for common Extruct workflows instead of relying on ad hoc prompts. It helps the agent choose the right Extruct path, construct valid requests, inspect existing tasks and tables before mutating them, and carry async work through to completion. The skill uses the same `EXTRUCT_API_TOKEN` as the API examples in this docs site and treats the public Extruct API contract as the source of truth. ## Typical prompts Use prompts like: * `Help me integrate the Extruct API into this codebase.` * `Research the competitive landscape around vercel.com using Extruct.` * `Give me an overview of my Extruct AI workspace.` * `Search Extruct for AI procurement startups.` * `Find companies similar to Ramp in Extruct.` * `Create an Extruct table for target accounts and enrich it.` * `Find decision makers at these companies in Extruct.` ## What the skill can do * Run Company Lookup, Semantic Search, Lookalike Search, and Deep Search * Help agents build against the Extruct API with the right workflow and payload shape * Create, inspect, update, run, and read Extruct tables * Add enrichment, scoring, and contact-finding workflows to existing tables * Poll long-running tasks and return results in a consistent shape ## Resources * [Extruct MCP](/build-with-ai-agents/extruct-mcp): remote MCP server (OAuth) for supported clients * [Extruct AI skills repository](https://github.com/extruct-ai/skills) * [skills.sh](https://skills.sh/) * [Skills CLI docs](https://skills.sh/docs/cli) * [Extruct API reference](/api-reference/introduction) * [Authentication](/api-reference/authentication) # Extruct MCP Source: https://docs.extruct.ai/build-with-ai-agents/extruct-mcp Run Extruct search and tables inside Claude or your editor. Sign in once with your Extruct account. Connect Extruct to Claude or your coding tool so company lookup, search, lookalikes, Deep Search, and tables show up in chat. Use your Extruct login. The tool will prompt you when it needs access. **Connector URL** (copy into your app): ``` https://api.extruct.ai/mcp ``` ## Installation Pick your app. The first time you connect, your browser may open for sign-in. 1. **Customize** → **Connectors** at [claude.ai/customize/connectors](https://claude.ai/customize/connectors). 2. **+** → **Add custom connector**. 3. **Name:** `Extruct AI`. **MCP URL:** `https://api.extruct.ai/mcp`. **Add**. 4. Select **Extruct AI** → **Connect** and sign in. Add custom connector: Name Extruct AI, MCP URL https://api.extruct.ai/mcp 1. **Customize** → **Connectors** (in the Claude app). 2. **+** → **Add custom connector**. 3. **Name:** `Extruct AI`. **MCP URL:** `https://api.extruct.ai/mcp`. **Add**. 4. Select **Extruct AI** → **Connect** and sign in. Add custom connector: Name Extruct AI, MCP URL https://api.extruct.ai/mcp ```bash theme={null} claude mcp add --transport http extruct https://api.extruct.ai/mcp ``` Sign in when the terminal or browser asks. [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=extruct\&config=eyJ1cmwiOiJodHRwczovL2FwaS5leHRydWN0LmFpL21jcCJ9) Or edit `~/.cursor/mcp.json`: ```json theme={null} { "mcpServers": { "extruct": { "url": "https://api.extruct.ai/mcp" } } } ``` [![Install with one click](https://img.shields.io/badge/Install_with_one_click-VS_Code-0098FF?style=flat-square\&logo=visualstudiocode\&logoColor=white)](https://vscode.dev/redirect/mcp/install?name=extruct\&config=%7B%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fapi.extruct.ai%2Fmcp%22%7D) Or add `.vscode/mcp.json` to your project: ```json theme={null} { "servers": { "extruct": { "type": "http", "url": "https://api.extruct.ai/mcp" } } } ``` ```bash theme={null} codex mcp add extruct --url https://api.extruct.ai/mcp codex mcp login extruct ``` Or add to `~/.codex/config.toml`: ```toml theme={null} [mcp_servers.extruct] url = "https://api.extruct.ai/mcp" ``` Then run `codex mcp login extruct`. [Codex MCP](https://developers.openai.com/codex/mcp) 1. **Settings** → **MCP** (labels vary). 2. Add a server with URL `https://api.extruct.ai/mcp`, or add this to `~/.codex/config.toml`: ```toml theme={null} [mcp_servers.extruct] url = "https://api.extruct.ai/mcp" ``` 3. Run `codex mcp login extruct` in a terminal. [Codex MCP](https://developers.openai.com/codex/mcp) Put `https://api.extruct.ai/mcp` in your app's MCP or connector settings (labels vary). Sign in when asked. ```json theme={null} { "mcpServers": { "extruct": { "url": "https://api.extruct.ai/mcp" } } } ``` ## After you connect You can run the same company lookup, search, lookalikes, Deep Search, Deep Research, and AI Tables workflows in chat that you use in the Extruct app. ## Try it Copy any of these into your chat: * `Who competes with Figma in Europe? Give me 10 with websites. Use Extruct MCP.` * `Pull up the Extruct company profile for stripe.com. Use Extruct MCP.` * `Find Series A fintech companies in New York with 20-100 employees. Use Extruct MCP.` * `Pull up lookalikes to ramp.com and compare their funding stages. Use Extruct MCP.` * `Build a table of these 15 domains, add a column for employee count and another for recent funding, then run it. Use Extruct MCP.` * `Find the Head of Sales at each company on my shortlist and get their LinkedIn. Use Extruct MCP.` * `Search for AI companies selling to logistics. Narrow it to Germany and the Nordics. Use Extruct MCP.` * `Take the top 20 results from my last search, create a table, and score them on product-market fit for our ICP. Use Extruct MCP.` * `Run deep research on Shell: buying centers, recent initiatives, and practical sales angles for our outreach. Use Extruct MCP.` * `Research this person and the team they work with before my call tomorrow: . We sell . Use Extruct MCP.` **Not working?** Reconnect in Connectors or MCP settings, or restart the app after you save a config file. **Can't sign in:** Run **Connect** (or your app's login command) again and complete the browser step. **No Extruct tools:** Quit and reopen the app after you save config. **Credits or plan limits:** Open the [Extruct app](https://app.extruct.ai/) to check billing and usage. **Claude:** **Customize** → **Connectors** → **+** → **Add custom connector** ([claude.ai/customize/connectors](https://claude.ai/customize/connectors)). **Extruct AI** → **Connect** (`https://api.extruct.ai/mcp`). # Introduction Source: https://docs.extruct.ai/index Choose the right Extruct API workflow for your goal. ## Start with your goal Extruct API gives you three ways to discover companies, Deep Research for cited reports on companies and people, and AI Tables for enrichment and scoring on either Extruct results or your own company list. Use: * Semantic Search for fast, recall-first search over the Extruct index. * Lookalike Search when you already have a representative company domain or UUID. * Deep Search when you need a more deliberate shortlist scored against custom criteria. * Deep Research when you need a deep, cited report on one research target — a company, a person, or a team: account plans, lead and buyer research, diligence. * AI Tables when you want to enrich, score, and review a company list in a reusable workflow. Start from a company domain or UUID and find similar companies ranked from the Extruct index. Start from a natural-language query and retrieve matching companies instantly from the Extruct index. Run asynchronous, agent-based discovery that ranks companies against natural-language criteria using web, Extruct DB, Maps, and LinkedIn. Submit a detailed research brief about a company, a person, or a team and get back a cited report — markdown or structured to your own schema. Start with companies from Extruct or from your own company list, then run repeatable enrichment and scoring workflows. ## Authentication ```bash theme={null} export EXTRUCT_API_TOKEN="YOUR_API_TOKEN" curl --get "https://api.extruct.ai/v1/user" \ -H "Authorization: Bearer ${EXTRUCT_API_TOKEN}" ``` Generate tokens in the [Dashboard API Tokens page](https://app.extruct.ai/api-tokens). For full setup, see [Authentication](/api-reference/authentication). ## Next step * Start with [Semantic Search Guide](/api-guides/search/semantic-search) if you need to discover companies * Or start with [Deep Research](/api-guides/research/deep-research) if you need a cited report on a company or a person * Or start with [AI Tables Basics](/api-guides/ai-tables/ai-table-basics) if you already have a company list * Or connect [Extruct MCP](/build-with-ai-agents/extruct-mcp) in your editor or agent (Cursor, VS Code, Claude, Codex, and others) * Or use the [Extruct API Skill](/build-with-ai-agents/extruct-api-skill) if you want the skill’s embedded API workflows and `EXTRUCT_API_TOKEN` from your coding agent * Or browse the [API Reference](/api-reference/introduction) # Make Source: https://docs.extruct.ai/integrations/automation/make Connect Extruct AI with Make to create powerful automated workflows. ## Overview Our Make integration lets you: * Design visual workflows with Extruct AI and other services * Process data through Extruct AI's enrichment capabilities * Create complex scenario-based automations with branching logic * Connect with hundreds of other apps in the Make ecosystem ## Use Cases * **Advanced Data Routing**: Send research results to different systems based on specific criteria * **Batch Processing**: Automate research for lists of companies on a schedule * **Multi-platform Orchestration**: Coordinate actions across your entire tech stack # n8n Source: https://docs.extruct.ai/integrations/automation/n8n Connect Extruct AI with n8n for open-source workflow automation. Original source and package:\ [GitHub](https://github.com/extruct-ai/n8n-nodes-extruct) | [npm](https://www.npmjs.com/package/n8n-nodes-extruct) ## Overview The Extruct AI n8n node lets you instantly enrich company data in your workflows using your custom Extruct tables. No code required. ## Why Use the Extruct AI n8n Node? * Enrich company data by website or name, using your custom Extruct table columns * Automate research and enrichment in any workflow (sales, investment, market research, etc.) * Seamlessly integrate with CRMs, lead gen tools, and analytics ## How It Works 1. **Install the Extruct AI community node:**\ Follow the [n8n community nodes guide](https://docs.n8n.io/integrations/community-nodes/) to add the Extruct AI node to your n8n instance. 2. **Create a Table:**\ Start from a template or build your own table in [Extruct AI](https://extruct.ai) with any custom columns you need (e.g., founding year, patents, CEO’s Twitter, last funding round, open job count, etc.). 3. **Get Your Table ID:**\ Copy the Table ID from the Extruct dashboard or directly from the table page URL. 4. **Add the Extruct Node in n8n:** * Make sure you have set up your Extruct API token as a credential in n8n (see [Authentication](#authentication)). * Paste your Table ID. * Enter the company name or website (manually, from a Form Trigger, or any other node). * Run the workflow. The node will add the company, trigger enrichment, and return a JSON object with the enriched results for all your custom columns. n8n node demo *Demo: creating custom columns, entering Table ID and company name, and receiving enriched JSON results in n8n.* ## Example Workflow Suppose you want to enrich a company by website and get its funding, team size, recent news headline, patent count, and head of HR LinkedIn profile. **Input:** ```json theme={null} { "Company": "stripe.com" } ``` **Example:** ```json theme={null} { "company_name": { "value": { "answer": "Stripe", "source": [ "https://en.wikipedia.org/wiki/Stripe,_Inc." ], "explanation": "Full company name as listed on the Stripe Wikipedia page." } }, "company_website": { "value": { "answer": "https://stripe.com/", "source": [ "https://en.wikipedia.org/wiki/Stripe,_Inc.", "https://stripe.com" ], "explanation": "Canonical homepage confirmed on Wikipedia and the stripe.com domain." } }, "recent_news_headline": { "value": { "answer": "Stripe’s first employee, the founder of fintech Increase, sort of bought a bank", "source": [ "https://techcrunch.com/2025/07/03/stripes-first-employee-the-founder-of-fintech-increase-sort-of-bought-a-bank" ], "explanation": "Headline from a TechCrunch article published July 3, 2025, as the latest news about Stripe." } }, "team_size": { "value": { "answer": "8550", "source": [ "https://techcrunch.com/2025/01/21/stripe-is-laying-off-300-people-but-says-it-still-plans-to-hire-in-2025" ], "explanation": "About 8,550 employees after a January 2025 layoff of 300 people, per TechCrunch." } }, "patent_count": { "value": { "answer": "247", "source": [ "https://insights.greyb.com/stripe-patents" ], "explanation": "Total of 247 patents held globally by Stripe, according to GreyB Insights." } }, "funding_amount": { "value": { "answer": "$9.81B", "source": [ "https://tracxn.com/d/companies/stripe/__uahG_IGnVgsUsOG-f8otYHLkOkliWg7YFhJ5ZkNIkpI/funding-and-investors", "https://www.crunchbase.com/organization/stripe/company_financials" ], "explanation": "Raised $9.81 B over 24 rounds, including a $6.87 B round in March 2023, per Tracxn and Crunchbase." } }, "head_of_hr_linkedin": { "value": { "answer": "https://www.linkedin.com/in/maiaj", "source": [ "https://www.comparably.com/companies/stripe/maia-josebachvili", "https://www.linkedin.com/in/maiaj" ], "explanation": "Confirmed as Head of People at Stripe via Comparably and LinkedIn." } } } ``` ## Extruct Table Templates Use these ready-to-go table templates for your n8n workflows: * [Sales and Business Development](https://app.extruct.ai/tables/shared/jlcBdFwKXrC8uw21)\ *Track leads, enrich company profiles, and automate sales research.* * [Complete Startup Overview](https://app.extruct.ai/tables/shared/gQlqQK4pQgPDmk81)\ *Get a 360° view of startups with funding, team, and product data.* * [Social Enrichment](https://app.extruct.ai/tables/shared/VfGemEC1BujAIJx8)\ *Enrich companies with social profiles, Twitter, LinkedIn, and more.* Open a template, get the Table ID, and use it in your node. ## Authentication * **Extruct API Token** * Sign up at [extruct.ai](https://extruct.ai) * Get your API token from the dashboard * Add it as a credential in n8n ## Resources * [API Reference](https://docs.extruct.ai) * [n8n Community Nodes](https://docs.n8n.io/integrations/community-nodes/) # Zapier Source: https://docs.extruct.ai/integrations/automation/zapier Connect Extruct AI with thousands of apps through Zapier automation. ## Overview Our Zapier integration lets you: * Trigger automated workflows based on Extruct AI data or events * Push data from other platforms into Extruct AI for enrichment * Create multi-step automations involving Extruct AI and your other tools * Build no-code integrations with 5,000+ applications ## Use Cases * **Automated Research**: Trigger company research when new leads arrive in your CRM * **Data Synchronization**: Keep company data consistent across multiple platforms * **Workflow Automation**: Start actions in other tools based on Extruct AI findings # Affinity CRM Source: https://docs.extruct.ai/integrations/crm/affinity Connect Extruct AI with Affinity to enrich your CRM data with AI-powered company insights. ## Overview The Extruct AI Affinity integration enables both manual and fully automated workflows between your Affinity CRM and Extruct AI: ### Manual Export Export enriched company data from Extruct directly to your Affinity CRM lists with a single click. Companies you've discovered and enriched in Extruct can be exported to your specific lists in Affinity, complete with all the unique data points that matter to your team. Export from Extruct to Affinity CRM *Single-click export workflow from Extruct to your Affinity CRM lists* ### Fully Automated Enrichment Set up a continuous enrichment pipeline where: 1. Company is added to Affinity 2. Automatically pushed to your Extruct table (with your custom data points configured) 3. Gets enriched by Extruct AI 4. Enriched data automatically flows back to Affinity This automated flow is how the real-life examples below are implemented - ensuring your Affinity data stays fresh and comprehensive without manual intervention. ## Why Use the Extruct AI Affinity Integration? * **One-Click Export**: Export enriched companies directly from Extruct to your Affinity lists * **Fully Automatic Sync**: Set up bidirectional sync for hands-off enrichment * **Custom Data Points**: Bring unique, AI-researched insights specific to your investment thesis * **Team-Specific Intelligence**: Different teams get different data points tailored to their needs * **Automated Enrichment**: Keep your Affinity data fresh with continuous updates from Extruct ## Automatic Bidirectional Sync Beyond manual exports, the integration supports fully automatic workflows: **Company added to Affinity** → **Pushed to Extruct table** → **Gets enriched with custom data points** → **Pushed back to Affinity** This seamless flow ensures your Affinity data is always up-to-date with the latest insights, without any manual intervention. Simply configure your custom data points once, and every new company in your Affinity lists gets automatically enriched. ## Real-Life Examples The following examples showcase teams using the fully automatic sync workflow, where companies are automatically enriched as they're added to Affinity: ### Private Equity Teams Get critical risk assessment data with our traffic light system for: * **Business Momentum**: Track growth trajectory and market position * **Brand & Market Perception**: Monitor reputation and customer sentiment * **Fundability Risks & Red Flags**: Identify potential investment concerns Private Equity Data Points *Example: PE teams get automatic traffic light alerts for business momentum, brand perception, and fundability risks* ### Innovation & Venture Capital Teams Surface unique data points that matter for early-stage investments: * **Client Lists**: See who their customers are * **Pricing Models**: Understand their monetization strategy * **Key Use Cases**: Identify product-market fit * **Technology Stack**: Assess technical capabilities VC and Innovation Team Data Points *Example: Innovation teams get automatically enriched insights on clients, pricing models, and use cases* # Attio Source: https://docs.extruct.ai/integrations/crm/attio Connect Extruct AI with Attio to enrich your CRM data with AI-powered company insights. ## Overview Our Attio integration lets you: * Automatically enrich company profiles in Attio with Extruct AI data * Sync custom field values between platforms * Trigger workflows based on Extruct AI findings * Semantically search for companies in Attio ## Use Cases * **Lead Enrichment**: Automatically populate company data in Attio * **Qualification Scoring**: Use Extruct AI criteria scoring to prioritize leads * **Account Intelligence**: Surface key insights about prospects to your sales team # Hubspot Source: https://docs.extruct.ai/integrations/crm/hubspot Connect Extruct AI with Hubspot to enrich your CRM data with AI-powered company insights. ## Overview Our Hubspot integration lets you: * Automatically enrich company profiles in Hubspot with Extruct AI data * Sync custom field values between platforms * Trigger workflows based on Extruct AI findings * Semantically search for companies in Hubspot ## Use Cases * **Lead Enrichment**: Automatically populate company data in Hubspot * **Qualification Scoring**: Use Extruct AI criteria scoring to prioritize leads * **Account Intelligence**: Surface key insights about prospects to your sales team # Pipedrive Source: https://docs.extruct.ai/integrations/crm/pipedrive Connect Extruct AI with Pipedrive to enrich your CRM data with AI-powered company insights. ## Overview Our Pipedrive integration lets you: * Automatically enrich company profiles in Pipedrive with Extruct AI data * Sync custom field values between platforms * Trigger workflows based on Extruct AI findings * Semantically search for companies in Pipedrive ## Use Cases * **Lead Enrichment**: Automatically populate company data in Pipedrive * **Qualification Scoring**: Use Extruct AI criteria scoring to prioritize leads * **Account Intelligence**: Surface key insights about prospects to your sales team # Salesforce Source: https://docs.extruct.ai/integrations/crm/salesforce Connect Extruct AI with Salesforce to enrich your CRM data with AI-powered company insights. ## Overview Our Salesforce integration lets you: * Automatically enrich company profiles in Salesforce with Extruct AI data * Sync custom field values between platforms * Trigger workflows based on Extruct AI findings * Semantically search for companies in Salesforce ## Use Cases * **Lead Enrichment**: Automatically populate company data in Salesforce * **Qualification Scoring**: Use Extruct AI criteria scoring to prioritize leads * **Account Intelligence**: Surface key insights about prospects to your sales team