Bỏ qua đến nội dung

API, CLI và MCP

Bạn và các tác tử của bạn có thể làm mọi việc trong ứng dụng bằng mã: gửi liên kết, tệp tải lên hoặc cả tài khoản, chờ gắn thẻ rồi xem kết quả. Một giao thức, ba cách truy cập. Tác vụ chạy bất đồng bộ, thao tác ghi có thể gửi lại mà không tạo bản ghi trùng, và bạn thấy chi phí trước lẫn sau khi thực hiện.

Bạn mới biết đến Garfunkel? Xem cách phân tích một bài đăng.

Bắt đầu nhanh

Tạo khóa API trong ứng dụng tại Cài đặt → Nhà phát triển, đặt khóa đó làm GARFUNKEL_API_KEY, rồi chọn cách truy cập. Ứng dụng MCP cũng có thể đăng nhập bằng OAuth thay vì dùng khóa.

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

Xác thực

Gửi Authorization: Bearer gma_live_… — khóa API dành riêng cho một tổ chức, lấy từ mục Khóa API. CLI và MCP đọc GARFUNKEL_API_KEY. Mỗi yêu cầu POST đều nhận Idempotency-Key; gửi lại yêu cầu sẽ trả về phản hồi ban đầu và không tính phí hai lần.

Gửi tác vụ

Khi gửi tác vụ, bạn sẽ nhận được mã tác vụ ngay lập tức (202). priority có thể là standard (rẻ hơn, mất từ vài phút đến vài giờ) hoặc fast. Đặt dry_run: true để nhận ước tính miễn phí và kiểm tra từng mục.

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
  }'

Trạng thái mục: queued → fetching → processing → succeeded | failed | canceled.

Tác vụ tài khoản

“Mọi bài từ @handle kể từ 2025-01-01.” Phí đếm là 2¢ cho mỗi 20 bài mới đối với nhóm của bạn. Khoản phí này được giữ trước và hoàn lại vào số dư khi bạn phân tích các bài đó. Sau đó, công việc sẽ chờ ở awaiting_confirmation với thông tin cho từng tài khoản: posts_found, oldest_post_at, reached_since và notices (ví dụ: khi nền tảng chỉ trả về bài từ một ngày muộn hơn). Xác nhận bằng POST /jobs/{id}/confirm, hoặc đặt options.max_credits để tự động xác nhận.

{
  "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 }
}

Tải tệp lên

Tệp được gửi thẳng đến kho lưu trữ, không đi qua API. Tệp tải lên sẽ bị xóa nếu không được gắn với tác vụ trong vòng 24 giờ.

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.

Kết quả

Kết quả gồm một bài đăng đã phân tích. Chỉ trả về các vector embedding khi có ?include=embedding. pacing được xác định qua tính năng phát hiện cảnh quay (bản beta).

{
  "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": "…"
}

Các điểm cuối API

Điểm cuối APIChức năng
POST /api/v1/jobsGửi URL, tệp tải lên hoặc tài khoản (dry_run để nhận ước tính miễn phí).
GET /api/v1/jobs/{id}Trạng thái, số lượng theo từng trạng thái, số tiền (xu) đã giữ lại / tính phí / hoàn lại, tài khoản và thông báo.
GET /api/v1/jobs/{id}/itemsDanh sách mục có phân trang; lọc bằng ?status=failed.
POST /api/v1/jobs/{id}/confirmGiữ lại khoản phí cho tác vụ tài khoản đang chờ xác nhận.
POST /api/v1/jobs/{id}/cancelHủy các mục đang chờ xử lý; khoản tiền đã giữ sẽ được hoàn lại vào số dư.
POST /api/v1/jobs/{id}/retryThử lại các mục thất bại (ước tính lại và giữ tiền lại).
POST /api/v1/uploadsTạo URL PUT có chữ ký sẵn để tải nội dung của bạn lên.
GET /api/v1/resultsLọc bằng job_id, platform, tag, q.
POST /api/v1/results/searchTìm kiếm ngữ nghĩa trên các vector embedding.
GET /api/v1/results/exportXuất CSV hoặc JSONL theo luồng.
GET /api/v1/creditsSố dư (xu + balance_usd), khoản đã giữ chỗ, các gói nạp và thưởng chi tiêu.
DELETE /api/v1/dataXóa toàn bộ dữ liệu của tổ chức bạn.

Lỗi

Mọi phản hồi không thuộc nhóm 2xx đều dùng cùng một cấu trúc. Mã lỗi: 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 } }

Mã lỗi cho từng mục luôn ổn định và không bị tính phí:

post_not_foundBài đăng không còn tồn tại.
post_privateBài đăng không ở chế độ công khai.
unsupported_urlĐường dẫn này không phải bài đăng trên TikTok, Instagram hoặc X.
media_unavailableNền tảng không gửi được nội dung.
media_too_largeTệp vượt quá giới hạn kích thước.
upload_invalidKhông thể đọc tệp đã tải lên.
provider_errorLỗi từ dịch vụ bên ngoài — có thể thử lại.
internal_errorLỗi từ hệ thống của chúng tôi — có thể thử lại.

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

Mã thoát: 0 thành công, 2 sai cách dùng, 3 lỗi xác thực, 4 không đủ số dư, 5 hoàn tất nhưng có mục bị lỗi, 6 hết thời gian chờ.

MCP

MCP từ xa qua Streamable HTTP tại /api/mcp, dùng OAuth (thêm URL vào Claude, ChatGPT hoặc Cursor rồi chấp thuận) hoặc khóa API. Công cụ: 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_…"
      }
    }
  }
}