mcp-gtm-suite
MCP server exposing 21 Mamba Labs GTM account-intelligence tools, each a thin client routing to an Apify actor and returning Clay-ready flat JSON for identity, enrichment, signal detection, scoring, and sequencer push.
Resolve identity & enrich companies: canonical identity from name/domain/LinkedIn (
resolve_company_identity), domain-to-LinkedIn URL (resolve_linkedin_url), firmographics (enrich_company_firmographics), social profiles and followers (map_company_social_presence).Detect buying signals: GTM hiring activity, tech stack/CRM, job-board keyword scans, funding and press events, change monitoring since last run, AI tooling maturity, cold-outbound infrastructure fingerprint, and publication cadence.
Score accounts: composite multi-source GTM score (
aggregate_gtm_signals) and ICP fit with 0-100 score, A-D tier, and per-signal breakdown (score_icp_fit).Resolve entities and records: registered legal entity across Companies House, GLEIF, SEC EDGAR (
resolve_legal_entity); deterministic job-title classification into department/seniority/rank (classify_contact).Assess reach and readiness: agent accessibility audit (llms.txt, robots.txt, structured data), company event/conference presence, public award-register winners, and indexed LinkedIn posts (commenters removed).
Push leads to sequencers: the only write tool, adding leads to an existing Instantly or Smartlead campaign, with ICP gating, dedupe, and a free
dry_runpayload preview.Operational notes: requires Node 18+ and an APIFY_TOKEN; runs bill to your own Apify account pay-per-event; every tool accepts an optional
max_charge_usdspending cap; runs poll up to 1,800s and return a run id and console link if still going.
Uses OpenAI's language models to score companies against an ideal customer profile via the score_icp_fit tool.
Mamba Labs GTM Suite MCP Server
One MCP server that exposes the Mamba Labs GTM Suite. Install a single package and get all twenty one account-intelligence tools in your MCP client, each wrapping a Mamba Labs actor on Apify and returning Clay-ready flat JSON.
What's Inside
Related MCP server: mcp-icp-fit-scorer
What it does
This server gives an AI client twenty one account-intelligence tools in one place, covering the full GTM workflow: resolve identity, enrich the account, detect buying signals, score fit, and push the survivors into a sequencer.
Identity and enrichment
resolve_company_identity: reconcile name, domain, and LinkedIn URL into one canonical identity with confidence scoresenrich_company_firmographics: enrich a domain into employee band, industry, HQ, founded year, revenue, logo, and descriptionmap_company_social_presence: map a domain to LinkedIn, X, Instagram, Facebook, and YouTube URLs and follower countsresolve_linkedin_url: resolve a domain or name to a LinkedIn company URL
Signals
scan_gtm_hiring_signals: detect GTM hiring activity from career pagesdetect_gtm_tech_stack: detect CRM, sequencer, and marketing automation toolsscan_job_board_keywords: scan job boards for roles in any categoryget_funding_press_signals: scan news and PR wires for funding, exec moves, launches, and acquisitionsget_company_changes: monitor a domain and return only what changed since the last run; choose the sources to watch and a severity floordetect_ai_tooling: determine whether a company declares, deploys, or charges for AIfingerprint_outbound_infrastructure: determine whether a company runs cold outbound, on what stack, and from which lookalike sending domainstrack_publication_cadence: how much long-form work a company publishes per month, and whether that rate is rising or falling
Scoring
aggregate_gtm_signals: combine hiring and tech-stack signals, plus funding, events, or workplace on request, into one composite scorescore_icp_fit: score a company against your ideal customer profile
Entity and record resolution
resolve_legal_entity: resolve a domain to its registered legal entity in Companies House, GLEIF or SEC EDGARclassify_contact: turn a job title into a department, a seniority level and a sortable rank, by deterministic rule
Reach and readiness
audit_agent_accessibility: whether an AI agent can read a site, and what the site's policy says about itmap_company_event_presence: the third-party conferences a company publicly says it attendsmonitor_public_awards: the companies that won work in a public award register, one row per winnercapture_linkedin_posts_and_commenters: the LinkedIn posts a search engine has indexed for profiles and company pages, with no request to LinkedIn (commenters removed 2026-10-12)
All of the work runs on Apify. This package is a thin client that routes each tool call to the right actor and hands back the result.
Quick start
You need Node.js 18 or newer and an Apify account with an API token.
Add this to your Claude Desktop config:
{
"mcpServers": {
"mamba-gtm-suite": {
"command": "npx",
"args": ["-y", "@mambalabsdev/mcp-gtm-suite"],
"env": {
"APIFY_TOKEN": "your-apify-token"
}
}
}
}Get your token at https://console.apify.com/account/integrations, paste it in, and restart Claude Desktop. All twenty one tools will be available.
Prerequisites
Node.js 18 or newer
An Apify account with an API token
Example prompts
"Profile stripe.com: firmographics, hiring signals, tech stack, and an overall GTM score."
"Resolve the canonical identity for Deel, then enrich its firmographics and social presence."
"Find figma.com's LinkedIn URL, then score it against my ICP."
"Any funding or exec moves at openai.com recently, and what CRM do they use?"
"What changed at datadoghq.com since last week?"
Tools and inputs
Each tool maps to one Apify actor. Every input each tool accepts is listed below, generated from the server's own tool list. Where a tool marks nothing required, it still needs one identifier: the tool says which when you call it without one.
scan_gtm_hiring_signals(8 inputs): requireddomain; optionalrole_filter,ats_slug,mode,include_role_details,previous_gtm_role_count,previous_run_date,max_charge_usddetect_gtm_tech_stack(7 inputs): optionaldomain,company_domain,url,crawl_additional_pages,skipCache,technologies,max_charge_usdaggregate_gtm_signals(5 inputs): requiredcompany_domain; optionalinclude_summary,explain_mode,sources,max_charge_usdscan_job_board_keywords(7 inputs): requiredcompany_domain,role_categories; optionalcustom_keywords,enable_fallback,previous_roles_detected,previous_run_date,max_charge_usdresolve_linkedin_url(6 inputs): optionalcompany_domain,company_name,includeFirmographics,skipCache,minConfidenceScore,max_charge_usdscore_icp_fit(44 inputs): requiredcompany_domain; optionalcompany_name,template,scoring_config,icp_description,llm_api_key,llm_provider,fetch_signals,include_explanation,tier_thresholds,funded_within_days,min_score_to_output,previous_score,gtm_hiring_signal,gtm_role_count,uses_hubspot,uses_salesforce,uses_clay,crm_detected,seq_tool_detected,tech_stack,headcount,headcount_min,headcount_max,headcount_in_range,employee_band,revenue_estimate,hq_location,founded_year,recently_funded,last_funding_date,latest_funding_date,latest_funding_amount,funding_stage,industry,industry_match,target_industries,social_platforms_found,total_followers,has_linkedin,has_twitter,job_count,keyword_match_count,max_charge_usdresolve_company_identity(6 inputs): optionalcompany_name,domain,linkedin_url,skipCache,minLinkedinConfidence,max_charge_usdenrich_company_firmographics(6 inputs): optionaldomain,company_name,domains,batchSize,skipCache,max_charge_usdmap_company_social_presence(6 inputs): optionalcompany_domain,company_name,platforms,includeFollowerCounts,skipCache,max_charge_usdget_funding_press_signals(5 inputs): requireddomain; optionalcompany_name,signal_types,lookback_days,max_charge_usdget_company_changes(7 inputs): requireddomain; optionalcompany_name,previous_snapshot,sub_actor_timeout_secs,sources,min_severity,max_charge_usddetect_ai_tooling(7 inputs): optionaldomain,domains,check_pricing,skipCache,request_timeout_ms,vendors,max_charge_usdfingerprint_outbound_infrastructure(10 inputs): optionaldomain,domains,scan_sending_domains,sending_domain_depth,check_deliverability,skipCache,max_sending_domain_probes,request_timeout_ms,dns_timeout_ms,max_charge_usdtrack_publication_cadence(9 inputs): optionaldomain,domains,max_pages_to_date,domain_time_budget_ms,skipCache,page_concurrency,max_sitemap_fetches,request_timeout_ms,max_charge_usdpush_leads_to_sequencer(11 inputs): requiredsequencer,campaign_id; optionalapi_key,leads,dataset_id,min_icp_score,deduplicate,dry_run,field_mapping,custom_variables,max_charge_usdaudit_agent_accessibility(6 inputs): requireddomain; optionalcheck_endpoints,check_structured_data,skipCache,checks,max_charge_usdclassify_contact(9 inputs): requiredjob_title; optionalfull_name,company_domain,verify_position,use_llm_fallback,llm_provider,llm_model,skipCache,max_charge_usdmap_company_event_presence(7 inputs): requireddomain; optionalcompany_name,years,include_own_events,max_queries,skipCache,max_charge_usdresolve_legal_entity(9 inputs): requireddomain,sec_requester_name,sec_requester_email; optionallegal_name_hint,jurisdiction_hint,match_strictness,validate_vat,skipCache,max_charge_usdmonitor_public_awards(8 inputs): requiredregister; optionalwindow_days,min_award_value,max_entities,exclude_government_recipients,resolve_domains,domain_confidence_floor,max_charge_usdcapture_linkedin_posts_and_commenters(4 inputs): optionalprofile_urls,company_urls,posted_since,max_charge_usd.
Every tool also accepts max_charge_usd, an optional spending cap in USD for that call: the actor stops before any charge that would take the run past it and keeps every row already charged.
push_leads_to_sequencer is the only tool here that writes: it adds leads to your campaign unless dry_run is true.
Pricing
Each tool runs its actor on your own Apify account and is billed there, pay per event. Every run also carries Apify's actor start event at $0.00005 per GB of memory. Prices below are read from each actor's live pricing record on 2026-10-16; the Apify page of each actor carries the current price.
Tool | Events and price per event (USD) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A pricing change takes effect on 2026-10-26 for company-firmographic-enricher, company-identity-resolver, domain-to-linkedin-url-resolver: the charge moves to a result event. Check the actor's Apify page after that date.
How each call runs
Each call starts the actor run, polls it until it finishes, then reads the dataset. A run is allowed 1,800 seconds. If the run is still going when this call stops waiting, the call returns the run id and a console link instead of a timeout, so the result is never lost.
Full actor documentation
For the complete input and output reference, pricing, and run history of each actor, see the Mamba Labs Apify Store page:
Mamba Labs GTM Suite
This is the umbrella server for the Mamba Labs GTM Suite: twenty one account-intelligence tools for go-to-market signal intelligence, each backed by a dedicated Apify actor and also published as its own standalone MCP server. The Mamba Labs fleet has 75 public actors; the brand presence mappers, the influencer suite, Expert Witness Directory, and the other actors outside this list are available as their own servers under @mambalabsdev on npm.
Tool | Actor | Immutable Actor ID |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
The Domain Deliverability Checker actor is published as a standalone MCP server but is intentionally not bundled here: it audits email-sending infrastructure (SPF, DKIM, DMARC, blacklists) rather than account intelligence, so it sits outside this suite's scope.
Built by Mamba Labs | npm | Apify Store | mambabuilt.com
License
MIT
Built by Mamba Labs. https://apify.com/mambalabs
Available Tools
21 toolsaggregate_gtm_signalsAggregate GTM SignalsAIdempotent
Aggregate a company's GTM signals into one composite score. Runs hiring and tech-stack detection by default, plus funding, events, or workplace when named in sources, in one call and returns a composite score, recommended action, and optional summary as a flat, Clay-ready JSON row. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| sources | No | Which signals to aggregate. Defaults to hiring and tech_stack. Each extra source adds one sub actor run to the bill and one dimension to the composite score, which is normalized over the sources selected. | |
| explain_mode | No | If true, the summary becomes a longer, more detailed explanation. | |
| company_domain | Yes | Bare company domain, e.g. stripe.com | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| include_summary | No | Include a plain-English gtm_signal_summary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavioral context beyond annotations: requires an APIFY_TOKEN, consumes Apify credits per call, reads public data and writes nothing, and each extra source adds a sub-actor run to the bill. There is mild tension with readOnlyHint=false (the call does trigger billable external runs), but the description is transparent about those side effects rather than hiding them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then supporting detail on defaults, return shape, and cost/auth. Efficient overall, though the second sentence is dense and packs defaults, costs, and return format into one long clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by naming the return contents (composite score, recommended action, optional summary as a flat Clay-ready JSON row). Combined with its auth/cost disclosure, an agent has enough to invoke it correctly, though pagination/error behavior is unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented in the schema, including defaults, the billing effect of extra sources, and max_charge_usd semantics. The description largely restates this (defaults to hiring/tech-stack, sources add cost and dimensions), so it adds little beyond the schema — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Aggregate a company's GTM signals into one composite score') and clarifies it combines hiring + tech-stack (plus optionally funding/events/workplace) 'in one call'. This distinguishes it from single-signal siblings like scan_gtm_hiring_signals and detect_gtm_tech_stack without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the aggregation context clearly: hiring and tech-stack run by default, others only when named in sources, all in a single call. This implies when to prefer the aggregator over individual scanners, but it never explicitly says 'use this instead of calling the single-signal tools separately' or names any when-not condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audit_agent_accessibilityAudit Agent AccessibilityAIdempotent
Give it a domain and it returns whether an AI agent can read that site, and what the site's policy says, as one flat row of 42 fields across five families: the llms.txt family including llms-full.txt and ai.txt, robots.txt AI crawler policy including the newer Content Signal directives, structured data presence and health across JSON-LD, microdata, Open Graph and canonical, render mode, and machine readable endpoint discovery covering sitemap, OpenAPI, well known files and feeds. Every field is a fact read off a fetch. No model is called at any point, so the same domain returns the same row today and next month unless the site actually changed. Twelve requests per domain, typically 2 to 4 seconds. Built for a technical SEO or growth engineer preparing a site for AI crawlers, or an agency selling that work and needing a before and after audit across a client list. Requires an APIFY_TOKEN and consumes Apify credits. Read only.
| Name | Required | Description | Default |
|---|---|---|---|
| checks | No | Run only these checks. Omit for all of them. Narrowing narrows the work, and the score is rescaled over the checks selected. | |
| domain | Yes | One company domain, for example vercel.com. Protocol and path are stripped. | |
| skipCache | No | Leave as false to use the 7 day cache. Set to true to re-audit the domain from scratch. Default: "false". | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| check_endpoints | No | Probes sitemap, OpenAPI, well known files and feeds. Adds 7 concurrent requests. Default: true. | |
| check_structured_data | No | Parses JSON-LD, microdata, Open Graph and canonical off the homepage. Costs no extra requests. Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description ends with 'Read only,' but the annotations declare readOnlyHint=false (a tool with side effects). This is a direct contradiction about the tool's safety profile, which is exactly the signal an agent relies on. Although the description otherwise discloses a lot (12 requests, 2-4s, no model, token and credit requirements, 7-day cache), the explicit read-only claim contradicts structured data and is capped at 1 per the rules.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and result, and nearly every clause adds value (determinism, timing, billing, cache). It is dense and somewhat run-on, but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description fully characterizes the return (42 flat fields across five named families), resource costs, timing, determinism, caching and auth requirements. An agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (checks, domain, skipCache, max_charge_usd, check_endpoints, check_structured_data) is already documented in the schema. The description adds context about the output families but no extra parameter syntax or semantics, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (given a domain, return whether an AI agent can read the site and what the policy says) and enumerates the five output families. This is unmistakably distinct from the GTM/sales-intelligence siblings, so an agent can route to it without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names clear contexts and personas: a technical SEO/growth engineer preparing a site for AI crawlers, or an agency needing a before/after audit across a client list. There is no explicit when-not guidance, but no sibling competes for the same task, so this is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
capture_linkedin_posts_and_commentersCapture LinkedIn Posts and CommentersAIdempotent
Point it at LinkedIn person profiles or company pages and it returns the posts a search engine has indexed for each one, as flat rows: permalink, author, a text excerpt, and the publish date decoded from the post id. No request is sent to LinkedIn and no cookie or account is used. A result counts only when its permalink names the source, so posts are never attributed to the wrong author. Coverage is what the search index holds: posts appear days or weeks after publishing and many never appear. Commenters, reaction counts, comment counts and media are no longer returned (removed 2026-10-12, they came only from LinkedIn pages). Rows carry row_type post or notice; filter on row_type before loading a table. post_id is the activity URN and is stable across runs. Every row carries degraded and degradation_reason. Requires an APIFY_TOKEN and consumes Apify credits. Read only.
| Name | Required | Description | Default |
|---|---|---|---|
| company_urls | No | LinkedIn company page URLs, for example https://www.linkedin.com/company/microsoft. Supply this, profile_urls, or both. | |
| posted_since | No | ISO date or timestamp, for example 2026-08-01. Posts published before this are skipped BEFORE anything is charged. Leave empty to take everything the index holds. | |
| profile_urls | No | LinkedIn person profile URLs, for example https://www.linkedin.com/in/williamhgates. Country subdomains such as uk.linkedin.com are fine. Supply this, company_urls, or both. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply openWorldHint=true, idempotentHint=true, destructiveHint=false and readOnlyHint=false, but the description adds far more: no LinkedIn request/cookie/account, permalink-based attribution guarantee, index coverage latency ('days or weeks', 'many never appear'), removed fields with a date, row_type post/notice semantics, stable post_id, per-row degraded/degradation_reason, APIFY_TOKEN requirement and credit consumption. The closing 'Read only.' sits in mild tension with readOnlyHint=false, but the description itself discloses the credit side effect, so the two are complementary rather than contradictory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what the tool does, then caveats, then output shape. It is dense but nearly every sentence carries distinct, decision-relevant information (coverage limits, attribution rule, removed fields). Slightly long, but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the full burden of describing returns — and it does: flat rows with permalink, author, excerpt, decoded publish date, row_type, post_id and degradation fields. Auth, cost, and coverage constraints are all covered, leaving nothing an agent needs to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the four parameters (company_urls, profile_urls, posted_since, max_charge_usd) are already richly documented in the schema, including the pre-charge skip semantics of posted_since. The description adds no parameter-level detail beyond what the schema states, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Point it at LinkedIn person profiles or company pages and it returns the posts a search engine has indexed'), plus the exact row shape returned. It also distinguishes itself from generic LinkedIn tools by specifying the mechanism (search-index based, no LinkedIn request), so an agent can tell what it is without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context ('Point it at LinkedIn person profiles or company pages') and practical guidance ('filter on row_type before loading a table'). However, it never names an alternative sibling (e.g., map_company_social_presence, track_publication_cadence) or states when NOT to use it, so routing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
classify_contactClassify ContactAIdempotent
One contact in, one classified row out. Give it a job title and it returns the department, the seniority level, a seniority_rank from 1 to 12 you can filter with a comparison, and classification_rule, the named rule that fired, so every decision is auditable. The classification is a deterministic rule table: it needs no API key, calls no model, and returns the same answer for the same title every time. Only job_title is required. full_name and company_domain are read only when verify_position is on, which checks whether the person is still listed on their employer's own website and adds roughly 3 seconds and 9 requests per contact. The optional LLM fallback for titles the rules cannot place runs on your own key, set as the LLM_API_KEY secret environment variable on your own copy of the actor, and only the title is ever sent, never the person's name. With no key set those titles come back null rather than failing the row. This actor does not discover people: the name and title come from you. Requires an APIFY_TOKEN and consumes Apify credits. Read only.
| Name | Required | Description | Default |
|---|---|---|---|
| full_name | No | Only needed for position verification. Classification works without it. This name is never sent to any language model. | |
| job_title | Yes | The contact's job title, exactly as you hold it. Classified by deterministic rules with no API key needed. | |
| llm_model | No | Model id passed straight through to the provider. Only read when the LLM fallback is on. Default: "gpt-4o-mini". | |
| skipCache | No | Set to true to ignore cached results and classify from scratch. Default: "false". | |
| llm_provider | No | Which provider your LLM_API_KEY belongs to. Only read when the LLM fallback is on. Default: "openai". | |
| company_domain | No | Only needed for position verification. The company's website domain, with or without https. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| verify_position | No | Check whether the person is still listed on their employer's own website. Off by default. Adds roughly 3 seconds and 9 requests per contact, and needs both the name and the domain. Default: false. | |
| use_llm_fallback | No | Off by default. When on, titles the rules cannot place are sent to your own model using the LLM_API_KEY secret environment variable you set on your copy of this Actor. Only the title is sent, never the person's name. With no key set the Actor still returns a row, it just leaves those titles null. Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description closes with 'Read only,' but the annotations declare readOnlyHint=false. That is a direct textual conflict about the tool's side-effect profile, which is the exact case the rubric scores 1. The otherwise rich behavioral detail (credits, 9 requests/contact, LLM key handling, null fallback) cannot offset a contradiction on the safety-relevant hint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core contract is front-loaded in the first sentence and the remaining detail is organized roughly by concern (determinism, then optional verification, then fallback, then auth/cost). It runs long at ~10 sentences for a 9-param tool and repeats some material already covered by the schema, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming every returned field (department, seniority level, seniority_rank, classification_rule). It also covers auth (APIFY_TOKEN, LLM_API_KEY secret), cost model, and the no-key edge case, leaving nothing an agent needs in order to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter, including the conditional nature of full_name/company_domain and the defaults. The description largely restates this (required job_title, name/domain only read under verify_position) rather than adding syntax or semantics the schema lacks. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening states a specific verb+resource and its exact contract: 'One contact in, one classified row out. Give it a job title and it returns the department, the seniority level, a seniority_rank from 1 to 12... and classification_rule.' It also draws a boundary that no sibling provides ('This actor does not discover people: the name and title come from you'), so an agent can distinguish it from scan_gtm_hiring_signals or resolve_company_identity without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for use: only job_title is required, and it explains the conditional triggers for optional work (verify_position adds ~3s/9 requests and needs name+domain; use_llm_fallback only fires for titles the rules cannot place). It lacks explicit when-to-use-vs-sibling routing, but the 'does not discover people' statement effectively scopes it against the enrichment siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_ai_toolingDetect AI ToolingAIdempotent
Given a company domain, determine how far that company has gone with AI. Returns an ai_maturity tier of none, declared (says AI but nothing observable is running), deployed (AI tooling is live on the site), or commercialized (the pricing page charges for AI via credits, tokens, an add-on, an AI-named plan, or a per-outcome price), plus the detected AI vendors, validated llms.txt status, robots.txt AI-crawler policy, and the evidence behind the verdict. A domain behind a bot challenge returns blocked=true at low confidence rather than a false negative. Returns flat, Clay-ready JSON. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per domain analyzed.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | Company domain to analyze, without https or www, e.g. intercom.com. | |
| domains | No | Batch mode: several company domains analyzed in one call. Takes precedence over domain. | |
| vendors | No | Report only these AI vendors. Omit to report every one. Detection is unchanged, so filtering costs nothing extra. The ai_maturity verdict, llms.txt, robots.txt, and pricing reads are site wide and never narrowed by this. | |
| skipCache | No | Force a fresh analysis and ignore the 7 day result cache. | |
| check_pricing | No | Fetch and score the pricing page. Default true. Setting this false is faster but caps the result at 'deployed', because 'commercialized' can only be proven on a pricing page. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| request_timeout_ms | No | Per-request timeout in milliseconds. 3000 to 20000. Default: 9000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations by disclosing auth requirements (APIFY_TOKEN), cost behavior (consumes Apify credits per domain), the 7-day cache, and the blocked=true low-confidence path instead of a false negative. It also states it reads public data and writes nothing to the target domain, which is nuanced against readOnlyHint=false (the run itself spends credits) but not a direct misrepresentation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the maturity taxonomy are front-loaded, then it layers output contents, an edge case, and operational constraints. It is a dense single block that is longer than strictly needed, but nearly every sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly carries the return-shape burden by naming the fields an agent receives (tier, vendors, llms.txt status, robots.txt policy, evidence, blocked). Combined with the auth and cost notes, nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter already carries its own documentation, making the baseline 3. The description reinforces the key semantics (vendors filter costs nothing extra, check_pricing caps the tier at 'deployed', batch mode precedence) but adds little that the schema doesn't already state.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource (analyze a company domain for AI adoption) and enumerates the exact output taxonomy: an ai_maturity tier of none/declared/deployed/commercialized. That level of specificity lets an agent separate it from the neighboring detect_gtm_tech_stack, which covers general GTM stack rather than AI adoption depth.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied rather than stated: batch mode 'takes precedence over domain', skipCache forces a fresh run, and check_pricing=false is only worth setting when 'deployed' is an acceptable ceiling. There is no explicit when-to-use/when-not or a named alternative among the many sibling detection tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_gtm_tech_stackDetect GTM Tech StackAIdempotent
Detect which GTM tools a company uses from its public website. Returns CRM, sequencer, and marketing automation signals with per-tool boolean flags as a flat, Clay-ready JSON row. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Deprecated alias for domain, accepted by the actor as a full company website URL. Prefer domain. | |
| domain | No | Bare company domain, e.g. stripe.com. Supply this, company_domain or url. | |
| skipCache | No | By default a clean detection is cached for 7 days and reused. Set true to force a fresh detection. | |
| technologies | No | Report only these tools. Omit to report every detectable tool. Only tools with a client side fingerprint are selectable. Detection is unchanged, so filtering costs nothing extra. | |
| company_domain | No | Deprecated alias for domain, accepted by the actor for older callers. Prefer domain. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| crawl_additional_pages | No | Crawl up to 2 extra pages for better coverage. Defaults to true when omitted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds real value beyond the annotations: it discloses the APIFY_TOKEN requirement, that Apify credits are consumed per call, that only public data is read, and the shape of what comes back. The annotations already cover openWorld/idempotent/destructive, so the bar is lower and auth/cost disclosure is exactly the kind of extra context that earns credit. The only soft spot is that 'writes nothing' sits slightly awkwardly next to readOnlyHint=false (defensible, since the call spends credits), which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, then return shape, then behavioral constraints. Each sentence carries distinct information (what, what-you-get, cost/auth) with no filler or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully carries the return-value burden by describing a flat per-tool boolean JSON row. Combined with the schema's coverage of caching, filtering and spend caps, only minor items (error/async behavior, latency) are unaddressed, so this is close to complete for a detection tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: all seven parameters, including the deprecated url/company_domain aliases, the 7-day cache behavior, the technologies filter and max_charge_usd, are already documented in the schema. The description adds no parameter-level detail beyond what is there, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Detect which GTM tools a company uses from its public website') and narrows the resource to CRM, sequencer and marketing automation signals, which separates it in substance from siblings like detect_ai_tooling or fingerprint_outbound_infrastructure. It does not name or contrast any sibling explicitly, so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the stated source ('from its public website') and the 'Clay-ready JSON row' output, which signals an enrichment-pipeline context. However, there is no explicit when-to-use/when-not guidance, no prerequisites beyond the token, and no alternative tool is named despite many overlapping sibling enrichment tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrich_company_firmographicsEnrich Company FirmographicsAIdempotent
Enrich a company domain into structured firmographics: employee band, industry, HQ, founded year, revenue estimate, logo, and description, with source provenance. Parsed from the company's schema.org/Organization JSON-LD and HTML meta tags and returned as a flat, Clay-ready JSON row with a source_signals array and a data_completeness score. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | Bare company domain to enrich, e.g. stripe.com. Provide this or domains. | |
| domains | No | List of bare domains for batch processing. Takes precedence over domain. | |
| batchSize | No | Domains enriched concurrently per wave in batch mode. Default 5, maximum 10. | |
| skipCache | No | Force a fresh enrichment and ignore the 7 day result cache. | |
| company_name | No | Optional company name, used as a fallback label when the page does not expose one. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: auth requirement (APIFY_TOKEN), per-call credit consumption, a 7-day result cache with a skipCache escape, a source_signals provenance array, and a data_completeness score. Minor tension with readOnlyHint=false given the claim 'writes nothing' — defensible since the call still consumes credits and creates a cached run, but the description could reconcile that explicitly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the operation and output before the operational caveats. Efficient, though the first sentence is a long run-on that could be split for faster scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-shape burden and does so (flat Clay-ready JSON row, source_signals, data_completeness). Combined with auth, cost, caching, and non-destructiveness notes, an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all six parameters (domain/domains precedence, batchSize caps, skipCache, max_charge_usd) are already documented in the schema. The description adds the return-row shape but no extra parameter semantics, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (enrich) and resource (company domain into firmographics) and enumerates the exact output fields (employee band, industry, HQ, founded year, revenue, logo, description). This is unmistakably distinct from siblings like detect_gtm_tech_stack or resolve_linkedin_url, so an agent can select it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description supplies operating context (public data only, requires APIFY_TOKEN, consumes Apify credits, 7-day cache) but never states when to reach for this tool versus alternatives such as resolve_company_identity or score_icp_fit. Usage is implied by the resource name rather than explicitly routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fingerprint_outbound_infrastructureFingerprint Outbound InfrastructureAIdempotent
Given a company domain, determine whether that company runs cold email outbound and on what stack. Returns a runs_outbound verdict of program (a deliberate cold outbound setup), light (one weak signal), none, or unknown, with the evidence behind it. The strongest signal is the lookalike sending domains a real program leaves behind: domains like getcompany.com or company-mail.com that carry their own mail and redirect back to the primary site. Also returns the inbox provider (Google Workspace, Microsoft 365 and others) for the primary domain and each sending domain, any detected sending platform (Outreach, Salesloft, Lemlist, Instantly, Smartlead, Apollo and more), registration clusters showing sending domains bought on the same day, cold email infrastructure vendors, and SPF, DKIM and DMARC posture. Sending platform recall is partial by design: sequencers that connect over OAuth to a customer's own mailbox leave no DNS trace, so an empty sending_platforms means little while a populated one is solid. Public DNS and HTTP redirects only. Returns flat, Clay-ready JSON. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per domain analyzed.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | Company domain to analyze, without https or www, e.g. smartlead.ai. | |
| domains | No | Batch mode: several company domains analyzed in one call. Takes precedence over domain. | |
| skipCache | No | Force a fresh analysis and ignore the 7 day result cache. | |
| dns_timeout_ms | No | Per-DNS-lookup timeout in milliseconds. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| request_timeout_ms | No | Per-HTTP-request timeout in milliseconds. | |
| check_deliverability | No | Add a blacklist check and a 0-100 health score by running the separate Domain Deliverability Checker actor, which bills its own per-domain rate on top of this one. Default false. SPF, DKIM and DMARC are read from DNS either way. | |
| scan_sending_domains | No | Scan for lookalike sending domains. Default true. The strongest signal and the slowest step; turning it off caps the verdict at what platform and deliverability signals alone can prove. | |
| sending_domain_depth | No | deep (default) checks .com, .co, .io, .net and .org. standard drops .net and .org. | |
| max_sending_domain_probes | No | Cap on how many candidate sending domains are probed per company. Lower it to bound run time on companies with many lookalike domains. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite readOnlyHint=false, the description discloses unusually rich behavior beyond the annotations: it requires an APIFY_TOKEN, consumes Apify credits per domain, uses public DNS/HTTP redirects only, and explicitly warns that sending-platform recall is partial by design (OAuth-connected sequencers leave no DNS trace), so an empty list means little. That is exactly the kind of caveat an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and verdict semantics are front-loaded, and the dense enumeration of returned fields earns its place because there is no output schema. It is a long single block of prose, which costs some readability, but there is little genuinely redundant content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of explaining returns and does so thoroughly: the runs_outbound verdict values and their meanings, inbox providers, sending platforms, registration clusters, vendors, and SPF/DKIM/DMARC posture, plus auth and cost requirements. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with 10 well-documented parameters, so the schema does the heavy lifting and the baseline is 3. The description adds no syntax or defaulting guidance for individual parameters (it never mentions domain vs domains precedence, skipCache, or timeouts), so it does not exceed the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+scope: 'Given a company domain, determine whether that company runs cold email outbound and on what stack.' That is far more precise than the sibling detect_gtm_tech_stack or detect_ai_tooling, and an agent can tell instantly what this tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied clearly (domain-based cold-outbound fingerprinting), but there is no explicit when-to-use/when-not guidance and no comparison to adjacent siblings such as detect_gtm_tech_stack, which an agent might reasonably confuse with 'on what stack' detection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_company_changesGet Company ChangesA
Monitor a company domain for changes across hiring, tech stack, funding, firmographics, and social since the last run. Returns only what changed as typed change events in flat, Clay-ready JSON. Pass sources to watch fewer than all five sources and min_severity to drop minor changes; each source left out is one fewer sub actor run on the bill. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | Company domain to monitor, without https or www, e.g. stripe.com. | |
| sources | No | Which sources to monitor. Omit for all five. Each source left out is one fewer sub actor run per company, so a single source watch is billed for one source, not five. | |
| company_name | No | Optional company name hint, used when the domain does not match the brand name, e.g. Deel for deel.com. | |
| min_severity | No | Report only changes at or above this severity. low reports every change and is the default. high keeps leadership moves, funding, acquisitions, and a CRM or sequencer appearing or disappearing. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| previous_snapshot | No | Snapshot object returned by a prior run. Supply it and it is the baseline instead of stored state, which is what makes a scheduled run cheap. | |
| sub_actor_timeout_secs | No | Per-child run timeout in seconds. Children run in parallel, so total wall time is about the slowest child. Default: 300. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true, idempotentHint=false); the description adds substantive context beyond that: it reads public data, requires an APIFY_TOKEN, consumes Apify credits per call, bills per sub actor run, and stores a baseline snapshot. The phrase 'writes nothing' sits in mild tension with readOnlyHint=false, though that is most plausibly about external data rather than the billing/state side effects it does disclose.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with purpose and return shape, then parameter/cost guidance, then auth and billing constraints. Nothing is redundant, though the final sentence packs three separate constraints together rather densely.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter tool with a nested object and no output schema, the description covers purpose, cost model, auth requirement, and baseline behavior. The return value is only sketched ('typed change events in flat, Clay-ready JSON'), which is thin given no output schema exists, but it is enough for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: omitting 'sources' costs five sub actor runs versus one, and 'previous_snapshot' replaces stored state and makes scheduled runs cheap. These are real decision-relevant semantics layered on top of the field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Monitor a company domain for changes') and enumerates the five monitored dimensions, plus what is returned ('only what changed as typed change events'). It is clear what the tool does, but it never distinguishes itself from the sibling scan/detect tools (scan_gtm_hiring_signals, detect_gtm_tech_stack, get_funding_press_signals) that cover the same domains, leaving the delta framing as the only implicit differentiator.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Since the last run' and the snapshot baseline imply a recurring/scheduled monitoring use case, and the description advises passing 'sources' and 'min_severity' to reduce scope and cost. However, it never states when to prefer this aggregator over the individual sibling signal tools, so the when-to-use guidance remains implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_funding_press_signalsGet Funding and Press SignalsAIdempotent
Scan Google News and PR wires for funding rounds, executive moves, product launches, and acquisitions at any company domain. Returns deduplicated, dated events in flat Clay-ready JSON. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | Company domain to scan, without https or www, e.g. stripe.com. | |
| company_name | No | Optional company name hint, used when the domain does not match the brand name, e.g. Deel for deel.com. | |
| signal_types | No | Report only these event types. Omit for every type. Narrowing also narrows the search: a funding only run issues one news query instead of four. | |
| lookback_days | No | How far back to search, in days. Default 365. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real context beyond the annotations: it requires an APIFY_TOKEN and consumes Apify credits per call, and it returns deduplicated, dated events in flat Clay-ready JSON. The 'writes nothing' claim sits in mild tension with readOnlyHint=false, though the disclosed per-call credit consumption plausibly accounts for the non-read-only flag.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: purpose and sources first, then return format, then behavioral/auth/cost constraints. No filler, and the most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still characterizes the return value (deduplicated, dated, flat Clay-ready JSON), and it discloses the auth requirement and cost model. Nothing needed to invoke this correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters are already documented, including the signal_types narrowing behavior and the max_charge_usd cap. The description echoes the event types and output shape but adds no syntax or format detail the schema lacks, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Scan) and resource (Google News and PR wires) plus the exact event classes retrieved (funding rounds, exec moves, product launches, acquisitions). This clearly separates it from siblings like scan_gtm_hiring_signals or detect_gtm_tech_stack, which cover different signal families.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the named sources and event types, and 'at any company domain' signals broad applicability, but there is no explicit when-to-use statement, no when-not, and no routing to alternative or complementary tools such as aggregate_gtm_signals. The reader must infer the fit from the content.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
map_company_event_presenceMap Company Event PresenceAIdempotent
Give it a company domain. It returns the third party conferences and trade shows that company publicly says it attends, with a year for each where one can be resolved, as one flat row. The search runs against the company's own domain, which is what stops a brand collision returning another company's events. The company's own conference is reported separately and is never mixed into the attendance list. It finds events for roughly 2 companies in 10, and an empty row is an honest empty row rather than a guess: read coverage, fetch_status and queries_failed to tell a company with no published events apart from a search that could not see. Events dated outside the years you ask for are still returned and flagged, so filter on event year rather than assuming the input filtered for you. This is not an events database and not an exhibitor list: it takes a company and reports what that company publishes. Requires an APIFY_TOKEN and consumes Apify credits. Read only.
| Name | Required | Description | Default |
|---|---|---|---|
| years | No | Comma separated, for example 2025,2026. Events dated outside this set are still returned and flagged. Sent as a string so it works from Clay. Default: "2025,2026". | |
| domain | Yes | A single company domain, for example 6sense.com. Protocol and path are stripped. | |
| skipCache | No | false uses the 21 day result cache. true forces a fresh look. Default: "false". | |
| max_queries | No | Between 1 and 5. Each query costs roughly 0.8 seconds plus a 1.3 second pause. 2 is the measured sweet spot: search engines refuse a third query from the same container almost every time, and the third query added no events the first two did not already find. Sent as a string so it works from Clay. Default: "2". | |
| company_name | No | Improves matching when the brand differs from the domain stem, for example Gong for gong.io. Derived from the domain when left empty. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| include_own_events | No | Reports whether the company runs its own conference as a separate field. It is never mixed into the attendance list. Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a lot the annotations do not: cache (21 days unless skipCache), credit consumption and APIFY_TOKEN requirement, per-query latency, a max_queries rationale, the domain-scoped search that prevents brand collisions, and the rule that out-of-range years are returned and flagged. Against that, the closing claim 'Read only.' conflicts with readOnlyHint=false in the annotations, so the safety framing an agent sees in prose disagrees with the structured safety field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core contract - domain in, flat row of declared attendance out, domain-scoped search - is front-loaded in the first two sentences, and the caveats that follow (hit rate, empty-row semantics, year flagging, cost) are all decision-relevant. It is dense rather than bloated, though the 'not an events database / not an exhibitor list' and 'Read only' tail sentences are the weakest and most repetitive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description has to explain return shape, and it does: one flat row, a year per event where resolvable, separate field for the company's own conference, and named diagnostic fields (coverage, fetch_status, queries_failed) for interpreting an empty result. Combined with cost/cache/auth disclosure, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and most of the description's parameter content (years being a soft filter, include_own_events being reported separately, max_queries sweet spot, cache behavior) is already documented in the schema property descriptions, so it largely restates structured data. The description does add operational meaning by tying years and include_own_events to what actually appears in the returned row, but the baseline of 3 applies when the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: given a company domain it returns the third-party conferences/trade shows that company publicly says it attends, as one flat row. It also draws sharp boundaries against nearby concepts ('not an events database and not an exhibitor list') and separates the company's own conference from the attendance list, so an agent can distinguish it from siblings such as monitor_public_awards or get_funding_press_signals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives strong context for when this is the right call: expected hit rate (roughly 2 companies in 10), an explicit instruction to read coverage, fetch_status and queries_failed to distinguish 'no published events' from 'search could not see', and a directive to filter on event year rather than trusting the input filter. It stops short of naming a sibling tool to use instead for event/exhibitor data, so it is clear context without explicit alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
map_company_social_presenceMap Company Social PresenceAIdempotent
Map a company's social media presence across LinkedIn, X, Instagram, Facebook, and YouTube. Returns profile URLs and follower counts in flat Clay-ready JSON. Profiles are discovered from the company's own homepage links, a web search fallback, and pattern guessing, then validated against the company. Follower counts are extracted where public; X is URL-only (its count needs login) and Instagram and Facebook counts are best-effort. Provide at least one of company_domain or company_name. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| platforms | No | Which platforms to map. Defaults to all five. | |
| skipCache | No | Force a fresh lookup and ignore the 7 day result cache. | |
| company_name | No | Optional company name. Improves search accuracy and disambiguation. Provide this or company_domain. | |
| company_domain | No | Bare company domain, e.g. stripe.com. Provide this or company_name. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| includeFollowerCounts | No | Fetch profile pages to extract follower counts (default true). Set false for URLs only, which is cheaper. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: discovery pipeline (homepage links, web-search fallback, pattern guessing) with validation, per-platform reliability caveats (X is URL-only, Instagram/Facebook counts best-effort), auth requirement (APIFY_TOKEN), and credit consumption. One minor tension: it asserts 'writes nothing' while readOnlyHint=false is defensible because the run writes a 7-day cache (exposed via skipCache).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what it maps, then output format, then method, then reliability limits, then requirements and cost. Five dense sentences with no filler, each carrying distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by specifying the return format (flat Clay-ready JSON with URLs and follower counts), the one-of identifier requirement, cost/auth prerequisites, and per-platform data-quality limits. Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents platforms, skipCache, both identifiers, max_charge_usd, and includeFollowerCounts. The description only reinforces the required-one-of rule and the follower-count cost tradeoff, adding little beyond structured data; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (map) and resource (company social presence) and enumerates the exact five platforms covered, plus the output shape (profile URLs and follower counts). An agent can distinguish it from siblings like map_company_event_presence or resolve_linkedin_url without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a real invocation constraint ('Provide at least one of company_domain or company_name') and a cost-driven toggle (set includeFollowerCounts false for URLs only, which is cheaper). However, it never says when to choose this tool over alternatives such as resolve_company_identity or enrich_company_firmographics, so usage is implied rather than routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monitor_public_awardsMonitor Public AwardsAIdempotent
Pick a public award register and a time window and it returns the companies that won public work in it, one flat row per winning company rather than one per award, with award count, total value, largest award, awarding body, award date, a deep link to the source record, and a resolved company domain. Five registers are covered: US federal contracts and US federal grants from USASpending, NIH SBIR and STTR from NIH RePORTER, and UK Contracts Finder and UK Find a Tender. This reports awards that have already been made, so it is not a tender feed and will not tell you what is open to bid on. US federal data lags about two days, so a one day window on a US register returns little or nothing. Winners are sorted by total award value and max_entities is the hard cap on billed rows. Requires an APIFY_TOKEN and consumes Apify credits. Read only.
| Name | Required | Description | Default |
|---|---|---|---|
| register | Yes | Which award register to read. US federal contracts and grants come from USASpending, NIH SBIR and STTR from NIH RePORTER, and the two UK registers from Contracts Finder and Find a Tender. Default: "us_federal_contracts". | |
| window_days | No | How many days back from today to read awards for. 1 to 90. US federal data lags about two days, so do not use a one day window on the US registers. Sent as a string so it works from Clay. Default: "7". | |
| max_entities | No | Hard cap on billed rows. 1 to 1000. Winners are sorted by total award value, and the run log says how many were dropped. Sent as a string so it works from Clay. Default: "100". | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| min_award_value | No | Drops awards below this amount in the register's own currency. Set to 0 to keep everything. Sent as a string so it works from Clay. Default: "100000". | |
| resolve_domains | No | Looks up each winner's website. Turning it off makes the run roughly 20x faster and returns recipient_domain as null with domain_status not_attempted. Default: true. | |
| domain_confidence_floor | No | How sure the actor has to be before it gives you a domain. Strict returns fewer domains and almost no wrong ones. Loose returns the most domains and about a third of them are wrong. Default: "standard". | |
| exclude_government_recipients | No | Drops winners that are themselves government, universities, or public authorities. Leave this on for the grant registers or you get state departments of education instead of companies. Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description closes with 'Read only,' but the annotations declare readOnlyHint=false, which asserts the tool is not read-only. That is a direct contradiction of the structured safety signal an agent relies on to decide whether a call is side-effect free. The otherwise useful behavioral detail (APIFY_TOKEN requirement, Apify credit consumption, ~two-day US data lag, sort order, hard row cap) cannot compensate for a contradictory safety claim.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The output shape and register list are front-loaded, and the paragraph packs a lot of decision-relevant facts into roughly 150 words without filler. There is some redundancy, notably the US two-day lag stated here and again in the window_days schema description, and the long single paragraph makes the cost and access constraints easy to skim past.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates the returned columns (award count, total value, largest award, awarding body, award date, deep link, resolved domain) and names all five registers, so an agent knows what comes back. It also covers cost and credential prerequisites, though it does not address pagination, run-log access, or what happens when a window yields nothing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all eight parameters, including the string-typed numerics for Clay compatibility, the enum values, and the max_charge_usd semantics. The description reinforces register coverage and the sorting rationale behind max_entities, but largely restates the schema ('max_entities is the hard cap on billed rows', the two-day lag on window_days), adding little beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause gives a specific verb and resource (returns companies that won public work, given a register and time window) and immediately specifies the grain ('one flat row per winning company rather than one per award'). It also pre-empts confusion with adjacent tool categories by stating it is not a tender feed, which no sibling tool covers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states clear conditions for use (pick a register plus a time window) and an explicit when-not ('not a tender feed and will not tell you what is open to bid on'), plus a concrete operational caveat that a one-day window on US registers returns little or nothing. It stops short of naming an alternative tool or route for the tender-feed use case, so the exclusion is stated but not redirected.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
push_leads_to_sequencerPush Leads to SequencerA
Push enriched lead rows into an existing Instantly or Smartlead campaign. Maps common Clay column names onto each sequencer's own field names, optionally drops leads below a minimum ICP score, optionally deduplicates against the leads already in the destination campaign, and sends the rest in batches. Returns one flat summary row: how many leads were received, dropped for having no usable email, dropped by the ICP gate, dropped as duplicates, eligible, actually created by the sequencer, skipped by the sequencer, and failed, plus the vendor's own error message per failed address. The campaign must already exist; this does not create campaigns or write sequence copy. Set dry_run true to get back the exact request payload that would be sent without creating a single lead and without being charged, which is the safe way to check a mapping against a new campaign. Billing is per lead the sequencer confirms it created, so gated, duplicate, skipped, failed and dry-run leads are all free. Instantly uses API v2 and needs a v2 key; Smartlead uses API v1. Requires an APIFY_TOKEN and consumes Apify credits. This WRITES to your sequencer campaign unless dry_run is true.
| Name | Required | Description | Default |
|---|---|---|---|
| leads | No | Lead rows to push. Each row needs an email at minimum. Takes precedence over dataset_id when both are set. | |
| api_key | No | Your Instantly v2 API key or your Smartlead API key. An Instantly v1 key will not work: v1 was deprecated on January 19, 2026. Required for any run that calls the sequencer. A dry run with deduplicate false makes no calls and needs no key. | |
| dry_run | No | Run every step, return the exact payload that would be sent, and make zero write calls. Creates no leads and charges nothing. Default false. | |
| sequencer | Yes | Which sequencer to push to. Instantly uses API v2, Smartlead uses API v1. | |
| dataset_id | No | An Apify dataset ID from an upstream run, for example the output of score_icp_fit. Used only when leads is empty. | |
| campaign_id | Yes | The target campaign in the sequencer. It must already exist. Instantly campaign IDs are UUIDs; Smartlead campaign IDs are numeric. | |
| deduplicate | No | Read the campaign's existing leads first and drop any email already there. Default true. This is a read, so it needs an API key even on a dry run. | |
| field_mapping | No | Override the default Clay column to sequencer field map. Keys are your column names, values are the sequencer field names. Set a value to an empty string to drop that column. A target the sequencer does not have is sent as a custom variable rather than rejected. | |
| min_icp_score | No | Drop leads whose icp_score is below this number. Default 0, which pushes everything. Rows with no icp_score are always kept. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| custom_variables | No | Extra column names to pass through as custom variables under their own name. Columns that are neither mapped nor listed here are dropped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations: it discloses the billing model (per lead the sequencer confirms it created; gated, duplicate, skipped, failed and dry-run leads are free), auth requirements (v2 key for Instantly, v1 for Smartlead, APIFY_TOKEN), credit consumption, and that deduplicate's read still requires a key even on a dry run. The annotations only give a coarse safety profile (not read-only, not destructive); the description supplies the operational detail that matters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and result shape, then caveats and billing; every sentence carries real information. It is long, but the caller has 11 parameters and a nested object, so the length is largely earned rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the return-value burden and does so completely, enumerating the summary fields (received, no-email drops, ICP drops, duplicates, eligible, created, skipped, failed) plus per-address vendor errors. Auth, billing, dry-run semantics and campaign preconditions are all covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the schema already documents leads, api_key, dry_run, deduplicate and others thoroughly. The description adds value by explaining cross-parameter interactions the schema states only locally: batch sending, the dedupe-vs-dry-run-vs-api_key dependency, and what 'the rest' means after drops.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('push enriched lead rows into an existing Instantly or Smartlead campaign') and enumerates the transformations it performs (field mapping, ICP gate, dedupe, batching). It is the only write/outbound tool among siblings that are otherwise read-and-enrich operations, and the description makes that distinction unmissable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly bounds when-not-to-use: 'The campaign must already exist; this does not create campaigns or write sequence copy.' It also routes the agent to a safe validation path ('Set dry_run true ... which is the safe way to check a mapping against a new campaign') and names an upstream sibling (score_icp_fit) as the source of dataset_id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_company_identityResolve Company IdentityAIdempotent
Resolve any combination of company name, domain, or LinkedIn URL into one canonical company identity: the name, primary domain, and LinkedIn company URL, each with a 0-100 confidence score plus an overall score and a match method. Cross-checks the inputs you give it, resolves the ones you do not, and flags conflicts (a domain and a LinkedIn slug that disagree) instead of merging them. A LinkedIn URL the actor finds is returned only when verified against the company site or the name, with the reason in linkedin_verification. Provide at least one of company_name, domain, or linkedin_url. Use this to reconcile or deduplicate records you already hold; use resolve_linkedin_url instead when you only need the LinkedIn company URL for a domain or name. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | Bare company domain, e.g. stripe.com. The strongest canonical key when provided. | |
| skipCache | No | Force a fresh resolution and ignore the 7 day result cache. | |
| company_name | No | Company name, e.g. Stripe. Provide at least one of company_name, domain, or linkedin_url. | |
| linkedin_url | No | LinkedIn company URL (https://www.linkedin.com/company/stripe) or bare slug (stripe). | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| minLinkedinConfidence | No | A LinkedIn page the actor finds is returned only when its linkedin_confidence is at least this value, 0 to 100. Default "70". A LinkedIn URL you provide is always returned as given. Sent as a string for Clay compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: conflict detection instead of merging, LinkedIn URLs returned only when verified with the reason surfaced in linkedin_verification, live public-data reads with no data writes, an APIFY_TOKEN requirement, and per-call Apify credit consumption. The credit/actor-run side effect is exactly what reconciles the non-read-only annotation with the 'writes nothing' phrasing, so an agent is not misled.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and every sentence carries information (behavior, conflict policy, verification, alternative routing, auth, cost). It is one dense block rather than cleanly separated purpose/usage/behavior sections, which slightly hurts scanability for a description of this length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description covers the return shape (name, primary domain, LinkedIn URL, per-field 0-100 confidence, overall score, match method, linkedin_verification). It also covers auth, cost, input preconditions, and the sibling alternative, so nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics the schema lacks: the three identity inputs are cross-checked against each other, unspecified ones are resolved, and disagreeing domain/LinkedIn inputs are flagged rather than merged. It also restates the at-least-one-input rule that the zero-required-parameter schema does not enforce via anyOf.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb + resource + outcome: resolve name/domain/LinkedIn URL into one canonical identity with per-field confidence scores, an overall score, and a match method. It explicitly differentiates itself from the sibling resolve_linkedin_url ('use resolve_linkedin_url instead when you only need the LinkedIn company URL'), so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit condition and alternative: 'Use this to reconcile or deduplicate records you already hold; use resolve_linkedin_url instead when you only need the LinkedIn company URL for a domain or name.' It also states the input precondition ('Provide at least one of company_name, domain, or linkedin_url'), leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_legal_entityResolve Legal EntityAIdempotent
Give it a company domain and it returns the registered legal entity behind it: legal name, company number, jurisdiction, status, entity type, LEI and VAT number, as one flat row with a full audit trail of what was rejected and why. Three registers are queried: UK Companies House, GLEIF and SEC EDGAR. Register search endpoints are fuzzy and always return something, so by default a record is accepted only when the normalized legal names are identical. That is why roughly 6 domains in 10 resolve rather than 10 in 10, and why a null here is a trustworthy answer rather than a gap. Read match_method, match_confidence and rejected_candidates before acting on a match. Setting match_strictness to fuzzy will hand you a confidently wrong company on most domains and should be treated as a research mode, not a default. This is not a company database and not a credit or risk product. Requires an APIFY_TOKEN and consumes Apify credits. Read only.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | A single company domain, for example monzo.com. Protocol and path are stripped. | |
| skipCache | No | false uses the cache: 90 days for a resolved company, 7 days for a null. true forces a fresh look. Default: "false". | |
| validate_vat | No | Runs any VAT number found on the company's own pages through the EU VIES service and returns the name VIES holds for it, as a cross-check against the register name. Default: true. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| legal_name_hint | No | Skips the domain lookup and goes straight to the registers with this name. Use it when you already have the legal name and just want the register record. | |
| match_strictness | No | exact accepts a register record only when the normalized legal names are equal, which is the default and the recommendation. fuzzy returns the best scoring candidate with a confidence below 100 and a warning in rejected_candidates. Register search is fuzzy and always returns something, so fuzzy mode will hand you a confidently wrong company on most domains. Default: "exact". | |
| jurisdiction_hint | No | ISO-2 country code, for example GB or US. Narrows which registers are queried and cuts latency. Leave empty to query every register. | |
| sec_requester_name | Yes | Required. Your own name or your company's name. The SEC requires every automated request to EDGAR to identify the requester by name and email, and the actor sends yours, never a default. | |
| sec_requester_email | Yes | Required. Your own working email address. Sent to the SEC with your name in the User-Agent of each EDGAR request, in the form the SEC asks for. Nothing else uses it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real behavioral context: ~6/10 resolve rate, defaults that reject non-identical names, requirement for APIFY_TOKEN, credit consumption, cache TTLs implied via skipCache. It does not restate readOnlyHint. However, the annotation readOnlyHint=false contradicts the description's closing 'Read only.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what the tool does and its output, then explains the matching policy and the null-rate caveat. Slightly long, but every sentence carries non-obvious information. Could trim the sibling list of registers if it ever grew.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite 9 parameters and no output schema, the description gives an agent everything needed: what it returns, the match semantics, the failure mode, the cost/auth model, and the trustworthiness of nulls. No material gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema carries parameter detail. The description still adds value by explaining why match_strictness defaults to exact and why fuzzy is risky, and by framing SEC requester fields as regulatory requirements rather than arbitrary inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (resolve) and resource (legal entity) with a precise output contract: registered legal name, company number, jurisdiction, status, entity type, LEI, VAT. It also names the three data sources (Companies House, GLEIF, SEC EDGAR), which distinguishes it clearly from siblings like resolve_company_identity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use fuzzy vs exact, when to use legal_name_hint, and what a null answer means. It also states when NOT to use it: 'not a company database and not a credit or risk product.' This is exactly the routing guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_linkedin_urlResolve LinkedIn URLAIdempotent
Resolve a company domain or name to its LinkedIn company URL, with a 0-100 confidence_score, social links, and optional firmographics from search snippets, as a flat, Clay-ready JSON row. A URL is returned only when verified: the company homepage links it, or its name is identical to the name the company site declares or the company_name you pass; otherwise linkedin_company_url is null and verification says why. No request is sent to LinkedIn. Provide at least one of company_domain or company_name. Use this when the LinkedIn company URL is the answer you need; use resolve_company_identity instead to cross-check a name, domain, and LinkedIn URL you already hold and get a canonical identity with conflicts flagged. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| skipCache | No | When "false", the default, a successful resolution is cached for 7 days and reused. Set "true" to force a fresh resolution. Sent as a string for Clay compatibility. | |
| company_name | No | Company name. Required if company_domain is not provided. | |
| company_domain | No | Bare company domain, e.g. stripe.com. Required if company_name is not provided. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| minConfidenceScore | No | A LinkedIn page is returned only when its match score is at least this value, 0 to 100. Default "70". Raise it for fewer, surer answers; lower it for more answers and more wrong ones. Sent as a string for Clay compatibility. | |
| includeFirmographics | No | When "true", also reads employee count, industry, HQ, follower count and description from search result snippets about the LinkedIn company page. No request is sent to LinkedIn. Fields no snippet states stay null. Off by default because it can add a search. Sent as a string for Clay compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses far more than the annotations: the exact verification rule for returning a URL vs null, that no request is sent to LinkedIn, 7-day caching, that it requires an APIFY_TOKEN, and that it consumes Apify credits per call. This explains why readOnlyHint is false (credit side effects) despite the tool writing no data, which the description states explicitly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the sibling distinction, then verification, then inputs, then routing and cost. Dense and every clause carries information, though it is delivered as one long block rather than broken into scannable units.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still characterizes the return shape (flat Clay-ready JSON row with confidence_score, social links, optional firmographics, and null-plus-reason when unverified). For a 6-param, 0-required, externally-billed call, nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds value beyond the schema: the 'at least one of company_domain or company_name' constraint is not expressed by required=0, and it explains what minConfidenceScore buys (fewer, surer answers vs more wrong ones).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Resolve a company domain or name to its LinkedIn company URL') plus the returned payload (confidence_score, social links, firmographics). It explicitly names and distinguishes the sibling resolve_company_identity, so an agent can route correctly without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a positive trigger ('Use this when the LinkedIn company URL is the answer you need'), names the alternative and its distinct purpose ('use resolve_company_identity instead to cross-check a name, domain, and LinkedIn URL you already hold'), and states the input precondition ('Provide at least one of company_domain or company_name').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_gtm_hiring_signalsScan GTM Hiring SignalsAIdempotent
Scan company career pages to detect GTM hiring activity. Returns sales, marketing, and revenue operations job postings across Greenhouse, Lever, and Ashby as a flat, Clay-ready JSON row. Use this for a go-to-market hiring verdict (is the company building its sales and marketing team, and how fast); use scan_job_board_keywords instead to count open roles in categories or keywords you choose, including non-GTM roles. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Processing mode. "single" scores the domain. "velocity" compares this run against previous_gtm_role_count and previous_run_date. "batch" is an actor-level mode this single-call tool supplies no list for. Default: "single". | |
| domain | Yes | Bare company domain, e.g. stripe.com | |
| ats_slug | No | Optional ATS board slug override when it differs from the domain. | |
| role_filter | No | Optional list of GTM role keywords to filter on. Defaults to the built-in list. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| previous_run_date | No | ISO date of the previous run for this domain, used in velocity mode to report days between runs. | |
| include_role_details | No | When true, include the full per-role detail array (title, department, location, url). Default: false. | |
| previous_gtm_role_count | No | GTM role count from the previous run for this domain, used in velocity mode to compute the delta. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, openWorldHint=true, idempotentHint=true, destructiveHint=false. The description adds genuinely useful context not in the annotations: it reads public data, writes nothing, requires an APIFY_TOKEN, and consumes Apify credits per call. It does not disclose rate limits or failure modes, but for a read-only scraper this is strong additional context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with what it does and what it returns, followed by the routing rule to the sibling, then the operational requirements. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-param, no-output-schema, open-world scraper, the description covers purpose, return shape ("flat, Clay-ready JSON row"), routing, and operational prerequisites. Slightly less than complete because it doesn't mention the batch mode's limitation (that this single-call tool supplies no list) which the schema notes, but the schema already carries that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 8 parameters (including mode's enum semantics and velocity-mode dependencies on previous_gtm_role_count/previous_run_date) are already fully documented in the schema. The description adds no parameter-level detail beyond what the schema provides, which is correct given full coverage — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (scan) and resource (career pages) and defines the narrow scope (GTM hiring activity: sales, marketing, revops). It explicitly names the sibling it differs from, scan_job_board_keywords, and the axis of difference (GTM-only vs arbitrary keyword counts).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit when-to-use case ("for a go-to-market hiring verdict") and an explicit alternative with the condition that selects it ("use scan_job_board_keywords instead to count open roles in categories or keywords you choose, including non-GTM roles"). No inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_job_board_keywordsScan Job Board KeywordsAIdempotent
Scan a company's job board for roles in chosen categories across Greenhouse, Lever, Ashby, Workday, and Rippling. Returns matched role counts and titles per category as a flat, Clay-ready JSON row. Use this when you choose the role categories or keywords (engineering, finance, a product name in a job ad); use scan_gtm_hiring_signals instead for the fixed sales and marketing hiring verdict. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| company_domain | Yes | Bare company domain, e.g. stripe.com | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| custom_keywords | No | Keyword strings to match when Custom is included in role_categories. | |
| enable_fallback | No | Fall back to a pre-indexed job database when the live ATS cascade finds nothing. | |
| role_categories | Yes | One or more of: GTM, Engineering, Finance, Operations, Executive, Custom. | |
| previous_run_date | No | ISO date of the previous run, e.g. 2026-03-15. | |
| previous_roles_detected | No | Comma-separated matched role titles from a previous run, to compute deltas. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover openWorld, idempotent and destructive hints, so the description's job is to add what they don't say — and it does: requires an APIFY_TOKEN, consumes Apify credits per call, and reads public data only. There is a mild tension between readOnlyHint=false and the phrase 'writes nothing', though the consumer of Apify credits plausibly explains the false hint; no strong contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tightly packed sentences with the purpose front-loaded and no filler. The final sentence stacks four separate facts (public data, no writes, token requirement, credit cost) which makes it dense, but each clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description tells the agent what comes back (matched role counts and titles per category as a flat, Clay-ready JSON row). Combined with full schema coverage on all seven parameters and the cost/auth disclosure, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: it clarifies that role_categories are user-chosen (engineering, finance, a product name in a job ad) and that custom_keywords work with the Custom category, giving the agent the intent behind two of the seven parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (scan) and resource (a company's job board for roles in chosen categories), and names the exact surface it covers (Greenhouse, Lever, Ashby, Workday, Rippling) plus the return shape. It also names the sibling it is not (scan_gtm_hiring_signals), so an agent can distinguish the two without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit selection rule: use this one 'when you choose the role categories or keywords'; use scan_gtm_hiring_signals 'instead for the fixed sales and marketing hiring verdict.' That is a clean when/when-not with the alternative named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
score_icp_fitScore ICP FitAIdempotent
Score a company against your ideal customer profile (ICP) using weighted signals. Returns a 0 to 100 icp_score, an A to D icp_tier, and a per-signal breakdown as a flat, Clay-ready JSON row. Define your ICP with a template, scoring_config, or plain-English icp_description (which requires llm_api_key). Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per call.
| Name | Required | Description | Default |
|---|---|---|---|
| industry | No | The company's industry (from the Company Firmographic Enricher, Actor ID YlUtLWjfPpqykmB8g). | |
| template | No | Name of a prebuilt scoring config. | |
| headcount | No | Current employee headcount. Accepts a numeric string (e.g. "3000"). Sent as a string for Clay compatibility and coerced to integer at runtime. | |
| job_count | No | Number of open jobs found, from the Job Board Keyword Signal Scanner (Actor ID 4DvqpvhMR74NLcDDY). Scores via active_hiring_volume when at or above min_job_count (default 3). Accepts a numeric string. | |
| uses_clay | No | Whether the company uses Clay. Accepts a boolean-like string ("true"/"false"). Sent as a string for Clay compatibility and coerced to boolean at runtime. | |
| tech_stack | No | Comma-separated list of technologies. Used to auto-detect CRM/sequencing tools if booleans are not set. | |
| has_twitter | No | Whether a company X/Twitter profile was found, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h). Contributes to social_presence. Accepts a boolean-like string. | |
| hq_location | No | Headquarters location from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g). Carried for reference; not currently scored. | |
| llm_api_key | No | Your OpenAI or Anthropic key, used only with icp_description. | |
| company_name | No | Optional display name of the company. | |
| crm_detected | No | Whether any CRM was detected. Accepts a boolean-like string ("true"/"false") or any non-empty CRM name (e.g. "Salesforce"). Sent as a string for Clay compatibility and coerced to boolean at runtime. Auto-derived from uses_hubspot/uses_salesforce if not set. | |
| founded_year | No | Year the company was founded, from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g). Carried for reference; not currently scored. Accepts a numeric string (e.g. "2015"). | |
| has_linkedin | No | Whether a company LinkedIn page was found, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h) or the Domain to LinkedIn URL Resolver (Actor ID 3HtnSaqPHOg1Qg5gx). Contributes to social_presence. Accepts a boolean-like string. | |
| llm_provider | No | LLM provider for icp_description: openai or anthropic. | |
| uses_hubspot | No | Whether the company uses HubSpot. Accepts a boolean-like string ("true"/"false"). Sent as a string for Clay compatibility and coerced to boolean at runtime. | |
| employee_band | No | Firmographic employee band from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g), e.g. "201-500". Scores via employee_band_match when it is in target_employee_bands. | |
| fetch_signals | No | If true, the actor runs the GTM Hiring Signal Scraper and the GTM Tech Stack Signal Scraper for this company before scoring and fills any hiring or tech stack signal not supplied. Both bill your Apify account at their own Store prices. If a lookup fails, the row is marked degraded and names the missing signals. | |
| funding_stage | No | Funding stage (e.g. seed, series_a, series_b, growth). Used to infer recently_funded. | |
| headcount_max | No | Maximum headcount for the headcount_in_range signal. | |
| headcount_min | No | Minimum headcount for the headcount_in_range signal. | |
| company_domain | Yes | The primary domain of the company to score, e.g. clay.com | |
| gtm_role_count | No | Number of open GTM/sales roles. Scores via the gtm_role_count_strong signal when at or above min_gtm_roles (default 2). Accepts a numeric string (e.g. "8"). Sent as a string for Clay compatibility and coerced to integer at runtime. | |
| industry_match | No | Override: whether the company's industry matches your target list. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| previous_score | No | Previous ICP score for this company. If provided, output includes score_change and score_trend fields. | |
| scoring_config | No | JSON object of scoring weights. | |
| icp_description | No | Plain-English ICP description. Requires llm_api_key. | |
| recently_funded | No | Override: whether the company was recently funded (within funded_within_days, default 540). | |
| tier_thresholds | No | Optional. Minimum score for each tier as { "tier_a": number, "tier_b": number, "tier_c": number }. Scores at or above tier_a are A, tier_b are B, tier_c are C, else D. Defaults to 80 / 60 / 40. | |
| total_followers | No | Total social followers across platforms, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h). Scores via strong_social_following when at or above min_total_followers (default 1000). Accepts a numeric string. | |
| uses_salesforce | No | Whether the company uses Salesforce. Accepts a boolean-like string ("true"/"false"). Sent as a string for Clay compatibility and coerced to boolean at runtime. | |
| revenue_estimate | No | Estimated annual revenue in dollars from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g). Scores via revenue_in_range. Accepts a numeric string (e.g. "50000000"). Coerced to integer at runtime. | |
| gtm_hiring_signal | No | Whether the company is actively hiring for GTM/sales roles. Accepts a boolean-like string ("true"/"false"). Sent as a string for Clay compatibility and coerced to boolean at runtime. | |
| last_funding_date | No | ISO date of last funding round (legacy field; latest_funding_date is preferred). Used to auto-detect recently_funded if the boolean is not set. | |
| seq_tool_detected | No | Whether a sales sequencing tool (Outreach, SalesLoft, Apollo, Lemlist) was detected. Accepts a boolean-like string ("true"/"false") or any non-empty tool name (e.g. "Outreach"). Sent as a string for Clay compatibility and coerced to boolean at runtime. | |
| target_industries | No | Comma-separated list of target industries for the industry_match signal. | |
| funded_within_days | No | Optional. How recent a funding round must be to count for the recently_funded signal, in days. Defaults to 540 (18 months). | |
| headcount_in_range | No | Override: whether headcount is in your target range. | |
| include_explanation | No | If true, adds a score_explanation string to the output. | |
| keyword_match_count | No | Number of target-keyword matches found, from the Job Board Keyword Signal Scanner (Actor ID 4DvqpvhMR74NLcDDY). Scores via keyword_signal_match when at or above min_keyword_matches (default 1). Accepts a numeric string. | |
| latest_funding_date | No | ISO date of the latest funding round (from C1 Funding & Press Signal Scanner when it ships). Drives recently_funded against funded_within_days. | |
| min_score_to_output | No | If set, rows scoring below this threshold are skipped from output (not pushed to dataset). Skipped rows are logged only. | |
| latest_funding_amount | No | Dollar amount of the latest funding round (from C1 when it ships). Scores via well_funded when at or above min_funding_amount (default 1000000). Accepts a numeric string (e.g. "50000000"). | |
| social_platforms_found | No | Number of official social platforms found, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h). Scores via social_presence when at or above min_social_platforms (default 2). Accepts a numeric string. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (destructiveHint=false, idempotentHint=true, openWorldHint=true), so the bar is lower, and the description still adds real behavioral context: it requires an APIFY_TOKEN and consumes Apify credits per call, which matters for an agent deciding to invoke it. It also declares 'reads public data and writes nothing', which sits in mild tension with readOnlyHint=false (the schema's fetch_signals spawns billable sub-actors), but this reads as credit/spend semantics rather than a genuine contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, all front-loaded: purpose and outputs first, then ICP configuration, then operational requirements. Every sentence carries information the agent needs and none repeats the title or name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 44 parameters, no output schema, and nested objects, the description does well to state the return shape inline and to disclose cost and auth requirements. It omits the degraded-row / fetch_signals behavior, but that is documented in the schema, so the omission is acceptable rather than a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 and the schema already explains every one of the 44 parameters in detail. The description adds only the cross-parameter dependency that icp_description needs llm_api_key; it does not summarize the signal-override inputs or the thresholds. Adequate but not additive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Score a company against your ideal customer profile') and immediately enumerates the concrete outputs (0-100 icp_score, A-D icp_tier, per-signal breakdown). It is clearly distinguishable from sibling enrichment tools like enrich_company_firmographics or aggregate_gtm_signals, which gather signals rather than score them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives useful guidance on the three ways to define an ICP (template, scoring_config, icp_description) and notes that icp_description requires llm_api_key. However, it never states when to prefer this tool over the sibling signal-gathering tools, nor what prerequisites (e.g. already-enriched firmographics) are expected. Usage is implied rather than routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
track_publication_cadenceTrack Publication CadenceAIdempotent
Given a company domain, measure how much long-form work that company publishes and whether the rate is rising or falling. Returns post counts for the last 30 days, 90 days and 12 months, a monthly average, and a cadence_trend of accelerating, steady, declining, dormant or unknown, with the percent change behind it. The trend compares the last 90 days against the prior 275 days, both normalized to posts per month. Also returns the blog URL, the format mix (blog posts, guides, reports, case studies, whitepapers, podcasts, videos, press releases, research), the number of distinct bylines, and how the post list was discovered. This measures EDITORIAL output volume, not product changelogs: a release feed is detected and rejected rather than counted. Publication dates are read from the post pages, because sitemap lastmod was measured to be a modification date running later than publication by a median of 151 to 1653 days. When a site's date field tracks edits rather than publication, date_source_reliable comes back false and every count is nulled rather than reported wrong, so read that field before quoting a number. Counts are a census when the archive fits the page budget and a scaled even sample otherwise, flagged by counts_are_estimate. Public sitemaps, feeds and pages only. Returns flat, Clay-ready JSON. Reads public data and writes nothing; requires an APIFY_TOKEN and consumes Apify credits per domain analyzed.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | Company domain to analyze, without https or www, e.g. zapier.com. | |
| domains | No | Batch mode: several company domains analyzed in one call. Takes precedence over domain. | |
| skipCache | No | Force a fresh crawl and ignore the 3 day result cache. | |
| max_charge_usd | No | Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account. | |
| page_concurrency | No | How many pages are fetched concurrently within one domain. | |
| max_pages_to_date | No | How many post pages to fetch per domain for dating. Default 400. Above this cap the counts are estimated from an even sample and counts_are_estimate is set true. | |
| request_timeout_ms | No | Per-HTTP-request timeout in milliseconds. | |
| max_sitemap_fetches | No | Cap on how many sitemap files are fetched per domain. Lower it to bound run time on deeply nested sitemap indexes. | |
| domain_time_budget_ms | No | Hard wall-clock ceiling per domain, default 75000. When nearly spent the crawl stops and the row is returned with partial_result true rather than timing out. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With sparse annotations (readOnlyHint=false, idempotentHint=true, openWorldHint=true), the description carries the disclosure burden well: credit consumption, auth requirement, 3-day cache, sample-vs-census estimation, nulling instead of reporting unreliable dates, partial_result on timeout, and public-data-only sourcing. The 'writes nothing' claim sits slightly oddly against readOnlyHint=false, but false is a non-claim rather than an assertion of writes, so this is a clarifying detail rather than a contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly 250 words, but front-loaded with the purpose and trend definition before the caveats. Almost every sentence carries a distinct fact (date_source_reliable, counts_are_estimate, credit cost), though the density is high enough that a couple of clauses could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must carry return values, and it does: the 30/90/12-month counts, monthly average, the cadence_trend enum values, the trend normalization window, format mix, byline count, and discovery method. Nothing an agent needs to call or interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further: it explains the page-budget/sampling tradeoff behind max_pages_to_date (counts_are_estimate), the per-domain wall clock that yields partial_result, the cost cap semantics, and cache bypass. Several parameters gain operational meaning beyond their schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'measure how much long-form work that company publishes and whether the rate is rising or falling.' It explicitly bounds the scope ('EDITORIAL output volume, not product changelogs') and describes the exact outputs, so an agent can distinguish it from any sibling like capture_linkedin_posts_and_commenters without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context: it rejects release feeds, requires an APIFY_TOKEN, consumes Apify credits per domain, reads only public sitemaps/feeds/pages, and instructs the agent to check date_source_reliable before quoting counts. It does not name a sibling alternative or state an explicit when-not-to-use condition, so it lands just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
21 tool updates
v1.14.0- Changed
aggregate_gtm_signals1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
audit_agent_accessibility1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
capture_linkedin_posts_and_commenters1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
classify_contact1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
detect_ai_tooling1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
detect_gtm_tech_stack1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
enrich_company_firmographics1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
fingerprint_outbound_infrastructure1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
get_company_changes2 fields changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +} - changed
Input schema / properties / sub_actor_timeout_secs / descriptionPrevious value: -"Per-child run timeout in seconds. Children run in parallel, so total wall time is about the slowest child. Default: 90."New value: +"Per-child run timeout in seconds. Children run in parallel, so total wall time is about the slowest child. Default: 300."
- Changed
get_funding_press_signals1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
map_company_event_presence1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
map_company_social_presence1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
monitor_public_awards1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
push_leads_to_sequencer1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
resolve_company_identity1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
resolve_legal_entity4 fields changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +} - added
Input schema / properties / sec_requester_emailAdded value: +{ + "description": "Required. Your own working email address. Sent to the SEC with your name in the User-Agent of each EDGAR request, in the form the SEC asks for. Nothing else uses it.", + "format": "email", + "type": "string" +} - added
Input schema / properties / sec_requester_nameAdded value: +{ + "description": "Required. Your own name or your company's name. The SEC requires every automated request to EDGAR to identify the requester by name and email, and the actor sends yours, never a default.", + "maxLength": 100, + "minLength": 1, + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "domain" -]New value: +[ + "sec_requester_name", + "sec_requester_email", + "domain" +]
- Changed
resolve_linkedin_url1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
scan_gtm_hiring_signals1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
scan_job_board_keywords1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
score_icp_fit1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
- Changed
track_publication_cadence1 field changed- added
Input schema / properties / max_charge_usdAdded value: +{ + "description": "Optional spending cap for this call, in USD, passed to the actor as max_charge_usd. The run stops before any charge that would take it past this amount and keeps every row already charged. Leave empty to rely only on the maximum charge per run set on your Apify account.", + "minimum": 0, + "type": "number" +}
18 tool updates
v1.1.1- Changed
aggregate_gtm_signals1 field changed- added
Input schema / properties / sourcesAdded value: +{ + "description": "Which signals to aggregate. Defaults to hiring and tech_stack. Each extra source adds one sub actor run to the bill and one dimension to the composite score, which is normalized over the sources selected.", + "items": { + "enum": [ + "hiring", + "tech_stack", + "funding", + "events", + "workplace" + ], + "type": "string" + }, + "type": "array" +}
- Added
audit_agent_accessibility - Added
capture_linkedin_posts_and_commenters - Added
classify_contact - Added
detect_ai_tooling - Changed
detect_gtm_tech_stack6 fields changed- added
Input schema / properties / company_domainAdded value: +{ + "description": "Deprecated alias for domain, accepted by the actor for older callers. Prefer domain.", + "type": "string" +} - changed
Input schema / properties / domain / descriptionPrevious value: -"Bare company domain, e.g. stripe.com"New value: +"Bare company domain, e.g. stripe.com. Supply this, company_domain or url." - added
Input schema / properties / skipCacheAdded value: +{ + "description": "By default a clean detection is cached for 7 days and reused. Set true to force a fresh detection.", + "type": "boolean" +} - added
Input schema / properties / technologiesAdded value: +{ + "description": "Report only these tools. Omit to report every detectable tool. Only tools with a client side fingerprint are selectable. Detection is unchanged, so filtering costs nothing extra.", + "items": { + "enum": [ + "hubspot", + "salesforce", + "marketo", + "pardot", + "intercom", + "drift", + "apollo", + "outreach", + "gong", + "zoominfo" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / urlAdded value: +{ + "description": "Deprecated alias for domain, accepted by the actor as a full company website URL. Prefer domain.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "domain" -]
- Added
fingerprint_outbound_infrastructure - Changed
get_company_changes4 fields changed- added
Input schema / properties / min_severityAdded value: +{ + "description": "Report only changes at or above this severity. low reports every change and is the default. high keeps leadership moves, funding, acquisitions, and a CRM or sequencer appearing or disappearing.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" +} - added
Input schema / properties / previous_snapshotAdded value: +{ + "additionalProperties": {}, + "description": "Snapshot object returned by a prior run. Supply it and it is the baseline instead of stored state, which is what makes a scheduled run cheap.", + "type": "object" +} - added
Input schema / properties / sourcesAdded value: +{ + "description": "Which sources to monitor. Omit for all five. Each source left out is one fewer sub actor run per company, so a single source watch is billed for one source, not five.", + "items": { + "enum": [ + "hiring", + "tech_stack", + "firmographic", + "funding", + "social" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / sub_actor_timeout_secsAdded value: +{ + "description": "Per-child run timeout in seconds. Children run in parallel, so total wall time is about the slowest child. Default: 90.", + "type": "integer" +}
- Changed
get_funding_press_signals2 fields changed- added
Input schema / properties / lookback_daysAdded value: +{ + "description": "How far back to search, in days. Default 365.", + "maximum": 1825, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / signal_typesAdded value: +{ + "description": "Report only these event types. Omit for every type. Narrowing also narrows the search: a funding only run issues one news query instead of four.", + "items": { + "enum": [ + "funding_round", + "ipo", + "acquisition", + "exec_move", + "product_launch", + "partnership" + ], + "type": "string" + }, + "type": "array" +}
- Added
map_company_event_presence - Added
monitor_public_awards - Added
push_leads_to_sequencer - Changed
resolve_company_identity1 field changed- added
Input schema / properties / minLinkedinConfidenceAdded value: +{ + "description": "A LinkedIn page the actor finds is returned only when its linkedin_confidence is at least this value, 0 to 100. Default \"70\". A LinkedIn URL you provide is always returned as given. Sent as a string for Clay compatibility.", + "pattern": "^\\s*(100|[1-9]?[0-9])?\\s*$", + "type": "string" +}
- Added
resolve_legal_entity - Changed
resolve_linkedin_url3 fields changed- added
Input schema / properties / includeFirmographicsAdded value: +{ + "description": "When \"true\", also reads employee count, industry, HQ, follower count and description from search result snippets about the LinkedIn company page. No request is sent to LinkedIn. Fields no snippet states stay null. Off by default because it can add a search. Sent as a string for Clay compatibility.", + "enum": [ + "false", + "true" + ], + "type": "string" +} - added
Input schema / properties / minConfidenceScoreAdded value: +{ + "description": "A LinkedIn page is returned only when its match score is at least this value, 0 to 100. Default \"70\". Raise it for fewer, surer answers; lower it for more answers and more wrong ones. Sent as a string for Clay compatibility.", + "pattern": "^\\s*(100|[1-9]?[0-9])?\\s*$", + "type": "string" +} - added
Input schema / properties / skipCacheAdded value: +{ + "description": "When \"false\", the default, a successful resolution is cached for 7 days and reused. Set \"true\" to force a fresh resolution. Sent as a string for Clay compatibility.", + "enum": [ + "false", + "true" + ], + "type": "string" +}
- Changed
scan_gtm_hiring_signals4 fields changed- added
Input schema / properties / include_role_detailsAdded value: +{ + "description": "When true, include the full per-role detail array (title, department, location, url). Default: false.", + "type": "boolean" +} - added
Input schema / properties / modeAdded value: +{ + "description": "Processing mode. \"single\" scores the domain. \"velocity\" compares this run against previous_gtm_role_count and previous_run_date. \"batch\" is an actor-level mode this single-call tool supplies no list for. Default: \"single\".", + "enum": [ + "single", + "batch", + "velocity" + ], + "type": "string" +} - added
Input schema / properties / previous_gtm_role_countAdded value: +{ + "description": "GTM role count from the previous run for this domain, used in velocity mode to compute the delta.", + "type": "integer" +} - added
Input schema / properties / previous_run_dateAdded value: +{ + "description": "ISO date of the previous run for this domain, used in velocity mode to report days between runs.", + "type": "string" +}
- Changed
score_icp_fit35 fields changed- added
Input schema / properties / crm_detectedAdded value: +{ + "description": "Whether any CRM was detected. Accepts a boolean-like string (\"true\"/\"false\") or any non-empty CRM name (e.g. \"Salesforce\"). Sent as a string for Clay compatibility and coerced to boolean at runtime. Auto-derived from uses_hubspot/uses_salesforce if not set.", + "type": "string" +} - added
Input schema / properties / employee_bandAdded value: +{ + "description": "Firmographic employee band from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g), e.g. \"201-500\". Scores via employee_band_match when it is in target_employee_bands.", + "type": "string" +} - changed
Input schema / properties / fetch_signals / descriptionPrevious value: -"If true, the actor fetches hiring and tech-stack signals automatically before scoring."New value: +"If true, the actor runs the GTM Hiring Signal Scraper and the GTM Tech Stack Signal Scraper for this company before scoring and fills any hiring or tech stack signal not supplied. Both bill your Apify account at their own Store prices. If a lookup fails, the row is marked degraded and names the missing signals." - added
Input schema / properties / founded_yearAdded value: +{ + "description": "Year the company was founded, from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g). Carried for reference; not currently scored. Accepts a numeric string (e.g. \"2015\").", + "type": "string" +} - added
Input schema / properties / funded_within_daysAdded value: +{ + "description": "Optional. How recent a funding round must be to count for the recently_funded signal, in days. Defaults to 540 (18 months).", + "type": "integer" +} - added
Input schema / properties / funding_stageAdded value: +{ + "description": "Funding stage (e.g. seed, series_a, series_b, growth). Used to infer recently_funded.", + "type": "string" +} - added
Input schema / properties / gtm_hiring_signalAdded value: +{ + "description": "Whether the company is actively hiring for GTM/sales roles. Accepts a boolean-like string (\"true\"/\"false\"). Sent as a string for Clay compatibility and coerced to boolean at runtime.", + "type": "string" +} - added
Input schema / properties / gtm_role_countAdded value: +{ + "description": "Number of open GTM/sales roles. Scores via the gtm_role_count_strong signal when at or above min_gtm_roles (default 2). Accepts a numeric string (e.g. \"8\"). Sent as a string for Clay compatibility and coerced to integer at runtime.", + "type": "string" +} - added
Input schema / properties / has_linkedinAdded value: +{ + "description": "Whether a company LinkedIn page was found, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h) or the Domain to LinkedIn URL Resolver (Actor ID 3HtnSaqPHOg1Qg5gx). Contributes to social_presence. Accepts a boolean-like string.", + "type": "string" +} - added
Input schema / properties / has_twitterAdded value: +{ + "description": "Whether a company X/Twitter profile was found, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h). Contributes to social_presence. Accepts a boolean-like string.", + "type": "string" +} - added
Input schema / properties / headcountAdded value: +{ + "description": "Current employee headcount. Accepts a numeric string (e.g. \"3000\"). Sent as a string for Clay compatibility and coerced to integer at runtime.", + "type": "string" +} - added
Input schema / properties / headcount_in_rangeAdded value: +{ + "description": "Override: whether headcount is in your target range.", + "type": "boolean" +} - added
Input schema / properties / headcount_maxAdded value: +{ + "description": "Maximum headcount for the headcount_in_range signal.", + "type": "integer" +} - added
Input schema / properties / headcount_minAdded value: +{ + "description": "Minimum headcount for the headcount_in_range signal.", + "type": "integer" +} - added
Input schema / properties / hq_locationAdded value: +{ + "description": "Headquarters location from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g). Carried for reference; not currently scored.", + "type": "string" +} - added
Input schema / properties / industryAdded value: +{ + "description": "The company's industry (from the Company Firmographic Enricher, Actor ID YlUtLWjfPpqykmB8g).", + "type": "string" +} - added
Input schema / properties / industry_matchAdded value: +{ + "description": "Override: whether the company's industry matches your target list.", + "type": "boolean" +} - added
Input schema / properties / job_countAdded value: +{ + "description": "Number of open jobs found, from the Job Board Keyword Signal Scanner (Actor ID 4DvqpvhMR74NLcDDY). Scores via active_hiring_volume when at or above min_job_count (default 3). Accepts a numeric string.", + "type": "string" +} - added
Input schema / properties / keyword_match_countAdded value: +{ + "description": "Number of target-keyword matches found, from the Job Board Keyword Signal Scanner (Actor ID 4DvqpvhMR74NLcDDY). Scores via keyword_signal_match when at or above min_keyword_matches (default 1). Accepts a numeric string.", + "type": "string" +} - added
Input schema / properties / last_funding_dateAdded value: +{ + "description": "ISO date of last funding round (legacy field; latest_funding_date is preferred). Used to auto-detect recently_funded if the boolean is not set.", + "type": "string" +} - added
Input schema / properties / latest_funding_amountAdded value: +{ + "description": "Dollar amount of the latest funding round (from C1 when it ships). Scores via well_funded when at or above min_funding_amount (default 1000000). Accepts a numeric string (e.g. \"50000000\").", + "type": "string" +} - added
Input schema / properties / latest_funding_dateAdded value: +{ + "description": "ISO date of the latest funding round (from C1 Funding & Press Signal Scanner when it ships). Drives recently_funded against funded_within_days.", + "type": "string" +} - added
Input schema / properties / min_score_to_outputAdded value: +{ + "description": "If set, rows scoring below this threshold are skipped from output (not pushed to dataset). Skipped rows are logged only.", + "type": "integer" +} - added
Input schema / properties / previous_scoreAdded value: +{ + "description": "Previous ICP score for this company. If provided, output includes score_change and score_trend fields.", + "type": "integer" +} - added
Input schema / properties / recently_fundedAdded value: +{ + "description": "Override: whether the company was recently funded (within funded_within_days, default 540).", + "type": "boolean" +} - added
Input schema / properties / revenue_estimateAdded value: +{ + "description": "Estimated annual revenue in dollars from the Company Firmographic Enricher (Actor ID YlUtLWjfPpqykmB8g). Scores via revenue_in_range. Accepts a numeric string (e.g. \"50000000\"). Coerced to integer at runtime.", + "type": "string" +} - added
Input schema / properties / seq_tool_detectedAdded value: +{ + "description": "Whether a sales sequencing tool (Outreach, SalesLoft, Apollo, Lemlist) was detected. Accepts a boolean-like string (\"true\"/\"false\") or any non-empty tool name (e.g. \"Outreach\"). Sent as a string for Clay compatibility and coerced to boolean at runtime.", + "type": "string" +} - added
Input schema / properties / social_platforms_foundAdded value: +{ + "description": "Number of official social platforms found, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h). Scores via social_presence when at or above min_social_platforms (default 2). Accepts a numeric string.", + "type": "string" +} - added
Input schema / properties / target_industriesAdded value: +{ + "description": "Comma-separated list of target industries for the industry_match signal.", + "type": "string" +} - added
Input schema / properties / tech_stackAdded value: +{ + "description": "Comma-separated list of technologies. Used to auto-detect CRM/sequencing tools if booleans are not set.", + "type": "string" +} - added
Input schema / properties / tier_thresholdsAdded value: +{ + "additionalProperties": {}, + "description": "Optional. Minimum score for each tier as { \"tier_a\": number, \"tier_b\": number, \"tier_c\": number }. Scores at or above tier_a are A, tier_b are B, tier_c are C, else D. Defaults to 80 / 60 / 40.", + "type": "object" +} - added
Input schema / properties / total_followersAdded value: +{ + "description": "Total social followers across platforms, from the Company Social Presence Mapper (Actor ID 4k6CCemkgBDz18m2h). Scores via strong_social_following when at or above min_total_followers (default 1000). Accepts a numeric string.", + "type": "string" +} - added
Input schema / properties / uses_clayAdded value: +{ + "description": "Whether the company uses Clay. Accepts a boolean-like string (\"true\"/\"false\"). Sent as a string for Clay compatibility and coerced to boolean at runtime.", + "type": "string" +} - added
Input schema / properties / uses_hubspotAdded value: +{ + "description": "Whether the company uses HubSpot. Accepts a boolean-like string (\"true\"/\"false\"). Sent as a string for Clay compatibility and coerced to boolean at runtime.", + "type": "string" +} - added
Input schema / properties / uses_salesforceAdded value: +{ + "description": "Whether the company uses Salesforce. Accepts a boolean-like string (\"true\"/\"false\"). Sent as a string for Clay compatibility and coerced to boolean at runtime.", + "type": "string" +}
- Added
track_publication_cadence
5 tool updates
v1.1.0- Added
enrich_company_firmographics - Added
get_company_changes - Added
get_funding_press_signals - Added
map_company_social_presence - Added
resolve_company_identity
6 tool updates
v1.0.3- First observed
aggregate_gtm_signals - First observed
detect_gtm_tech_stack - First observed
resolve_linkedin_url - First observed
scan_gtm_hiring_signals - First observed
scan_job_board_keywords - First observed
score_icp_fit
TDQS
Scored across 21 tools
Most tools target clearly distinct resources (hiring, tech stack, funding, social, events, awards, legal entity, AI, outbound, publications), and descriptions explicitly cross-reference sibling tools to steer selection (e.g. scan_job_board_keywords vs scan_gtm_hiring_signals). The main overlap is compositional: aggregate_gtm_signals and get_company_changes both re-invoke the primitive scan/detect tools, so an agent must decide composite vs primitive despite the explanations.
Every tool follows a strict snake_case verb_noun convention (scan_*, resolve_*, detect_*, map_*, get_*, audit_*, classify_*, monitor_*, capture_*). No camelCase or mixed styles, and the verb choice is predictable across the whole suite.
At 21 tools the suite is on the heavier side, but each tool maps to a genuinely distinct enrichment or action (identity, firmographics, funding, AI maturity, outbound infra, publication cadence, awards, etc.), so nothing is redundant filler. It is slightly over the ideal range for a single server rather than bloated with duplicates.
The GTM enrichment surface is broad, covering firmographics, hiring, tech stack, funding, social, events, awards, legal entity, ICP scoring, and sequencer push. The notable gap is people/contact discovery: classify_contact explicitly does not find people, and there is no email or contact-finder tool, which a full GTM workflow would need (presumably supplied externally via Clay).
Maintenance
Related MCP Connectors
- LayrcakeOAuthdev.layrcake
Go-to-market infrastructure for AI agents: find leads, verify emails, read signals, run campaigns.
B2B lead generation, email verification, company enrichment, and agentic GTM Ops.
Live LinkedIn people, company, post and job data, ICP search and job-change signals for AI agents.
Signal-based B2B prospecting: find leads with buying intent, run email and LinkedIn outreach.
Related MCP Servers
- AlicenseAqualityAmaintenanceDetects hiring intent signals by scanning job boards for specific companies. Returns structured role data for outbound sales targeting.1250 npm1MIT
- AlicenseAqualityAmaintenanceScores companies against a configurable Ideal Customer Profile using firmographic and signal data. Returns a weighted fit score with per-criterion breakdowns.2255 npm3MIT
- AlicenseAqualityAmaintenanceEnables auditing any domain's email deliverability and DNS health, including SPF, DKIM, DMARC, MX, mail provider, DNS blacklist status, catch-all, domain age, and a deliverability score.1121 npm1MIT
- AlicenseAqualityAmaintenanceEnables enriching company domains into structured firmographics including employee band, industry, HQ, founded year, revenue estimate, logo, and description, with source provenance and data completeness scoring.1226 npm1MIT