Prism Comments API
TikTok과 YouTube, Facebook, Reddit, Hacker News, Instagram 게시물의 댓글을 끝까지 페이징해 전부 반환하며 플랫폼이 허용하면 답글도 중첩해 담습니다.
GET /v1/prism/commentsPrism Comments API는 언제 쓰나요
댓글 스레드 전체가 필요할 때 사용하세요. 플랫폼별 comments 엔드포인트를 돌려가며 페이지를 이어 붙이지 않고 요청 한 번으로 끝납니다.
API 레퍼런스 영문 원문
Give it any TikTok, YouTube, Facebook, Reddit, Hacker News, or Instagram post URL and it harvests every top-level comment (paginated to the end) with ALL of each comment's replies nested under it, in one call. Each entry in data.comments is { comment, replies }: a comment's replies are the replies array beside it, never separate entries, so returned and total_fetched count top-level comments and replies_returned counts the replies nested under them (parents_expanded is how many comments carry any). On TikTok, YouTube and Facebook (replies on by default) and on Instagram (when you send replies=true), every returned comment whose engagement.replies is above zero gets its replies fetched and their pages walked to the end, up to 100 parent comments and 10 replies pages per comment per call. A comment whose replies a limit, the time budget or a failed replies call stopped short is marked replies_truncated: true and the response says completed: false; nothing is dropped silently. Reddit and Hacker News return their whole nested thread; on Reddit, a reply branch the scan's credit or time budget cannot reach is marked the same way. Instagram without replies=true comes back top-level only, as before; you can also fetch one comment's replies yourself from GET /v1/instagram/post/comment/replies (post url plus the parent comment_id, cursor-paged, 1 credit a call). Pass sort=top to get the most-liked comments first (ranked by engagement.likes): ideal for pulling the top comments on a high-volume post; pair it with limit to cap how many you get back (e.g. sort=top&max=500&limit=200 scans ~500 and returns the top 200). YouTube sorts upstream so its top set is exact; other platforms are sorted across the scanned set. Metered at 1 credit per comment page plus 1 credit per replies call that returned replies (minimum 2). The upfront hold covers the pages max implies plus 1 credit per parent comment it may expand (3 on Instagram, whose replies come 15 to a page), and everything unused is refunded. sort/limit never change the price. Instagram is the exception: an Instagram post URL is a flat 5 credits per call whatever max you pass, because that source returns the comment set in one call rather than by page; with replies=true it adds 1 credit per replies call that returned replies. Returns sync JSON, or a typed SSE stream when you send Accept: text/event-stream: a page chunk lands as each page settles. The next_cursor is one opaque token that resumes every leg; legs[] reports each page's and each replies call's status, cost, and latency.
69개 플랫폼을 병렬로 검색합니다
Comments API로 무엇을 할 수 있을까요
Comments 엔드포인트가 통합 스키마와 계산 필드를 담은 Prism 데이터를 한 번의 요청으로 보내드려요. 스크래핑 인프라를 직접 만들거나 유지할 필요가 없어요.
요청 예시
# GET /v1/prism/comments: Metered: holds 120 credits per call up front and refunds what the call does not use. Cache hits are free and failed calls are refunded.
# Check the price first for 0 credits: add dry_run=1 to the query. Nothing is fetched or charged.
# --max-time 50: this endpoint's measured p99 latency x 1.5.
# --retry 3: retries timeouts, 429 and 5xx, honoring Retry-After.
# -o response.json keeps only the final attempt's body.
# One Idempotency-Key per request, reused on every retry, so a retried call is never charged twice.
IDEMPOTENCY_KEY=$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')
curl -sS --max-time 50 --retry 3 -o response.json \
-H "x-api-key: YOUR_API_KEY" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
"https://www.socialcrawl.dev/v1/prism/comments?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ&replies=true&sort=top" && cat response.json# GET /v1/prism/comments: Metered: holds 120 credits per call up front and refunds what the call does not use. Cache hits are free and failed calls are refunded.
# Check the price first for 0 credits: add dry_run=1 to the query. Nothing is fetched or charged.
import os
import random
import time
import uuid
import requests
API_KEY = os.environ.get("SOCIALCRAWL_API_KEY", "YOUR_API_KEY")
TIMEOUT_S = 50 # this endpoint's measured p99 latency x 1.5.
MAX_RETRIES = 3
URL = "https://www.socialcrawl.dev/v1/prism/comments"
def backoff(attempt):
# Exponential backoff with jitter: about 1 s, 2 s, then 4 s.
return 2 ** attempt * (0.5 + random.random() / 2)
def socialcrawl(params):
# One Idempotency-Key per request, reused on every retry, so a retried call is never charged twice.
idempotency_key = str(uuid.uuid4())
for attempt in range(MAX_RETRIES + 1):
try:
res = requests.get(
URL,
params=params,
headers={"x-api-key": API_KEY, "Idempotency-Key": idempotency_key},
timeout=TIMEOUT_S,
)
body = res.json()
except (requests.RequestException, ValueError):
# A timeout, a dropped connection or a non-JSON gateway page: retry with the same key.
if attempt == MAX_RETRIES:
raise
time.sleep(backoff(attempt))
continue
if body["success"]:
return body
error = body["error"]
# Branch on error["type"], never on the message text.
if error["type"] == "RESOURCE_NOT_FOUND":
return None # refunded: nothing to read
retry_after = res.headers.get("Retry-After")
# SERVICE_UNAVAILABLE without Retry-After is a withdrawn endpoint: permanent.
permanent = error["type"] == "SERVICE_UNAVAILABLE" and retry_after is None
if not error.get("retryable") or permanent or attempt == MAX_RETRIES:
raise RuntimeError(f"{error['type']}: {error['message']} (request_id {body['request_id']})")
# Retry-After (seconds) wins; otherwise back off.
time.sleep(float(retry_after) if retry_after else backoff(attempt))
params = {
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"replies": "true",
"sort": "top",
}
body = socialcrawl(params)
if body is not None:
print(body["data"])// GET /v1/prism/comments: Metered: holds 120 credits per call up front and refunds what the call does not use. Cache hits are free and failed calls are refunded.
// Check the price first for 0 credits: add dry_run=1 to the query. Nothing is fetched or charged.
const API_KEY = process.env.SOCIALCRAWL_API_KEY ?? "YOUR_API_KEY";
const TIMEOUT_MS = 50_000; // this endpoint's measured p99 latency x 1.5.
const MAX_RETRIES = 3;
type Page = { next_cursor: string | null; has_more: boolean };
type SocialCrawlResponse =
| { success: true; data: any; pagination?: Page; credits_used: number; request_id: string }
| { success: false; error: { type: string; message: string; retryable: boolean }; request_id: string };
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
// Exponential backoff with jitter: about 1 s, 2 s, then 4 s.
const backoffMs = (attempt: number) => 2 ** attempt * 1000 * (0.5 + Math.random() / 2);
async function socialcrawl(url: URL) {
// One Idempotency-Key per request, reused on every retry, so a retried call is never charged twice.
const idempotencyKey = crypto.randomUUID();
for (let attempt = 0; ; attempt++) {
let res: Response;
let body: SocialCrawlResponse;
try {
res = await fetch(url, {
headers: {
"x-api-key": API_KEY,
"Idempotency-Key": idempotencyKey,
},
signal: AbortSignal.timeout(TIMEOUT_MS),
});
body = (await res.json()) as SocialCrawlResponse;
} catch (error) {
// A timeout, a dropped connection or a non-JSON gateway page: retry with the same key.
if (attempt >= MAX_RETRIES) throw error;
await sleep(backoffMs(attempt));
continue;
}
if (body.success) return body;
// Branch on error.type, never on the message text.
if (body.error.type === "RESOURCE_NOT_FOUND") return null; // refunded: nothing to read
const retryAfter = res.headers.get("Retry-After");
// SERVICE_UNAVAILABLE without Retry-After is a withdrawn endpoint: permanent.
const permanent = body.error.type === "SERVICE_UNAVAILABLE" && retryAfter === null;
if (!body.error.retryable || permanent || attempt >= MAX_RETRIES) {
throw new Error(`${body.error.type}: ${body.error.message} (request_id ${body.request_id})`);
}
// Retry-After (seconds) wins; otherwise back off.
await sleep(retryAfter ? Number(retryAfter) * 1000 : backoffMs(attempt));
}
}
const url = new URL("https://www.socialcrawl.dev/v1/prism/comments");
url.searchParams.set("url", "https://www.youtube.com/watch?v=dQw4w9WgXcQ");
url.searchParams.set("replies", "true");
url.searchParams.set("sort", "top");
const body = await socialcrawl(url);
if (body) console.log(body.data);파라미터
| 파라미터 | 필수 | 설명 |
|---|---|---|
| url | 예 | Absolute http(s) URL of the post whose comments to harvest. |
| max | 아니오 | Stop after roughly this many top-level comments (1-5000, default 1000). Whole pages are returned, so the actual count can slightly exceed this. Drives billing and, for `sort=top`, the depth of the ranking scan. |
| replies | 아니오 | Nest every reply under the comments that have them (`engagement.replies` above zero), walking each comment's replies pages to the end: up to 100 comments and 10 replies pages per comment per call, 1 credit per replies call that returned replies. Default true on TikTok, YouTube and Facebook. On Instagram it is off unless you send `replies=true`, which adds 1 credit per replies call to the flat 5. A comment a limit or the time budget stopped short is marked `replies_truncated: true` and the response says `completed: false`. Reddit and Hacker News always return their whole nested thread and ignore it. Pair with `replies=false` when you only want the top comments. |
| cursor | 아니오 | Opaque composite cursor from a prior response's `next_cursor` to resume harvesting. |
| sort | 아니오 | `recent` (default: natural order) or `top` (most-liked first, ranked by each comment's like count). With `top`, the response adds `sorted_by: "likes_desc"`. On Instagram, `top` returns the platform's own ranked head (`sorted_by: "popular"`) rather than a re-sort, and that head is finite: use the default `recent` to harvest a whole Instagram thread. (top | recent) |
| limit | 아니오 | Cap on how many top-level comments to return after sorting/scanning (1-5000, defaults to `max`). Truncates only the returned set, never what was scanned or billed. The response reports `returned`. |
Prism Comments API는 무엇을 돌려주나요
모든 응답은 하나의 통합 스키마를 따라요. 크레딧을 쓰기 전에 어떤 필드가 돌아오는지, 실제 응답 본문 그대로 확인해 보세요.
응답 예시 보기
{
"success": true,
"platform": "instagram",
"endpoint": "/v1/instagram/engagement",
"data": {
"engagement_rate_percentages": 38.33,
"recent_posts": 12,
"followers": 87608035,
"comments": 528912,
"likes": 33049046,
"recent_posts_explanation": "Statistics based on the last 12 posts",
"id_user": "2278169415",
"username": "mrbeast",
"is_private": false,
"posts_details": [
{
"likes": 5636982,
"comments": 69484,
"taken_at": 1781457954,
"datetime": "2026-06-14 20:25:54",
"hours_since_post": 461,
"time_ago": "19 days ago",
"likes_per_hour": 12228,
"comments_per_hour": 151
},
{
"likes": 20000768,
"comments": 223510,
"taken_at": 1732824650,
"datetime": "2024-11-28 23:10:50",
"hours_since_post": 13971,
"time_ago": "2 years ago",
"likes_per_hour": 1432,
"comments_per_hour": 16
},
{
"likes": 929226,
"comments": 30633,
"taken_at": 1782232475,
"datetime": "2026-06-23 19:34:35",
"hours_since_post": 246,
"time_ago": "10 days ago",
"likes_per_hour": 3777,
"comments_per_hour": 125
},
{
"likes": 487761,
"comments": 22482,
"taken_at": 1781799425,
"datetime": "2026-06-18 19:17:05",
"hours_since_post": 366,
"time_ago": "15 days ago",
"likes_per_hour": 1333,
"comments_per_hour": 61
},
{
"likes": 712265,
"comments": 15716,
"taken_at": 1781366405,
"datetime": "2026-06-13 19:00:05",
"hours_since_post": 487,
"time_ago": "20 days ago",
"likes_per_hour": 1463,
"comments_per_hour": 32
},
{
"likes": 1475116,
"comments": 35386,
"taken_at": 1781277094,
"datetime": "2026-06-12 18:11:34",
"hours_since_post": 512,
"time_ago": "21 days ago",
"likes_per_hour": 2881,
"comments_per_hour": 69
},
{
"likes": 1108220,
"comments": 26632,
"taken_at": 1780160249,
"datetime": "2026-05-30 19:57:29",
"hours_since_post": 822,
"time_ago": "1 months ago",
"likes_per_hour": 1348,
"comments_per_hour": 32
},
{
"likes": 542948,
"comments": 28476,
"taken_at": 1779375582,
"datetime": "2026-05-21 17:59:42",
"hours_since_post": 1040,
"time_ago": "1 months ago",
"likes_per_hour": 522,
"comments_per_hour": 27
},
{
"likes": 698514,
"comments": 24401,
"taken_at": 1779120014,
"datetime": "2026-05-18 19:00:14",
"hours_since_post": 1111,
"time_ago": "2 months ago",
"likes_per_hour": 629,
"comments_per_hour": 22
},
{
"likes": 468000,
"comments": 13548,
"taken_at": 1778947209,
"datetime": "2026-05-16 19:00:09",
"hours_since_post": 1159,
"time_ago": "2 months ago",
"likes_per_hour": 404,
"comments_per_hour": 12
},
{
"likes": 526594,
"comments": 24411,
"taken_at": 1777737719,
"datetime": "2026-05-02 19:01:59",
"hours_since_post": 1495,
"time_ago": "2 months ago",
"likes_per_hour": 352,
"comments_per_hour": 16
},
{
"likes": 462652,
"comments": 14233,
"taken_at": 1777580305,
"datetime": "2026-04-30 23:18:25",
"hours_since_post": 1538,
"time_ago": "2 months ago",
"likes_per_hour": 301,
"comments_per_hour": 9
}
]
},
"credits_used": 5,
"credits_remaining": 9999,
"request_id": "req-8Kq2ZmR4vT9xLb3P",
"cached": false,
"redacted": true
}Instagram API에서 가져온 예시예요. 모든 SocialCrawl 엔드포인트가 똑같은 통합 스키마를 돌려주기 때문에, Prism Comments 응답도 같은 필드로 구성돼요.
Prism Comments API는 어떻게 동작하나요
API 키와 함께 GET 요청을 보내면, 통합 스키마와 계산 필드를 담은 깔끔한 JSON이 돌아와요.
메서드
GET
응답 형식
JSON
소셜 미디어 데이터를 몇 초 만에 수집하는 방법
개발자를 위한 가장 빠른 소셜 미디어 스크래핑 API. 월간 활성 사용자 100억 명 이상을 포괄하는 69개 플랫폼에서 프로필, 게시물, 댓글, 분석 데이터를 수집하세요.
모든 플랫폼을 하나의 스키마로
동일한 응답 구조로 69개 플랫폼을 조회하세요. 연동은 한 번이면 충분합니다.
단순 수집을 넘어 계산된 필드 제공
엔드포인트가 해당 지표를 지원하고 계산에 필요한 원본 값이 있을 때, 정규화된 레코드에 engagement_rate, estimated_reach, content_category, language를 함께 담아 바로 활용할 수 있습니다.
코드 한 줄 쓰기 전에, 데이터부터
Visual Data Explorer에 URL만 붙여넣으면 결과 카드와 정형화된 테이블, CSV 내보내기를 바로 사용할 수 있습니다.
import requests
response = requests.get(
'https://www.socialcrawl.dev/v1/tiktok/profile',
params={'handle': 'charlidamelio'},
headers={'x-api-key': 'sc_YOUR_API_KEY'}
)
data = response.json(){
"success": true,
"platform": "tiktok",
"data": {
"author": {
"username": "charlidamelio",
"followers": 152400000
},
"engagement": {
"likes": 12400000000,
"engagement_rate": 0.087
},
"metadata": {
"language": "en",
"content_category": "lifestyle"
}
}
}자주 묻는 질문
API, 요금제, 기능에 대한 질문과 답변입니다.
문의하기게시물의 모든 댓글을 어떻게 가져오나요?
어떤 플랫폼을 지원하나요?
답글도 중첩해서 주나요?
요금은 어떻게 책정되나요?
댓글을 수집되는 대로 스트리밍으로 받을 수 있나요?
AI에게 SocialCrawl을 물어보세요
이 엔드포인트를 쓰는 활용 가이드
가이드마다 작업 하나를 처음부터 끝까지 다루고, 호출 순서와 한 번 실행할 때 드는 비용을 정리했어요. 가이드 본문은 영어예요.
Prism Comments 데이터, 가져올 준비 되셨어요?
API 키 받고 60초 안에 Prism 데이터를 받아 가세요.
