API, CLI e MCP
Tutto quello che fai nell’app puoi farlo anche con il tuo codice e i tuoi agenti: inviare link, file o interi account, attendere le etichette e consultare i risultati. Un’unica interfaccia, tre modi per accedervi. Le attività vengono elaborate in modo asincrono, le richieste ripetute non creano duplicati e puoi vedere il costo prima e dopo.
Non conosci ancora Garfunkel? Scopri come analizziamo un post.
Guida rapida
Crea una chiave API nell’app, in Impostazioni → Sviluppatori, impostala come GARFUNKEL_API_KEY e scegli come accedere. I client MCP possono anche accedere con OAuth invece che con una chiave.
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 jsonlAutenticazione
Invia Authorization: Bearer gma_live_…, una chiave API associata all’organizzazione, disponibile in Chiavi API. La CLI e MCP leggono GARFUNKEL_API_KEY. Ogni POST accetta un Idempotency-Key: se ripeti una richiesta, ricevi la risposta originale e non ti viene addebitato due volte.
Invia un’attività
L’invio restituisce subito l’ID dell’attività (202). priority può essere standard (più economica, richiede da alcuni minuti a qualche ora) oppure fast. Imposta dry_run: true per ricevere una stima gratuita con la convalida di ogni elemento.
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
}'Stati degli elementi: queued → fetching → processing → succeeded | failed | canceled.
Attività sugli account
“Tutti i post di @handle dal 2025-01-01.” Il conteggio costa 2¢ ogni 20 post nuovi per il tuo team. L’importo viene trattenuto subito e riaccreditato man mano che li analizzi; poi il job resta in awaiting_confirmation con, per ogni account, posts_found, oldest_post_at, reached_since e notices (per esempio, se una piattaforma restituisce solo i post a partire da una data successiva). Conferma con POST /jobs/{id}/confirm oppure imposta options.max_credits per confermare 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 }
}Caricamenti
I file vengono inviati direttamente allo spazio di archiviazione, senza passare dall’API. I caricamenti non associati a un’attività entro 24 ore vengono eliminati.
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.Risultati
Un post analizzato. I vettori di embedding vengono restituiti solo se specifichi ?include=embedding. pacing deriva dal rilevamento delle inquadrature (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": "…"
}Endpoint
| Endpoint | Descrizione |
|---|---|
| POST /api/v1/jobs | Invia URL, file o account (dry_run per una stima gratuita). |
| GET /api/v1/jobs/{id} | Stato, conteggi per stato, importi (in centesimi) accantonati, addebitati e restituiti, account e avvisi. |
| GET /api/v1/jobs/{id}/items | Elementi paginati; filtra con ?status=failed. |
| POST /api/v1/jobs/{id}/confirm | Accantona l’importo per un’attività sugli account in attesa di conferma. |
| POST /api/v1/jobs/{id}/cancel | Annulla gli elementi in coda; l’importo accantonato torna al saldo. |
| POST /api/v1/jobs/{id}/retry | Riprova gli elementi non riusciti (nuova stima e nuovo accantonamento). |
| POST /api/v1/uploads | PUT con URL firmato per i tuoi contenuti multimediali. |
| GET /api/v1/results | Filtra con job_id, platform, tag, q. |
| POST /api/v1/results/search | Ricerca semantica sugli embedding. |
| GET /api/v1/results/export | CSV o JSONL in streaming. |
| GET /api/v1/credits | Saldo (centesimi + balance_usd), importi riservati, ricariche, premi per la spesa. |
| DELETE /api/v1/data | Elimina tutti i dati della tua organizzazione. |
Errori
Tutte le risposte non 2xx usano lo stesso formato. Codici: 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 } }I codici degli errori dei singoli elementi sono stabili e non comportano addebiti:
| post_not_found | Il post non esiste (più). |
| post_private | Il post non è pubblico. |
| unsupported_url | L’URL non rimanda a un post di TikTok, Instagram o X. |
| media_unavailable | La piattaforma non ha restituito il contenuto multimediale. |
| media_too_large | Il file supera il limite di dimensione. |
| upload_invalid | Non è stato possibile leggere il file caricato. |
| provider_error | Errore del servizio esterno: puoi riprovare. |
| internal_error | Si è verificato un errore: puoi riprovare. |
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 50000Codici di uscita: 0 ok, 2 uso, 3 autenticazione, 4 saldo insufficiente, 5 completato con elementi non riusciti, 6 timeout.
MCP
MCP remoto su HTTP Streamable all’indirizzo /api/mcp con OAuth (aggiungi l’URL a Claude, ChatGPT o Cursor e approva l’accesso) oppure con una chiave API. Strumenti: 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_…"
}
}
}
}