{
  "openapi": "3.0.1",
  "info": {
    "title": "Prospect Engine: B2B Company and Contact Enrichment",
    "description": "Turn a domain or a hiring keyword into enriched company records and verified contacts. Resolves the real employer behind a job posting, scores ICP fit, and returns one flat Clay-ready row per entity with per-field provenance. Bring your own vendor keys.",
    "version": "0.0",
    "x-build-id": "HlKONPCbpPXtvJqpP"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mambalabs~b2b-prospect-engine/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mambalabs-b2b-prospect-engine",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/mambalabs~b2b-prospect-engine/runs": {
      "post": {
        "operationId": "runs-sync-mambalabs-b2b-prospect-engine",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/mambalabs~b2b-prospect-engine/run-sync": {
      "post": {
        "operationId": "run-sync-mambalabs-b2b-prospect-engine",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "enrich_companies",
              "discover_jobs",
              "find_contacts",
              "full"
            ],
            "type": "string",
            "description": "What to run. enrich_companies resolves identity, firmographics, LinkedIn and social for each company. discover_jobs finds who is hiring for your keywords and resolves the real employer from the job description. find_contacts finds people at each company. full chains all three.",
            "default": "enrich_companies"
          },
          "domains": {
            "title": "Company domains",
            "type": "array",
            "description": "One domain per line. Used by enrich_companies and find_contacts.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "company_names": {
            "title": "Company names",
            "type": "array",
            "description": "One name per line. Used when you have a name but no domain.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "title": "Job keywords",
            "type": "array",
            "description": "Roles to search for. Used by discover_jobs and full. Example: copy editor, proofreader, content editor.",
            "default": [
              "copy editor",
              "proofreader",
              "content editor"
            ],
            "items": {
              "type": "string"
            }
          },
          "country": {
            "title": "Country",
            "type": "string",
            "description": "Two letter country code for job search, for example us or gb.",
            "default": "us"
          },
          "location": {
            "title": "Location",
            "type": "string",
            "description": "Optional location filter for job search, for example New York."
          },
          "lookback_days": {
            "title": "Lookback days",
            "type": "string",
            "description": "Drop postings older than this many days. Sent as a string because Clay sends every field as a string.",
            "default": "30"
          },
          "max_results": {
            "title": "Max results",
            "type": "string",
            "description": "Cap on postings returned per run. Keeps a broad keyword set from running away.",
            "default": "25"
          },
          "max_pages": {
            "title": "Max search pages per keyword",
            "type": "string",
            "description": "1 to 5. Each page is one SerpAPI call, so this is the main cost dial on discovery.",
            "default": "1"
          },
          "new_postings_only": {
            "title": "New postings only",
            "type": "string",
            "description": "true to return only postings not seen in a previous run.",
            "default": "false"
          },
          "previous_run_date": {
            "title": "Previous run date",
            "type": "string",
            "description": "YYYY-MM-DD watermark for delta detection when the cross-run cache is unavailable."
          },
          "remote_only": {
            "title": "Remote roles only",
            "type": "string",
            "description": "true to keep only postings flagged remote by the board.",
            "default": "false"
          },
          "company_size_min": {
            "title": "Minimum employee count",
            "type": "string",
            "description": "Drop companies below this headcount. Only takes effect once headcount is known, so it applies in full mode and to any discovery row that carried an employee count. Discovery alone does not enrich."
          },
          "company_size_max": {
            "title": "Maximum employee count",
            "type": "string",
            "description": "Drop companies above this headcount. Same condition as the minimum."
          },
          "exclude_staffing": {
            "title": "Exclude staffing agencies",
            "type": "string",
            "description": "true to drop postings from staffing and recruitment agencies.",
            "default": "true"
          },
          "exclude_marketplaces": {
            "title": "Exclude freelance marketplaces",
            "type": "string",
            "description": "true to drop Upwork, Fiverr, Freelancer and similar gig listings.",
            "default": "true"
          },
          "extra_marketplaces": {
            "title": "Extra marketplaces to exclude",
            "type": "array",
            "description": "Additional marketplace names to filter out.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "fetch_posting_page": {
            "title": "Fetch the posting page",
            "type": "string",
            "description": "true to open the job posting when the description alone does not identify the employer. Slower, and it is what catches a job board posting on an employer's behalf.",
            "default": "true"
          },
          "target_contacts": {
            "title": "Contacts per company",
            "type": "string",
            "description": "1 to 25.",
            "default": "3"
          },
          "target_roles": {
            "title": "Target roles",
            "type": "array",
            "description": "Only enrich contacts whose title plausibly matches one of these roles. Filters AFTER discovery and BEFORE any paid email lookup, so a non-matching contact costs nothing. Leave empty to keep every contact the seniority and department filters allow.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "deny_tokens": {
            "title": "Deny tokens",
            "type": "array",
            "description": "Words that disqualify a contact even when the title matched a target role. Matched on whole words, not substrings, so a deny token of 'product' refuses 'Product Owner' and keeps 'Production Editor'. Applies even when no target roles are set.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "company_concurrency": {
            "title": "Companies in parallel",
            "type": "string",
            "description": "How many companies to work at once. Concurrency is nested, so simultaneous provider calls are this times contact_concurrency. The default 6 x 3 = 18 sits under the tightest documented provider ceiling (Findymail, 30 concurrent). Raise only if your provider plan is above the default tier.",
            "default": "6"
          },
          "contact_concurrency": {
            "title": "Contacts in parallel per company",
            "type": "string",
            "description": "How many contacts to enrich at once within one company. The email waterfall itself is never parallelized: layers run in order and stop at the first hit, which is what keeps the paid fallbacks off the primary's successes.",
            "default": "3"
          },
          "max_spend_usd": {
            "title": "Run spend cap, USD",
            "type": "string",
            "description": "Stop making paid provider calls once this much of YOUR vendor spend is committed, and emit everything completed up to that point. This caps your own vendor bills (Findymail, Icypeas, Prospeo, BounceBan), not the Apify charge for this actor. Leave empty for no cap."
          },
          "job_titles": {
            "title": "Target job titles",
            "type": "array",
            "description": "Titles to search for when finding contacts.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "seniority": {
            "title": "Seniority filter",
            "type": "array",
            "description": "c_level, vp, director, manager, senior.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "departments": {
            "title": "Department filter",
            "type": "array",
            "description": "marketing, sales, engineering, product, finance, hr, operations, legal.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "include_email": {
            "title": "Find emails",
            "type": "string",
            "description": "true to run the email waterfall. Needs an Icypeas or Prospeo key, which you supply and are billed for directly.",
            "default": "false"
          },
          "verify_email": {
            "title": "Verify emails",
            "type": "string",
            "description": "true to verify each address. Needs a BounceBan key.",
            "default": "true"
          },
          "verify_position": {
            "title": "Verify each contact still holds the role",
            "type": "string",
            "description": "Ask a model whether the title on record is consistent and plausibly current, using only the supplied evidence. Contacts found on the company's own website are skipped, because a team page read today is current by construction. An included step of the per-contact enrichment charge: turning it off saves your own model tokens, it does not change what this actor bills.",
            "default": "true"
          },
          "personalize": {
            "title": "Write a personalized opener",
            "type": "string",
            "description": "One or two sentences referencing something specific about the company, for use as the opening line of a cold email. Runs only for contacts that have an address. An included step of the per-contact enrichment charge.",
            "default": "true"
          },
          "brand_voice": {
            "title": "Brand voice",
            "type": "string",
            "description": "How the opener should sound. Leave empty and it writes plainly and directly."
          },
          "score_icp": {
            "title": "Score ICP fit",
            "type": "string",
            "description": "true to score every row against the ICP rules and tier it A to D.",
            "default": "true"
          },
          "icp_preset": {
            "title": "ICP scoring preset",
            "enum": [
              "editorial_services",
              "generic_b2b"
            ],
            "type": "string",
            "description": "Which scoring model to apply. \"editorial_services\" scores for a seller of managed copy editing and proofreading. \"generic_b2b\" scores on hiring intent, employer resolvability and headcount with no service-specific vocabulary.",
            "default": "editorial_services"
          },
          "min_icp_score": {
            "title": "Minimum ICP score",
            "type": "string",
            "description": "In full mode, only companies scoring at or above this go on to contact discovery. Default 45: at 25 the filter passed every keyword-discovered editorial posting, because 25 is the floor such a posting can score.",
            "default": "45"
          },
          "extra_exclude_names": {
            "title": "Extra excluded company names",
            "type": "array",
            "description": "Any company whose name contains one of these is excluded.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "signal_taxonomy": {
            "title": "Custom signal taxonomy",
            "type": "array",
            "description": "Override the default signal types. Each entry is an object with type, strength, title_keywords, and optional also_keywords and description_keywords."
          },
          "include_social": {
            "title": "Find social profiles",
            "type": "string",
            "description": "true to resolve Facebook, Instagram, X and YouTube alongside LinkedIn.",
            "default": "true"
          },
          "source_timeout_secs": {
            "title": "Per source timeout",
            "type": "string",
            "description": "5 to 120. A source that exceeds this is marked degraded and the run continues.",
            "default": "30"
          },
          "skip_cache": {
            "title": "Skip the cache",
            "type": "string",
            "description": "true to ignore the 7 day cross-run cache and recompute everything.",
            "default": "false"
          },
          "serper_api_key": {
            "title": "Serper Api Key",
            "type": "string",
            "description": "Your Serper.dev key. REQUIRED IN PRACTICE for find_contacts: without it the actor falls back to a free DuckDuckGo search that Apify's IP ranges are reliably served an anti-bot challenge on, so a run with no key and no reachable /team page returns a notice row and no contacts. Measured on four domains on 2026-08-12. enrich_companies and discover_jobs do not need it."
          },
          "findymail_api_key": {
            "title": "Findymail Api Key",
            "type": "string",
            "description": "Your Findymail key. First provider in the email waterfall."
          },
          "icypeas_api_key": {
            "title": "Icypeas Api Key",
            "type": "string",
            "description": "Your Icypeas key. Runs on Findymail misses."
          },
          "prospeo_api_key": {
            "title": "Prospeo Api Key",
            "type": "string",
            "description": "Your Prospeo key. Runs on the residual after Findymail and Icypeas."
          },
          "bounceban_api_key": {
            "title": "Bounceban Api Key",
            "type": "string",
            "description": "Your BounceBan key. Second verifier, used for the catch-all case."
          },
          "serpapi_key": {
            "title": "Serpapi Key",
            "type": "string",
            "description": "Your SerpApi key. Required by discover_jobs and full. Distinct from a Serper key: different vendor."
          },
          "source_tag": {
            "title": "Source Tag",
            "type": "string",
            "description": "Internal attribution tag set by Mamba Labs on published task examples. Not required, and nothing depends on it. Leave it empty."
          },
          "claude_api_key": {
            "title": "Anthropic API key",
            "type": "string",
            "description": "Your own Anthropic key, used for position verification and personalization. Both steps are skipped when it is absent. Never stored."
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}