Pular para o conteúdo

API, CLI e MCP

Tudo o que você pode fazer no app também pode ser feito pelo seu código e pelos seus agentes: envie links, arquivos ou contas inteiras, aguarde as marcações e consulte os resultados. Um contrato com três formas de acesso. Os trabalhos são assíncronos, as gravações são idempotentes e você vê o custo antes e depois.

Conhecendo o Garfunkel? Veja como um post é analisado.

Início rápido

Crie uma chave de API no app, em Configurações → Desenvolvedores, defina-a como GARFUNKEL_API_KEY e escolha como acessar. Clientes MCP também podem entrar com OAuth em vez de usar uma chave.

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

Autenticação

Envie Authorization: Bearer gma_live_… — uma chave de API vinculada à organização, disponível em Chaves de API. A CLI e o MCP leem GARFUNKEL_API_KEY. Todo POST aceita um Idempotency-Key; se você repetir a solicitação, recebe a resposta original e não paga duas vezes.

Enviar um trabalho

Ao enviar um trabalho, você recebe um ID imediatamente (202). priority pode ser standard (mais barato, de minutos a horas) ou fast. Defina dry_run: true para receber uma estimativa grátis com validação de cada item.

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

Status dos itens: queued → fetching → processing → succeeded | failed | canceled.

Trabalhos de contas

“Todos os posts de @handle desde 2025-01-01.” A contagem custa 2¢ a cada 20 posts novos para sua equipe. O valor é reservado antecipadamente e devolvido à medida que você analisa os posts. Depois, o trabalho fica aguardando em awaiting_confirmation, com posts_found, oldest_post_at, reached_since e notices por conta (por exemplo, quando uma plataforma só retorna posts a partir de uma data mais recente). Confirme com POST /jobs/{id}/confirm ou defina options.max_credits para confirmar automaticamente.

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

Envios

Os dados são enviados diretamente para o armazenamento, sem passar pela API. Os arquivos que não forem vinculados a um trabalho em até 24 horas serão excluídos.

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.

Resultados

Um post analisado. Os vetores de embedding só são retornados com ?include=embedding. pacing vem da detecção de cenas (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": "…"
}

Endpoints

EndpointO que faz
POST /api/v1/jobsEnvie URLs, arquivos ou contas (dry_run para receber uma estimativa grátis).
GET /api/v1/jobs/{id}Status, contagem por status, valores (centavos) reservados, cobrados e liberados, contas e avisos.
GET /api/v1/jobs/{id}/itemsItens paginados; filtre com ?status=failed.
POST /api/v1/jobs/{id}/confirmReserva o valor para um trabalho de conta que aguarda confirmação.
POST /api/v1/jobs/{id}/cancelCancela os itens na fila; o valor reservado volta para o saldo.
POST /api/v1/jobs/{id}/retryTenta novamente os itens com falha (com nova estimativa e reserva).
POST /api/v1/uploadsPUT pré-assinado para enviar sua própria mídia.
GET /api/v1/resultsFiltre por job_id, platform, tag, q.
POST /api/v1/results/searchBusca semântica em embeddings.
GET /api/v1/results/exportCSV ou JSONL em fluxo.
GET /api/v1/creditsSaldo (em centavos + balance_usd), valores reservados, pacotes e recompensas por gastos.
DELETE /api/v1/dataExclua todos os dados da sua organização.

Erros

Toda resposta que não seja 2xx usa o mesmo formato. Códigos: 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 } }

Os códigos de falha por item são estáveis e não geram cobrança:

post_not_foundA publicação não existe mais.
post_privateA publicação não é pública.
unsupported_urlEste link não é de uma publicação do TikTok, Instagram ou X.
media_unavailableA plataforma não forneceu o arquivo de mídia.
media_too_largeO arquivo excede o tamanho máximo.
upload_invalidNão foi possível ler o arquivo enviado.
provider_errorFalha no serviço externo. Você pode tentar de novo.
internal_errorFalha nossa. Você pode tentar de novo.

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

Códigos de saída: 0 sucesso, 2 uso incorreto, 3 autenticação, 4 saldo insuficiente, 5 processo concluído com itens com falha, 6 tempo esgotado.

MCP

MCP remoto via HTTP Streamable em /api/mcp, com OAuth (adicione a URL no Claude, ChatGPT ou Cursor e autorize o acesso) ou uma chave de API. Ferramentas: 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_…"
      }
    }
  }
}