API, CLI und MCP
Alles, was du in der App machen kannst, geht auch mit deinem Code und deinen Agents: Links, Uploads oder ganze Konten einreichen, auf die Tags warten und die Ergebnisse lesen. Ein Vertrag mit drei Zugangswegen. Aufträge laufen im Hintergrund, Schreibvorgänge lassen sich ohne doppelte Abbuchung wiederholen und du siehst die Kosten vorher und danach.
Neu bei Garfunkel? So wird ein Post analysiert.
Schnellstart
Erstelle in der App unter Einstellungen → Entwickler einen API-Schlüssel und speichere ihn als GARFUNKEL_API_KEY. Wähle dann deinen Zugangsweg. Bei MCP-Clients kannst du dich statt mit einem Schlüssel auch per OAuth anmelden.
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 jsonlAnmeldung
Sende Authorization: Bearer gma_live_… mit einem API-Schlüssel für deine Organisation aus API-Schlüssel. CLI und MCP lesen GARFUNKEL_API_KEY aus. Jeder POST akzeptiert einen Idempotency-Key. Bei einer Wiederholung erhältst du die ursprüngliche Antwort und zahlst nie doppelt.
Auftrag einreichen
Beim Einreichen erhältst du sofort eine Auftrags-ID (202). priority ist entweder standard (günstiger, dauert Minuten bis Stunden) oder fast. Mit dry_run: true bekommst du eine kostenlose Kostenschätzung mit Prüfung jedes einzelnen Posts.
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 der einzelnen Posts: queued → fetching → processing → succeeded | failed | canceled.
Kontenaufträge
„Jeder Post von @handle seit dem 01.01.2025.“ Das Zählen kostet 2 Cent pro 20 Posts, die für dein Team neu sind. Der Betrag wird im Voraus reserviert und gutgeschrieben, sobald du die Posts analysierst. Danach wartet der Auftrag unter awaiting_confirmation und zeigt pro Konto posts_found, oldest_post_at, reached_since und notices an (zum Beispiel, wenn eine Plattform nur Posts ab einem späteren Datum zurückgibt). Bestätige mit POST /jobs/{id}/confirm oder lege mit options.max_credits eine automatische Bestätigung fest.
{
"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 }
}Uploads
Die Dateien werden direkt in den Speicher hochgeladen, nicht über die API. Uploads, die innerhalb von 24 Stunden keinem Auftrag zugeordnet werden, werden gelöscht.
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.Ergebnisse
Ein analysierter Post. Einbettungsvektoren erhältst du nur mit ?include=embedding. pacing basiert auf der Shot-Erkennung (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": "…"
}Endpunkte
| Endpunkt | Funktion |
|---|---|
| POST /api/v1/jobs | URLs, Uploads oder Konten einreichen (dry_run für eine kostenlose Kostenschätzung). |
| GET /api/v1/jobs/{id} | Status, Anzahl je Status, zurückgelegte / abgebuchte / freigegebene Beträge (Cent), Konten und Hinweise. |
| GET /api/v1/jobs/{id}/items | Einträge mit Seitenumbruch; filtern mit ?status=failed. |
| POST /api/v1/jobs/{id}/confirm | Den Preis für einen Kontoauftrag zur Bestätigung zurücklegen. |
| POST /api/v1/jobs/{id}/cancel | Wartende Posts abbrechen; der zurückgelegte Betrag geht zurück aufs Guthaben. |
| POST /api/v1/jobs/{id}/retry | Fehlgeschlagene Posts erneut versuchen (neu geschätzt und reserviert). |
| POST /api/v1/uploads | Signierter PUT-Upload für deine eigenen Medien. |
| GET /api/v1/results | Filtern mit job_id, platform, tag, q. |
| POST /api/v1/results/search | Semantische Suche in Einbettungen. |
| GET /api/v1/results/export | CSV oder JSONL als Stream. |
| GET /api/v1/credits | Guthaben (Cent + balance_usd), reservierter Betrag, Pakete und Ausgabenboni. |
| DELETE /api/v1/data | Lösche alle Daten deiner Organisation. |
Fehler
Alle Fehler mit einem Statuscode außerhalb von 2xx haben dasselbe Format. Codes: 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 } }Fehlercodes für einzelne Posts sind festgelegt und kosten nichts:
| post_not_found | Der Post existiert nicht (mehr). |
| post_private | Der Post ist nicht öffentlich. |
| unsupported_url | Kein Link zu einem TikTok-, Instagram- oder X-Post. |
| media_unavailable | Die Plattform hat die Mediendatei nicht bereitgestellt. |
| media_too_large | Die Datei überschreitet die zulässige Größe. |
| upload_invalid | Die hochgeladene Datei ließ sich nicht lesen. |
| provider_error | Fehler beim Anbieter – du kannst es erneut versuchen. |
| internal_error | Bei uns ist ein Fehler aufgetreten – du kannst es erneut versuchen. |
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 50000Exitcodes: 0 erfolgreich, 2 falsche Verwendung, 3 Anmeldung, 4 Guthaben reicht nicht aus, 5 abgeschlossen, aber einzelne Posts sind fehlgeschlagen, 6 Zeitüberschreitung.
MCP
Remote-MCP über Streamable HTTP unter /api/mcp mit OAuth (füge die URL in Claude, ChatGPT oder Cursor ein und bestätige den Zugriff) oder mit einem API-Schlüssel. Funktionen: 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_…"
}
}
}
}