{
  "openapi": "3.0.1",
  "info": {
    "title": "Creator Leads Scraper: YouTube & TikTok Creator Email Finder",
    "description": "Influencer email finder for creator outreach. YouTube influencer search by keyword: YouTube creator emails, YouTuber email, YouTube emails. TikTok emails, Instagram emails by handle. TikTok lead scraper, TikTok account scraper. Influencer emails, influencer contacts; influencer database built live.",
    "version": "0.1",
    "x-build-id": "ebKzoxuMIvhcrYoeM"
  },
  "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).",
            "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. Lookup: set maxCreators to at least the total you paste across channels, profiles and usernames (max 300 per run); at the default 10 the run stops at 10 creators and never looks up the rest.",
            "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. Lookup: set maxCreators to at least the total you paste across channels, profiles and usernames (max 300 per run); at the default 10 the run stops at 10 creators and never looks up the rest.",
            "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. Lookup: set maxCreators to at least the total you paste across channels, profiles and usernames (max 300 per run); at the default 10 the run stops at 10 creators and never looks up the rest.",
            "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": "Creators DELIVERED across all platforms - the main cost lever. Pasted channels/profiles/usernames: set this to at least their total (max 300); the default 10 stops at 10 creators and never looks up the rest. Profile filters never use a slot. With onlyWithEmail, onlyVerifiedEmail, minScore or emailDomains, extra waves run until this many are delivered - at most 3 extra waves, never more than 4x this number scraped. 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": "Turns runs into a <b>watch</b>: each run delivers up to maxCreators creators this watch has not delivered yet (already-delivered ones: no bill, no slot), so later runs work through a big search and its newcomers. Nothing new: zero rows, no charge. A run with this off remembers nothing. Memory is per platforms + search terms/handles + follower bounds (+ emailDomains, onlyVerifiedEmail when set), not maxCreators; it forgets a creator not delivered or refreshed for 90 days.",
            "default": false
          },
          "maxResults": {
            "title": "YouTube channels per keyword",
            "minimum": 1,
            "maximum": 40,
            "type": "integer",
            "description": "YouTube channels per keyword on the run's first search. Every later wave or refill re-searches at 40. With no onlyWithEmail, onlyVerifiedEmail, minScore or emailDomains, no profiles/usernames for a selected platform, crossPlatformDiscovery off, no proxyUrls, this at 20+, maxCreators above this x keywords and 30+ min of time budget left at the search (never on a timeout of 31 min or less), each keyword keeps up to 40 from pages already fetched; the extras go last, only while time remains.",
            "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. They are removed before delivery, so only rows that carry an email are billed. 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 (email_status): drops creators with no email and undeliverable addresses (no mail server, disposable domain, bad syntax) before billing. An unknown grade (lookup could not complete) 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 maxCreators 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": "TikTok and Instagram try Apify datacenter exits first (see socialProxyMode) and fall back to this group (RESIDENTIAL by default) on the remaining attempts; every attempt mints a fresh session. Keep RESIDENTIAL here so a handle the datacenter pool cannot serve is still attempted (a handle refused everywhere is never billed). YouTube is fetched DIRECT with no proxy unless you supply your own proxyUrls, so a YouTube-only run spends no proxy traffic.",
            "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, then the proxy group (RESIDENTIAL); Instagram tries three datacenter exits, then up to three RESIDENTIAL exits. The per-lead price is the same either way; a refused datacenter exit adds a few seconds. 'residential_only' skips the datacenter rungs; pick it if datacenter exits are refused. Ignored when you supply your own proxyUrls; a run with apifyProxyCountry set is residential-only.",
            "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 for an alert service. 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}