본문으로 건너뛰기

API, CLI 및 MCP

앱에서 할 수 있는 일은 코드와 에이전트로도 할 수 있어요. 링크, 파일 또는 계정 전체를 제출하고 태그 작업이 끝나면 결과를 확인하세요. 세 가지 방식 모두 같은 규칙을 따라요. 작업은 비동기로 처리되고, 같은 요청을 다시 보내도 중복 처리되지 않으며, 작업 전후에 비용을 확인할 수 있어요.

Garfunkel를 처음 사용하시나요? 게시물 분석 과정 보기.

빠른 시작

앱에서 설정 → 개발자로 이동해 API 키를 만든 다음, GARFUNKEL_API_KEY로 설정하고 원하는 방식을 선택하세요. MCP 클라이언트는 키 대신 OAuth로 로그인할 수도 있어요.

export GARFUNKEL_API_KEY=gma_live_…
garfunkel submit urls.txt --category sports --dry-run
garfunkel submit urls.txt --category sports --wait
garfunkel results export job_… --format jsonl

인증

API 키에서 발급한 조직용 API 키를 Authorization: Bearer gma_live_…에 넣어 보내세요. CLI와 MCP는 GARFUNKEL_API_KEY를 읽어요. 모든 POST 요청에 Idempotency-Key를 지정할 수 있어요. 같은 요청을 다시 보내면 처음 응답을 돌려주고 요금은 한 번만 청구돼요.

작업 제출

제출하면 작업 ID가 즉시 반환돼요(202). priority는 standard(저렴하며 처리에 몇 분에서 몇 시간 걸려요) 또는 fast로 설정할 수 있어요. dry_run: true을 설정하면 항목별 검증 결과와 무료 예상 비용을 확인할 수 있어요.

curl -X POST https://garfunkel.gar-ai.com/api/v1/jobs \
  -H "Authorization: Bearer $GARFUNKEL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "items": [{ "url": "https://www.tiktok.com/@user/video/7412345678901234567" }],
    "options": { "translate_to": "en" },
    "dry_run": true
  }'

항목 상태: queued → fetching → processing → succeeded | failed | canceled.

계정 작업

“2025-01-01 이후 @handle의 모든 게시물.” 팀에서 새로 찾은 게시물 20개당 2¢가 들고, 먼저 보류한 뒤 해당 게시물을 분석하면 비용을 돌려드려요. 그러면 작업은 awaiting_confirmation 상태로 대기하고, 계정별로 posts_found, oldest_post_at, reached_since, notices가 표시돼요(예: 플랫폼에서 더 최근 날짜의 게시물까지만 제공하는 경우). POST /jobs/{id}/confirm으로 확인하거나, 자동 확인하려면 options.max_credits를 설정하세요.

{
  "items": [
    { "account": "@nike", "platform": "tiktok", "since": "2025-01-01", "max_posts": 1000 },
    { "account": "https://x.com/nasa", "since": "2025-01-01" }
  ],
  "options": { "max_credits": 50000 }
}

업로드

파일은 API를 거치지 않고 스토리지로 바로 전송돼요. 24시간 안에 작업에 연결되지 않은 파일은 삭제돼요.

POST /api/v1/uploads
{ "filename": "clip.mp4", "content_type": "video/mp4", "size_bytes": 1234567 }
→ { "id": "upl_…", "upload_url": "<presigned PUT>", "method": "PUT", "headers": {…}, "expires_at": "…" }

# PUT the bytes straight to storage, then submit { "upload_id": "upl_…" } as a job item.

결과

분석한 게시물 하나의 결과예요. 임베딩 벡터는 ?include=embedding를 지정한 경우에만 반환돼요. pacing은 샷 감지 기능으로 분석한 값이며, 베타 버전이에요.

{
  "item_id": "itm_01J…",
  "job_id": "job_01J…",
  "source": { "platform": "tiktok", "url": "…", "author": "…", "posted_at": "…",
              "metrics": { "views": 0, "likes": 0, "comments": 0, "shares": 0 } },
  "caption": "…",
  "language": "es",
  "transcript": { "text": "…", "segments": [{ "start": 0.0, "end": 2.1, "text": "…" }] },
  "translation": { "language": "en", "caption": "…", "transcript": "…", "on_screen_text": "…" },
  "summary": "…",
  "tags": { "format": "…", "theme": "…", "tone": ["…"], "topics": ["…"], "keywords": ["…"] },
  "hook": { "type": "…", "timing_s": 1.2, "confidence": 0.8 },
  "pacing": { "beta": true, "shot_count": 14, "avg_shot_s": 2.1, "cuts_per_s": 0.47, "first_cut_s": 0.9 },
  "embedding": { "dims": 1024 },
  "credits_charged": 12,
  "processed_at": "…"
}

엔드포인트

엔드포인트기능
POST /api/v1/jobsURL, 파일 또는 계정을 제출해요. 무료 예상 비용은 dry_run으로 확인할 수 있어요.
GET /api/v1/jobs/{id}상태, 상태별 항목 수, 확보·청구·반환된 금액(센트), 계정 및 안내를 확인해요.
GET /api/v1/jobs/{id}/items페이지별로 항목을 확인하고 ?status=failed로 필터링해요.
POST /api/v1/jobs/{id}/confirm확인을 기다리는 계정 작업의 요금을 잔액에서 확보해요.
POST /api/v1/jobs/{id}/cancel대기 중인 항목을 취소해요. 확보한 금액은 잔액으로 돌아가요.
POST /api/v1/jobs/{id}/retry실패한 항목을 다시 시도해요. 비용을 다시 계산하고 잔액에서 다시 확보해요.
POST /api/v1/uploads내 미디어를 직접 업로드하는 사전 서명 PUT 요청이에요.
GET /api/v1/resultsjob_id, platform, tag, q로 필터링해요.
POST /api/v1/results/search임베딩을 바탕으로 의미를 검색해요.
GET /api/v1/results/exportCSV 또는 JSONL 형식으로 데이터를 스트리밍해요.
GET /api/v1/credits잔액(센트 + balance_usd), 예약 금액, 충전 팩, 사용 보상이에요.
DELETE /api/v1/data조직의 모든 데이터를 삭제해요.

오류

2xx가 아닌 모든 응답은 같은 형식을 사용해요. 코드: unauthorized, forbidden, not_found, invalid_request, insufficient_credits, rate_limited, idempotency_conflict, counting_in_progress, internal_error.

{ "error": { "code": "insufficient_credits",
             "message": "Job needs $1.80; your balance is 42¢.",
             "details": { "required": 180, "balance": 42 },
             "retryable": false } }

항목별 실패 코드는 항상 동일하며 요금이 청구되지 않아요.

post_not_found게시물이 존재하지 않아요.
post_private게시물이 공개 상태가 아니에요.
unsupported_urlTikTok, Instagram 또는 X 게시물 링크가 아니에요.
media_unavailable플랫폼에서 미디어를 제공하지 않았어요.
media_too_large크기 제한을 초과했어요.
upload_invalid업로드한 파일을 읽을 수 없어요.
provider_error외부 서비스 오류예요. 다시 시도할 수 있어요.
internal_error내부 오류예요. 다시 시도할 수 있어요.

CLI

export GARFUNKEL_API_KEY=gma_live_…

garfunkel submit urls.txt --category sports --dry-run   # free estimate
garfunkel submit urls.txt --category sports --wait      # run it
garfunkel results export job_… --format jsonl -o results.jsonl

# Whole accounts: counting is 2¢ per 20 posts (credited back when analyzed); you confirm the analysis
garfunkel submit --accounts accounts.txt --since 2025-01-01 --max-credits 50000

종료 코드: 0 성공, 2 사용 오류, 3 인증 오류, 4 잔액 부족, 5 일부 항목 실패 후 완료, 6 시간 초과예요.

MCP

OAuth(Claude, ChatGPT 또는 Cursor에 URL을 추가한 뒤 승인) 또는 API 키로 /api/mcp에서 Streamable HTTP 기반 원격 MCP에 연결해요. 도구: estimate_job, submit_job, create_upload, confirm_job, list_job_posts, get_job, get_team, wait_for_job, list_results, get_result, list_accounts, get_account, analyze_comments, refresh_metrics, get_comments, search_results, export_results, chat_with_data, get_credit_balance, show_post, create_checkout.

{
  "mcpServers": {
    "garfunkel": {
      "type": "http",
      "url": "https://garfunkel.gar-ai.com/api/mcp",
      "headers": {
        "Authorization": "Bearer gma_live_…"
      }
    }
  }
}