{
  "openapi": "3.0.1",
  "info": {
    "title": "Creator Leads Scraper: YouTube TikTok Creator Emails, Instagram",
    "description": "Influencer email finder for creator outreach. Keywords make it a YouTube influencer finder and YouTuber email finder for YouTube creator emails; handles add TikTok leads and Instagram influencer emails, all in one run. YouTube email finder tool: followers, lead score, best public email, MX-checked.",
    "version": "0.1",
    "x-build-id": "DO4hoyGqK2qUQf0sM"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/flash_scraper~creator-leads-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-flash_scraper-creator-leads-scraper",
        "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/flash_scraper~creator-leads-scraper/runs": {
      "post": {
        "operationId": "runs-sync-flash_scraper-creator-leads-scraper",
        "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/flash_scraper~creator-leads-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-flash_scraper-creator-leads-scraper",
        "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": {
          "platforms": {
            "title": "Platforms",
            "type": "array",
            "description": "Which platforms to pull creators from. Only YouTube can discover creators from a keyword; TikTok and Instagram need the handles supplied below. A platform left out of this list is skipped entirely even if its handle list is filled, and the run log names the input it ignored.",
            "items": {
              "type": "string",
              "enum": [
                "tiktok",
                "instagram",
                "youtube"
              ],
              "enumTitles": [
                "TikTok",
                "Instagram",
                "YouTube"
              ]
            },
            "default": [
              "tiktok",
              "instagram",
              "youtube"
            ]
          },
          "searchKeywords": {
            "title": "YouTube search keywords",
            "maxItems": 50,
            "type": "array",
            "description": "YouTube keyword search - the only discovery path in this Actor. One keyword per line. Each keyword returns about 30 unique channels (measured 28, 27 and 36 for three keywords on 2026-08-09); add keywords for volume rather than raising the limit below. Channels that recur across a keyword's result pages, or turn up for several keywords, are fetched first, and every row records which keyword found it (matched_keyword).",
            "default": [
              "home barista"
            ],
            "items": {
              "type": "string"
            }
          },
          "channels": {
            "title": "YouTube channels",
            "maxItems": 300,
            "type": "array",
            "description": "Specific YouTube channels: @handles, bare UC... channel ids or channel URLs, one per line. Scraped in addition to anything the keywords find. A handle that does not exist is reported as not found, never billed.",
            "items": {
              "type": "string"
            }
          },
          "profiles": {
            "title": "TikTok creators (usernames or URLs)",
            "maxItems": 1000,
            "type": "array",
            "description": "TikTok creators: usernames, @handles or profile URLs, one per line. This Actor does not discover on TikTok - logged-out HTTP exposes no /tag/ or search data (browser-based scrapers exist but are slower and pricier) - so this list is the only way in.",
            "items": {
              "type": "string"
            }
          },
          "usernames": {
            "title": "Instagram creators (usernames or URLs)",
            "maxItems": 1000,
            "type": "array",
            "description": "Instagram creators: usernames, @handles or profile URLs, one per line. Instagram cannot be searched by keyword or hashtag without an account either, so this list is the only way in.",
            "items": {
              "type": "string"
            }
          },
          "crossPlatformDiscovery": {
            "title": "Follow Instagram and TikTok links found on YouTube channels",
            "type": "boolean",
            "description": "Scrape the Instagram and TikTok profiles linked from the About page of every YouTube channel found above. Measured on 9 channels discovered on 2026-08-09: 7 published an Instagram link and 3 a TikTok link. Each followed handle becomes an extra billed row, which is why this is off by default.",
            "default": false
          },
          "discoverRelated": {
            "title": "Follow Instagram's related accounts",
            "type": "boolean",
            "description": "Follow Instagram's own related-accounts list (up to ~49 per profile) to find more creators. Instagram-only, and it starts from a handle you already supplied.",
            "default": false
          },
          "maxRelatedPerProfile": {
            "title": "Related accounts per Instagram profile",
            "minimum": 1,
            "maximum": 49,
            "type": "integer",
            "description": "How many related accounts to queue from each Instagram profile when the option above is on.",
            "default": 10
          },
          "maxCreators": {
            "title": "Max creators per run",
            "minimum": 1,
            "maximum": 300,
            "type": "integer",
            "description": "How many creators you want DELIVERED across all platforms - the main cost lever. Cheap filters (followers, verified, private, website) never use up a slot. With onlyWithEmail or minScore set, the run fetches in extra discovery waves whenever the filter removes candidates, until this many leads are delivered - at most 3 extra waves, and never more than 4x this number scraped, so a low email rate cannot run up the bill. The handles you supply yourself are reserved ahead of YouTube keyword discovery.",
            "default": 10
          },
          "onlyNewCreators": {
            "title": "Skip creators already delivered by this watch",
            "type": "boolean",
            "description": "Turn this Actor into a <b>watch</b>: every run skips the creators this watch already delivered (no second bill, and no maxCreators slot used) and delivers up to maxCreators of the rest. One run stops at maxCreators, so later runs keep delivering the rest of a big search, plus creators who turn up in it later; a run that finds only creators this watch already delivered returns zero rows and charges nothing. The first run of each search + filter combination with this on is the baseline (a run with it off remembers nothing). Memory is kept in your own account per platforms + search terms/handles + minFollowers/maxFollowers (+ emailDomains and onlyVerifiedEmail when set), not maxCreators, and forgets a creator it has not delivered or refreshed for 90 days.",
            "default": false
          },
          "maxResults": {
            "title": "YouTube channels per keyword",
            "minimum": 1,
            "maximum": 40,
            "type": "integer",
            "description": "How many YouTube channels to collect per keyword on the run's first search. One YouTube search returns about 30 unique channels (measured 28, 27 and 36 for three keywords on 2026-08-09, combining the plain results page with the channel-filtered one); ask for more and you get what exists, not an error. Add keywords for volume. Three cases go past this value, up to 40 per keyword: each extra wave of a run with onlyWithEmail, onlyVerifiedEmail, minScore or emailDomains set re-searches at 40; a run with pasted TikTok/Instagram handles that comes up short can re-search at 40 in one refill pass; and the keep. The keep: on a run with no pasted TikTok/Instagram handles, crossPlatformDiscovery off, none of onlyWithEmail, onlyVerifiedEmail, minScore or emailDomains set and no proxy URLs of your own, with this value at 20 or more and maxCreators above this value x keywords, each keyword keeps every channel on the result page(s) it already fetched, up to 40, with no extra search request - but only when at least 30 minutes of the run's time budget (what is left of the timeout, less a reserve of up to 90 seconds) are left when YouTube is searched, and the extra channels are fetched last, only while the budget left still covers the website crawl, email check and AI openers of every creator already collected. A run on the default 1-hour timeout starts with about 58 minutes of budget; a timeout of 31 minutes or less never leaves 30. A TikTok or Instagram handle counts as pasted whenever its platform is selected, including the example handle gymshark this form pre-fills in both lists (an API call without those fields has none): clear both lists, or select only YouTube, for a keyword-only run.",
            "default": 20
          },
          "delaySeconds": {
            "title": "Delay between profiles (seconds)",
            "minimum": 0,
            "maximum": 30,
            "type": "integer",
            "description": "Pause between profiles on TikTok and Instagram. Default 0: every attempt already rotates to a fresh proxy session, so a burst from one IP does not happen and a delay only adds run time. YouTube keeps a small fixed spacing of its own. Set it above 0 only if you deliberately want to slow a long list down.",
            "default": 0
          },
          "minFollowers": {
            "title": "Minimum followers",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only creators with at least this many followers (0 = no filter). Applies to every platform - on YouTube this is the subscriber count, which YouTube itself rounds.",
            "default": 0
          },
          "maxFollowers": {
            "title": "Maximum followers",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only creators with at most this many followers (0 = no cap). Use with the minimum to target nano, micro or macro tiers.",
            "default": 0
          },
          "onlyVerified": {
            "title": "Only verified accounts",
            "type": "boolean",
            "description": "Keep only verified accounts. Works on all three platforms - the YouTube badge is read from the channel page, not assumed.",
            "default": false
          },
          "onlyBusiness": {
            "title": "Only business / commerce accounts",
            "type": "boolean",
            "description": "Keeps only accounts flagged as business or commerce. TikTok and Instagram publish that flag; YouTube does not, so YouTube rows are kept unfiltered and the run log says how many.",
            "default": false
          },
          "skipPrivate": {
            "title": "Skip private accounts",
            "type": "boolean",
            "description": "Drop private accounts. Applies to TikTok and Instagram; YouTube channels have no private flag.",
            "default": false
          },
          "onlyWithWebsite": {
            "title": "Only creators with a link",
            "type": "boolean",
            "description": "Drop creators who published no external link. Measured link rates: TikTok 15 of 28 profiles had a bio link; 4 of 9 YouTube channels published a non-social website.",
            "default": false
          },
          "onlyWithEmail": {
            "title": "Only creators with an email",
            "type": "boolean",
            "description": "Drop creators where no email was found in the bio or on the linked site. Expect it to remove most rows - see the measured fill rates in the README before you rely on it.",
            "default": false
          },
          "onlyVerifiedEmail": {
            "title": "Only creators whose email passed verification",
            "type": "boolean",
            "description": "Keep only creators whose best email graded deliverable or risky in the MX check (see the email_status column): drops creators with no email and addresses that are undeliverable (no mail server on the domain, a disposable domain, bad syntax), before billing. An address whose lookup could not complete (email_status = unknown) is kept, so a resolver outage never deletes a good lead - filter the column yourself for the strict set. Judged after the website crawl like onlyWithEmail, so the run keeps discovering in waves until this many leads are delivered.",
            "default": false
          },
          "emailDomains": {
            "title": "Only emails on these domains",
            "type": "array",
            "description": "Keep only creators whose best email OR any extra email ends with one of these domains (case-insensitive), e.g. @gmail.com for personal inboxes that answer cold outreach, or @yourbrand.com. Judged after the website crawl and before billing, like onlyWithEmail, so a matching address found on the linked site counts too. Empty = no filtering.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "minScore": {
            "title": "Minimum lead score",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Keep only leads scoring at or above this value, 0-100 (0 = no filter). The score is normalised per platform, so a YouTube lead is comparable to a TikTok one.",
            "default": 0
          },
          "enrichEmails": {
            "title": "Find emails on the linked website",
            "type": "boolean",
            "description": "Visit each creator's linked site (home, /contact, /about, resolving Linktree-style pages) for emails and social profiles. This is the main email source on all three platforms - no key needed. YouTube's own 'View email address' button is never used (it needs a Google login, a reCAPTCHA and a small daily reveal quota), so a YouTube email comes from the About text, the published links and this website crawl.",
            "default": true
          },
          "writeOpeners": {
            "title": "Write an AI cold-opener per lead",
            "type": "boolean",
            "description": "Generate a personalized one-sentence outreach opener for each lead, aware of which platform the creator is on. Requires your own OpenAI/Anthropic key below.",
            "default": false
          },
          "llmProvider": {
            "title": "AI provider (for openers)",
            "enum": [
              "openai",
              "anthropic"
            ],
            "type": "string",
            "description": "AI provider used to write the cold openers - OpenAI (GPT) or Anthropic (Claude). Use the provider that matches the API key you supply.",
            "default": "openai"
          },
          "llmApiKey": {
            "title": "AI API key (for openers)",
            "type": "string",
            "description": "Your own OpenAI or Anthropic API key. Used once per run to write the openers; never logged and never stored."
          },
          "llmModel": {
            "title": "AI model (optional)",
            "type": "string",
            "description": "Override the default model (gpt-4o-mini for OpenAI, claude-haiku-4-5-20251001 for Anthropic)."
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "For TikTok and Instagram this Actor tries one Apify datacenter exit FIRST on each handle and falls back to this group (RESIDENTIAL by default) on the remaining attempts - every attempt mints a fresh session, so a burned exit IP is never retried. Keep RESIDENTIAL here: it is the group the remaining attempts run on, so a handle the datacenter pool cannot serve is still attempted there (at volume some handles are refused everywhere; a refused handle is never billed). YouTube is fetched DIRECT, with no proxy at all - measured 665s proxied versus 16-21s un-proxied for the same channels and the same rows - so a YouTube-only run spends no proxy traffic and no proxy setting changes its result. YouTube honours proxyUrls only if you supply them yourself.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "socialProxyMode": {
            "title": "TikTok/Instagram proxy strategy",
            "enum": [
              "datacenter_first",
              "residential_only"
            ],
            "type": "string",
            "description": "How TikTok and Instagram pick an exit. 'datacenter_first' (default): TikTok tries one Apify datacenter exit first and falls back to the proxy group above (RESIDENTIAL) on the remaining attempts; Instagram tries three Apify datacenter exits first, then up to three RESIDENTIAL exits. Your per-lead price is the same either way; what you may notice is a few extra seconds on a handle whose datacenter exit is refused before the residential attempt runs. 'residential_only' skips the datacenter rungs and goes straight to the proxy group on every attempt; pick it if you see datacenter exits being refused. Ignored when you supply your own proxyUrls (always honoured), and a run with apifyProxyCountry set is residential-only (the datacenter pool does not serve every country).",
            "default": "datacenter_first"
          },
          "webhookUrl": {
            "title": "Alert webhook URL (Slack, Discord, n8n, Make, Zapier…)",
            "type": "string",
            "description": "Optional. When at least one row is delivered, the run POSTs a digest to this URL: a Slack incoming webhook gets a text message, a Discord webhook gets a message, any other URL (n8n / Make / Zapier catch hook, your own endpoint) gets JSON with the counts, console links and the first 20 rows. Quiet runs send nothing. Pair it with onlyNewCreators on a schedule and this actor becomes an alert service on its own. Delivery is best-effort: a webhook failure is reported in the status message and never fails the run."
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}