Utility API Quickstart API
첫 호출에 필요한 것을 한 번에 반환합니다. 인증 방법, 기본 URL, 응답 구조, 크레딧 과금, 에러 코드, 레이트 리밋, 샘플이 들어 있습니다.
GET /v1/utility/quickstartUtility API Quickstart API는 언제 쓰나요
처음 연동하면서 API의 규칙을 한 응답으로 파악할 때 무료로 사용하세요.
API 레퍼런스 영문 원문
Everything needed for a first successful API call in one response: authentication, base URL, the response envelope, the credit billing model, the error taxonomy, rate limits, pagination rules, and a copy-paste first request. Pass platform to tailor the first-call example. Free to call.
69개 플랫폼을 병렬로 검색합니다
API Quickstart API로 무엇을 할 수 있을까요
API Quickstart 엔드포인트가 통합 스키마와 계산 필드를 담은 Utility 데이터를 한 번의 요청으로 보내드려요. 스크래핑 인프라를 직접 만들거나 유지할 필요가 없어요.
요청 예시
# GET /v1/utility/quickstart: Free: 0 credits per call.
# --max-time 10: 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 10 --retry 3 -o response.json \
-H "x-api-key: YOUR_API_KEY" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
"https://www.socialcrawl.dev/v1/utility/quickstart?platform=tiktok" && cat response.json# GET /v1/utility/quickstart: Free: 0 credits per call.
import os
import random
import time
import uuid
import requests
API_KEY = os.environ.get("SOCIALCRAWL_API_KEY", "YOUR_API_KEY")
TIMEOUT_S = 10 # this endpoint's measured p99 latency x 1.5.
MAX_RETRIES = 3
URL = "https://www.socialcrawl.dev/v1/utility/quickstart"
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 = {
"platform": "tiktok",
}
body = socialcrawl(params)
if body is not None:
print(body["data"])// GET /v1/utility/quickstart: Free: 0 credits per call.
const API_KEY = process.env.SOCIALCRAWL_API_KEY ?? "YOUR_API_KEY";
const TIMEOUT_MS = 10_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/utility/quickstart");
url.searchParams.set("platform", "tiktok");
const body = await socialcrawl(url);
if (body) console.log(body.data);파라미터
| 파라미터 | 필수 | 설명 |
|---|---|---|
| platform | 아니오 | Tailor the first-call example and links to one platform slug |
Utility API Quickstart API는 무엇을 돌려주나요
문서에 나온 응답 구조와 필드를 보여 주기 위해 만든 합성 예시예요. 값은 이해를 돕기 위한 것이며 실제 API 응답은 아니에요.
응답 예시 보기
{
"success": true,
"platform": "utility",
"endpoint": "/v1/utility/quickstart",
"data": {
"kind": "quickstart",
"name": "SocialCrawl API",
"base_url": "https://www.socialcrawl.dev/v1",
"auth": {
"type": "api_key",
"header": "x-api-key",
"also_accepted": "Authorization: Bearer <key>",
"get_key_url": "https://www.socialcrawl.dev/dashboard/api"
},
"first_call": {
"description": "Get TikTok user profile",
"url": "https://www.socialcrawl.dev/v1/tiktok/profile?handle=charlidamelio",
"curl": "curl -H \"x-api-key: $SOCIALCRAWL_API_KEY\" \"https://www.socialcrawl.dev/v1/tiktok/profile?handle=charlidamelio\"",
"how_to_use": "/v1/utility/endpoint?id=tiktok/profile"
},
"envelope": {
"success": {
"success": true,
"platform": "tiktok",
"endpoint": "/v1/tiktok/profile",
"data": "... the endpoint's response object ...",
"credits_used": 1,
"request_id": "req-Ex4mpleRequest1d",
"cached": false,
"credits_remaining": 99
},
"success_list": {
"success": true,
"platform": "tiktok",
"endpoint": "/v1/tiktok/profile/videos",
"data": {
"items": [
"... one row per result ..."
],
"next_cursor": "... the source's own cursor; use pagination.next_cursor ...",
"dropped": 0
},
"credits_used": 1,
"request_id": "req-Ex4mpleRequest1d",
"cached": false,
"pagination": {
"next_cursor": "sc.eyJ2IjoyLCJjIjoiLi4uIHRoZSBzb3VyY2UncyBvd24gY3Vyc29yOyB1c2UgcGFnaW5hdGlvbi5uZXh0X2N1cnNvciAuLi4ifQ",
"has_more": true,
"page_size": 1,
"typical_page_size": 30,
"next_page_credits": 1
},
"credits_remaining": 99
},
"error": {
"success": false,
"error": {
"type": "INSUFFICIENT_CREDITS",
"message": "... human-readable cause ... Retrying this request will not succeed until your account balance changes.",
"status": 402,
"doc_url": "https://www.socialcrawl.dev/docs/errors#insufficient-credits",
"retryable": false,
"details": {
"reason": "balance_too_low",
"retry_will_succeed": false,
"next_step": "Top up your credits on the billing page (or turn on auto-recharge there), then send the request again.",
"top_up_url": "https://www.socialcrawl.dev/dashboard/billing/payments"
}
},
"credits_used": 0,
"request_id": "req-Ex4mpleRequest1d",
"credits_remaining": 0
}
},
"billing": {
"model": "credits",
"tiers": {
"standard": 1,
"advanced": 5,
"premium": 10
},
"rules": [
"Cache hits cost 0 credits",
"Failed calls and empty results are automatically refunded",
"Some endpoints have flat or metered pricing; each endpoint's exact cost is in /v1/utility/endpoints"
]
},
"errors": [
{
"code": "MISSING_API_KEY",
"http": 401,
"meaning": "No API key on the request: send x-api-key or Authorization: Bearer"
},
{
"code": "INVALID_API_KEY",
"http": 401,
"meaning": "API key is malformed, not found, revoked, or expired"
},
{
"code": "INSUFFICIENT_CREDITS",
"http": 402,
"meaning": "Credit balance is lower than the endpoint cost"
},
{
"code": "INVALID_REQUEST",
"http": 400,
"meaning": "A required parameter is missing, a value failed validation, or no one-of group member was provided"
},
{
"code": "ENDPOINT_NOT_FOUND",
"http": 404,
"meaning": "The platform or resource is not supported"
},
{
"code": "RESOURCE_NOT_FOUND",
"http": 404,
"meaning": "The requested item was not found on the platform; credits are refunded when triggered by an empty upstream result"
},
{
"code": "CONCURRENCY_LIMIT",
"http": 429,
"meaning": "More than 50 simultaneous requests on the same API key; honor Retry-After, then back off"
},
{
"code": "UPSTREAM_ERROR",
"http": 502,
"meaning": "The platform returned an error; credits are automatically refunded"
},
{
"code": "SERVICE_UNAVAILABLE",
"http": 503,
"meaning": "Temporarily unavailable for this platform after repeated failures; retry shortly, credits are refunded"
},
{
"code": "INTERNAL_ERROR",
"http": 500,
"meaning": "Unexpected server error; credits are automatically refunded"
},
{
"code": "METHOD_NOT_ALLOWED",
"http": 405,
"meaning": "Wrong HTTP method for this endpoint"
},
{
"code": "IDEMPOTENCY_IN_PROGRESS",
"http": 409,
"meaning": "Another request with the same key and payload is still running; not charged, retry after Retry-After"
},
{
"code": "IDEMPOTENCY_KEY_CONFLICT",
"http": 409,
"meaning": "The Idempotency-Key is already in use by another account"
},
{
"code": "IDEMPOTENCY_REPLAY_UNAVAILABLE",
"http": 409,
"meaning": "The completed response for this key exceeded the replay size limit; use a new key to make a new billable request"
},
{
"code": "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
"http": 422,
"meaning": "The Idempotency-Key was reused with a different request payload"
},
{
"code": "PAYLOAD_TOO_LARGE",
"http": 413,
"meaning": "The JSON request body exceeds the 1 MB size limit"
},
{
"code": "RATE_LIMITED",
"http": 429,
"meaning": "More than 600 requests in a 1-minute window on the same API key; honor Retry-After, then back off"
},
{
"code": "KEY_BUDGET_EXCEEDED",
"http": 402,
"meaning": "This API key has spent its per-key credit limit; the account balance is unaffected. Raise or reset the key's limit in Dashboard → API Keys, or use a key with no limit"
},
{
"code": "COHORT_MEMBER_LIMIT_EXCEEDED",
"http": 400,
"meaning": "The member upload would push the cohort past its 10,000-member limit"
},
{
"code": "COHORT_LIMIT_EXCEEDED",
"http": 400,
"meaning": "The account already holds the maximum of 100 cohorts; delete one before creating another"
},
{
"code": "COHORT_IDENTITY_PLATFORM_UNSUPPORTED",
"http": 400,
"meaning": "That platform is not supported for cohort queries"
},
{
"code": "COHORT_IDENTITY_CONFLICT",
"http": 409,
"meaning": "Another external_id already claims that normalized identity in this cohort"
},
{
"code": "COHORT_QUERY_NOT_CANCELLABLE",
"http": 409,
"meaning": "The cohort query is already terminal and cannot be cancelled"
},
{
"code": "COHORT_QUERY_NOT_READY",
"http": 409,
"meaning": "The cohort query has not reached a terminal state, so its results are not available yet"
},
{
"code": "COHORT_RESULT_TOO_LARGE",
"http": 413,
"meaning": "A single stored cohort result cannot fit beneath the 1 MB response-page ceiling"
},
{
"code": "RUN_NOT_FOUND",
"http": 404,
"meaning": "No discover run with this id belongs to your account; start a run"
},
{
"code": "RUN_STATE_CONFLICT",
"http": 409,
"meaning": "The discover run is in a state that does not allow this call, such as resuming a completed run"
},
{
"code": "RUN_EXPIRED",
"http": 410,
"meaning": "The discover run's retention passed and its rows were deleted; start a new run"
},
{
"code": "NEEDS_ASYNC",
"http": 422,
"meaning": "The discover request is over what one call can answer and async=false forbids a background run"
},
{
"code": "SCHEDULE_NOT_FOUND",
"http": 404,
"meaning": "No discover schedule with this id belongs to your account; list yours at /v1/prism/discover/schedules"
},
{
"code": "STREAM_NOT_FOUND",
"http": 404,
"meaning": "No listener with this id belongs to this API key; list this key's listeners"
},
{
"code": "STREAM_STATE_CONFLICT",
"http": 409,
"meaning": "The listener's state does not allow this call, such as resuming a deleted listener"
},
{
"code": "CURSOR_EXPIRED",
"http": 410,
"meaning": "The events cursor is older than the event log's 30-day retention; restart from cursor=oldest"
}
],
"envelope_fields": {
"data.dropped": "List responses only. Count of upstream rows discarded because they could not be repaired to the schema; 0 means the page is complete. It sits INSIDE data, not at the envelope root, and is absent from single-object responses.",
"data._warnings": "Optional string[] of non-fatal notices (field-map drift, clamped computed values). Advisory only; never treat its presence as a failure.",
"data.next_cursor": "List responses only. The source's own cursor, kept for older clients; page with pagination.next_cursor instead.",
"data.empty_reason": "List responses with no rows only. Why the page is empty (no_matches, end_of_list, nothing_new_since, ...), with data.empty_reason_note saying what to do next.",
"pagination": "List responses only, at the envelope ROOT. Stop on has_more === false rather than on cursor absence.",
"pagination.typical_page_size": "Rows a full page of this endpoint holds for this request, or null when it is not verified. A shorter page is a short page, not an error.",
"pagination.next_page_credits": "Credits the next page holds up front, priced from the next request itself; null when there is no next page.",
"cached": "true when the response came from cache, in which case credits_used is 0.",
"age_s": "Cache hits only, beside cached. Whole seconds since the copy was fetched (also the X-Cache-Age header), or null when not recorded. Send max_age_s to choose how old a copy you accept: up to an hour on profile and post lanes, served for 0 credits; a lower value fetches fresh; 0 always fetches live.",
"credits_remaining_note": "Cache hits only. Says why credits_remaining is null there (a free hit does not read the balance) and where to read it.",
"error.retryable": "Errors only. true when the same request may succeed later (honor Retry-After); false means change the request instead.",
"error.details": "Errors only, optional. Structured context for the error, such as the credits a 402 needed and how to make the call fit."
},
"pagination": {
"how": "List endpoints return pagination.next_cursor; pass it back as ?cursor=... until has_more is false",
"params": [
"cursor"
]
},
"rate_limits": {
"requests_per_minute": 600,
"concurrent_requests": 50
},
"stats": {
"platforms": 69,
"endpoints": 679
},
"next_steps": {
"catalog": "/v1/utility/endpoints",
"endpoint_guide": "/v1/utility/endpoint?id=tiktok/profile",
"agent_context": "/v1/utility/llms",
"docs": "https://www.socialcrawl.dev/docs",
"openapi": "https://www.socialcrawl.dev/openapi.json",
"mcp_server": "npx -y socialcrawl-mcp",
"agent_skill": "npx skills add socialcrawl/skills"
}
},
"credits_used": 0,
"request_id": "req-Ex4mpleRequest1d",
"cached": false
}문서에 나온 응답 구조를 확인하기 위한 합성 예시예요. 값은 이해를 돕기 위한 것이며 운영 환경에서 가져온 응답이 아니에요.
Utility API Quickstart 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을 물어보세요
Utility API Quickstart 데이터, 가져올 준비 되셨어요?
API 키 받고 60초 안에 Utility 데이터를 받아 가세요.
