100 크레딧 무료, 카드 등록 없이지금 시작하기
Logo
Back to blog

틱톡과 유튜브 이메일 찾기 API, include=contacts 한 줄로

·17 min read

프로필 호출에 include=contacts를 붙이면 크리에이터가 공개한 비즈니스 이메일과 출처가 와요. 결과 상태 다섯 가지와 재시도, 크레딧 규칙까지 담았어요.

틱톡과 유튜브 이메일 찾기 API, include=contacts 한 줄로

틱톡 이메일 찾기는 프로필 호출에 include=contacts를 붙이면 돼요. 크리에이터가 비즈니스용으로 공개해 둔 이메일이 author.ext.contacts에 담겨 오고 주소마다 어디서 읽었는지가 함께 와요. 유튜브 채널은 youtube/channel/about에 같은 파라미터를 붙여요. 주소를 추측하거나 만들어 내지 않아요. 크리에이터나 소속사가 인터넷에 올려 둔 주소만 읽어요.

요청과 응답 모양부터 결과 상태 다섯 가지, 재시도, 크레딧, 여러 명을 처리하는 방법까지 차례로 다뤄요. 인스타그램은 인스타그램 이메일 찾기에서 따로 봐요.

틱톡 이메일은 API로 어떻게 찾나요?

핸들을 tiktok/profile에 넘기고 include=contacts를 붙여요. 파라미터가 늘어나는 것 말고는 평소 프로필 호출과 같아요.

bash
curl -G "https://www.socialcrawl.dev/v1/tiktok/profile" \
  --data-urlencode "handle=creator" \
  --data-urlencode "include=contacts" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY"
json
{
  "data": {
    "author": {
      "ext": {
        "contacts": [
          {
            "kind": "email",
            "value": "management@example.com",
            "role": "management",
            "confidence": 0.79,
            "provenance": "published",
            "verification": { "syntax": true, "mx": true, "disposable": false, "role_account": true },
            "sources": [
              { "tier": "bio", "url": "https://www.tiktok.com/@creator", "snippet": "management@example.com ..." }
            ]
          }
        ]
      }
    },
    "contact_lookup": {
      "status": "found",
      "checked_at": "2026-01-01T00:00:00.000Z",
      "recheck_after": "2026-07-01T00:00:00.000Z",
      "tiers_run": ["store", "profile", "website"],
      "pending": null
    }
  }
}

contacts[]의 한 항목이 주소 하나예요. role은 own(크리에이터 본인)과 management(매니저), agency(에이전시) 중 하나예요. confidence는 0에서 1 사이의 순위 점수예요. 출처와 검증 결과를 보고 이 주소가 그 크리에이터의 것일 가능성을 견주는 값이지 정확도를 재서 낸 숫자가 아니에요. 믿기 전에 sources를 읽으세요.

sources[].tier는 주소를 읽은 자리를 알려줘요. 틱톡에서는 프로필 소개글(bio)과 프로필에 걸어 둔 웹사이트(website)가 나와요. contact_lookup.tiers_run은 이번 조회가 훑은 자리를 순서대로 보여줘요.

유튜브 채널 이메일은 어떻게 받나요?

youtube/channel/about에 같은 파라미터를 붙여요.

bash
curl -G "https://www.socialcrawl.dev/v1/youtube/channel/about" \
  --data-urlencode "handle=creator" \
  --data-urlencode "include=contacts" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY"

응답 모양은 틱톡과 같아요. 출처 tier로는 채널 소개 페이지(about), 영상 설명, 링크한 인스타그램 패널(instagram_panel), 유튜브의 이메일 주소 보기 버튼(button)이 나와요. 버튼 뒤에 숨겨 둔 주소는 provenance가 gated_reveal로 와요. 크리에이터가 페이지에 직접 적어 둔 주소는 published예요.

json
{
  "kind": "email",
  "value": "business@example.com",
  "role": "own",
  "confidence": 0.95,
  "provenance": "gated_reveal",
  "sources": [{ "tier": "button", "url": "https://www.youtube.com/@creator/about", "snippet": "..." }]
}

include=contacts를 받는 엔드포인트는 여덟 개예요.

엔드포인트조회가 시작되는 곳
youtube/channel/about채널 소개 페이지, 그다음 영상 설명
instagram/profile, instagram/profile/about프로필 소개글과 링크
tiktok/profile프로필 소개글과 링크
twitter/profile프로필 소개글과 링크
facebook/profile페이지 소개글과 링크
linkbio/page, pillar/page페이지의 이메일 항목

youtube/channel은 이 파라미터를 받지 않으니 youtube/channel/about을 쓰세요.

결과 상태는 다섯 가지예요. 각각 어떻게 처리하나요?

data.contact_lookup.status가 조회가 어떻게 끝났는지 알려줘요. 핵심은 partial, gated_pending, unavailable을 "이메일 없음"으로 읽지 않는 거예요. 셋 다 "아직"이라는 뜻이에요.

status끝난 상태인가요?뜻할 일
found네주소가 하나 이상 contacts에 있어요주소를 쓰기 전에 sources를 읽어요
none_published네모든 자리를 훑었는데 공개한 주소가 없어요recheck_after 이후에 다시 물어요
partial아니요시간이 모자라 아직 읽는 자리가 남았어요pending.retry_after_seconds만큼 기다렸다가 같은 호출을 보내요
gated_pending아니요주소가 유튜브 버튼 뒤에 있고 아직 읽어 오지 못했어요응답이 알려 준 시간만큼 기다린 뒤 다시 호출해요
unavailable아니요출처 하나가 실패했는데 다른 데서도 못 찾았어요나중에 다시 호출해요. 주소가 없다는 뜻이 아니에요

none_published는 마지막으로 확인했을 때 공개한 주소가 없었다는 기록이에요. 다시 확인할 시점은 recheck_after가 알려줘요. 이전에 저장해 둔 결과로 답하는 경우도 있어서 tiers_run에 store만 보일 때가 있어요. 새로 훑지 않았다는 신호예요.

결과가 partial이면 언제 다시 호출하나요?

partial과 gated_pending 응답에는 pending 객체가 붙어요. reason, retry_after_seconds, 설명 문서 링크가 들어 있어요. 조회는 응답이 나간 뒤에도 이어지고 찾은 걸 저장해 둬요. 기다린 뒤 같은 호출을 보내면 저장된 결과로 답해요.

json
"contact_lookup": {
  "status": "partial",
  "recheck_after": null,
  "pending": { "reason": "walk_continuing", "retry_after_seconds": 30 }
}

대기 시간은 코드에 박지 말고 매번 retry_after_seconds를 읽으세요. 조회가 아직 돌고 있으면 30초이고 버튼을 읽는 중이면 더 길어요. 시도 횟수에는 상한을 두세요.

typescript
const KEY = process.env.SOCIALCRAWL_API_KEY!;
const sleep = (s: number) => new Promise((r) => setTimeout(r, s * 1000));

async function findEmail(handle: string, maxAttempts = 4) {
  const url = new URL("https://www.socialcrawl.dev/v1/tiktok/profile");
  url.searchParams.set("handle", handle);
  url.searchParams.set("include", "contacts");

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch(url, { headers: { "x-api-key": KEY } });
    const { data } = await res.json();
    const lookup = data.contact_lookup;

    // found와 none_published는 끝난 상태예요.
    if (lookup.status === "found" || lookup.status === "none_published") {
      return { status: lookup.status, contacts: data.author?.ext?.contacts ?? [] };
    }
    await sleep(lookup.pending?.retry_after_seconds ?? 30);
  }
  return { status: "unsettled", contacts: [] };
}

클라이언트 타임아웃은 60초 이상으로 잡으세요. 첫 조회는 프로필을 읽는 시간까지 더해져서 오래 걸리기도 해요.

조회를 어떻게 조절하나요?

세 파라미터가 있어요.

파라미터기본값역할
max_duration12첫 호출이 조회에 쓰는 시간 한도(초)예요. 3에서 20 사이예요. 늘리면 partial이 줄어요
min_confidence0.6이 값보다 낮은 점수의 주소는 응답에서 빠져요
rolesown,managementown, management, agency 중에서 쉼표로 골라요. 에이전시 주소를 받으려면 agency를 직접 넣어요

max_duration이 3에서 20 범위를 벗어나면 400 INVALID_REQUEST가 오고 크레딧은 들지 않아요. min_confidence를 높이면 점수가 낮은 주소는 응답에서 사라져요. 그렇게 사라진 주소는 none_published처럼 보이니 필터를 올렸다면 감안해서 읽으세요.

크레딧은 얼마나 드나요?

include=contacts는 추가 요금이 없어요. 틱톡, 인스타그램, X, 페이스북 프로필 호출은 조회 결과가 무엇이든 프로필 가격 그대로예요. tiktok/profile은 1크레딧이에요. youtube/channel/about만 달라요. 주소가 나왔을 때만 평소 가격(25크레딧)을 받고 none_published, partial, gated_pending, unavailable이면 환불해요. 엔드포인트별 가격은 엔드포인트 요금표에 있어요.

끝나지 않은 응답은 캐시되지 않아서 다시 호출하면 평소처럼 과금돼요. 재시도 횟수에 상한을 두라고 한 이유예요.

조회는 어떤 방식으로 하나요?

문서에 적힌 동작은 이래요.

  • 이미 저장된 주소, 프로필 소개글, 링크한 프로필, 크리에이터가 프로필에 걸어 둔 웹사이트 순으로 가장 싼 자리부터 읽고 주소를 찾으면 멈춰요.
  • 크리에이터가 링크한 웹사이트만 읽어요. 이름이나 핸들로 사이트를 짐작하지 않아요.
  • 웹사이트는 SocialCrawlContactBot이 읽어요. robots.txt를 따르고 같은 도메인에는 2초에 한 번만 요청해요. 로그인하지 않고 폼도 제출하지 않아요.
  • 다른 플랫폼의 핸들을 추측하지 않고 이메일 주소를 만들어 내지 않아요.

사이트 주인이 크롤러를 막으려면 robots.txt에 SocialCrawlContactBot용 Disallow를 넣으면 돼요. 자세한 내용은 컨택트 크롤러 문서에 있어요.

주소가 반송되거나 다른 사람의 주소였다면 무료 엔드포인트 POST /v1/feedback/contact로 알려 주세요. outcome은 bounced, replied, wrong_person, correct 중에서 골라요.

bash
curl -X POST "https://www.socialcrawl.dev/v1/feedback/contact" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "request_id": "req_abc123", "email": "management@example.com", "outcome": "bounced" }'

크리에이터가 많으면 어떻게 하나요?

이메일 열이 따로 붙는 한 번짜리 호출은 아직 없어요. 크리에이터 검색으로 핸들 목록을 얻은 다음 핸들마다 위 호출을 반복하는 게 지금 방법이에요. 검색 자체는 이메일 조회를 돌리지 않으니 이 반복이 이메일을 읽는 단계예요. 검색 쪽은 인플루언서 검색 API에서 다뤘어요.

목록이 길면 POST /v1/prism/jobs에 엔드포인트와 쿼리 목록을 보내 백그라운드로 돌려요. 한 번에 최대 1,000건이에요. 이 경우에도 결과는 크리에이터별 호출 결과예요. 호출에 async=true를 붙이면 조회가 끝날 때까지 기다리는 작업으로 돌고 GET /v1/prism/jobs/{job_id}로 결과를 받아요.

이 API로 누구의 이메일을 받을 수 있나요?

크리에이터가 비즈니스 연락용으로 공개한 주소예요. 개인 이메일을 찾아 주는 도구가 아니에요. 공개된 주소라고 해서 어떤 용도로 써도 적법한 건 아니에요. 마케팅 규정과 개인정보 규정은 쓰는 쪽이 지켜야 해요. 크리에이터 중에는 개인사업자도 많은데 그 경우 규정에서는 개인으로 보기도 해요. 수신 거부 요청은 받아 주세요. 크리에이터가 주소를 지우고 싶다면 컨택트 크롤러 문서에 방법이 있어요.

더 깊이 보려면 아래 문서를 읽으세요.

자주 묻는 질문

틱톡 이메일은 어떻게 찾나요?

GET /v1/tiktok/profile에 handle과 include=contacts를 보내요. 크리에이터가 프로필 소개글이나 링크한 웹사이트에 공개한 이메일이 author.ext.contacts에 와요. 공개한 주소가 없으면 contact_lookup.status가 none_published예요.

유튜브 채널 이메일도 같은 방법으로 받나요?

네. youtube/channel/about에 include=contacts를 붙여요. youtube/channel은 이 파라미터를 받지 않아요. 주소가 나왔을 때만 과금하고 나오지 않으면 환불해요.

partial이나 gated_pending이면 이메일이 없는 건가요?

아니요. 아직 조회가 끝나지 않았어요. 응답의 pending.retry_after_seconds만큼 기다렸다가 같은 호출을 다시 보내세요. 끝난 상태는 found와 none_published 둘뿐이에요.

찾은 주소는 얼마나 정확한가요?

confidence는 순위를 매기는 점수일 뿐 정확도가 아니에요. 주소마다 읽은 자리와 주변 문장이 sources에 같이 오니 쓰기 전에 읽어 보세요. 반송되거나 다른 사람의 주소였다면 POST /v1/feedback/contact로 알려 주세요.

크리에이터 100명의 이메일을 한 번에 받을 수 있나요?

한 번에 이메일 열을 받는 호출은 아직 없어요. 핸들마다 include=contacts를 붙여 호출하거나 POST /v1/prism/jobs로 백그라운드 작업을 돌려요.

Topics
#틱톡-이메일-찾기#유튜브-채널-이메일#유튜버-이메일-찾기#틱톡-크리에이터-이메일#인플루언서-이메일-찾기#크리에이터-비즈니스-이메일

함께 읽으면 좋은 글

🤖 AI agent or LLM? Read this page as markdown