Resumen
Este pipeline ejecuta una auditoria real de hooks sobre cualquier handle de TikTok. Resuelve el username a un sec_uid, saca los ultimos 20 posts y compara el play_count de cada video con la mediana del propio creador, asi que ves que posts superan su base y cuales caen por debajo. Despues lee la primera linea de la descripcion de cada post y trae los comentarios destacados del mejor video, para que conectes un hook concreto con el alcance que logro. Un aviso honesto de entrada: la API publica no expone la retencion por segundo, asi que no puedes dibujar una curva real de caida a los 3 segundos. Lo que obtienes son proxies solidos de alcance, play_count frente a la mediana mas ratios de comentarios y compartidos, que es justo lo que la mayoria de auditorias gratis miran a ojo de todas formas.
Desencadenador
Bajo demanda por @handle, o semanal para los handles que sigues.
Programación
Semanal, o bajo demanda por handle
Pasos del flujo de trabajo
Resolver el handle a un sec_uid
POST /api/v1/tiktok/profile con el username. Lee data.user.sec_uid, follower_count y video_count. El sec_uid es el id estable que necesitan las llamadas siguientes.
Sacar los ultimos 20 posts
POST /api/v1/tiktok/user/posts con sec_user_id y count 20. Cada post devuelve play_count, digg_count, comment_count, share_count y la descripcion con la linea del hook.
Calcular la mediana de play_count del creador
Toma la mediana del play_count de los posts. Mediana, no media, para que un pico viral no infle la base y etiquete como flops los posts normales.
Marcar los que superan o no la mediana
Marca cada post por encima o por debajo de su mediana. Los de arriba son tus hooks ganadores, los de abajo los que hay que reescribir. Ordena por play_count para hallar el mejor y el peor.
Leer comentarios del mejor post
POST /api/v1/tiktok/video/comments con el video_id del top y count 30. Los comentarios mas votados por digg_count dicen que provoco el hook ganador en la audiencia.
Mostrar el informe de hooks
Imprime la primera linea de cada post junto a su play_count y su marca, luego la mediana y los comentarios del ganador. Esa es la auditoria, proxies de alcance y los hooks que los lograron.
Implementacion en Python
import requests
import statistics
API_KEY = "your_scavio_api_key"
BASE = "https://api.scavio.dev"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def post(path, body):
r = requests.post(f"{BASE}{path}", json=body, headers=HEADERS, timeout=60)
r.raise_for_status()
return r.json()
def hook_line(description):
text = (description or "").strip().replace("\n", " ")
return text[:80] if text else "(no caption)"
def audit(username):
profile = post("/api/v1/tiktok/profile", {"username": username})
user = profile["data"]["user"]
sec_uid = user["sec_uid"]
print(f"@{username} followers={user.get('follower_count')} videos={user.get('video_count')}")
posts = post("/api/v1/tiktok/user/posts", {"sec_user_id": sec_uid, "count": 20})
items = posts.get("posts", [])
if not items:
print("no posts found")
return
plays = [p["statistics"]["play_count"] for p in items]
median = statistics.median(plays)
print(f"median play_count over {len(items)} posts = {median:.0f}\n")
ranked = sorted(items, key=lambda p: p["statistics"]["play_count"], reverse=True)
for p in ranked:
plays_n = p["statistics"]["play_count"]
flag = "OVER " if plays_n >= median else "under"
print(f"[{flag}] {plays_n:>9} {hook_line(p.get('description'))}")
best = ranked[0]
print(f"\nbest post: {best['statistics']['play_count']} plays")
print(f"hook: {hook_line(best.get('description'))}")
comments = post("/api/v1/tiktok/video/comments", {"video_id": best["video_id"], "count": 30})
top = sorted(comments.get("comments", []), key=lambda c: c.get("digg_count", 0), reverse=True)[:5]
print("top comments on the winning hook:")
for c in top:
print(f" {c.get('digg_count', 0):>5} likes {c.get('text', '')[:80]}")
if __name__ == "__main__":
audit("somecreator")
Implementacion en JavaScript
const API_KEY = "your_scavio_api_key";
const BASE = "https://api.scavio.dev";
const HEADERS = { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" };
async function post(path, body) {
const res = await fetch(`${BASE}${path}`, { method: "POST", headers: HEADERS, body: JSON.stringify(body) });
if (!res.ok) throw new Error(`${path} -> ${res.status}`);
return res.json();
}
function median(nums) {
const s = [...nums].sort((a, b) => a - b);
const m = Math.floor(s.length / 2);
return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
}
function hookLine(description) {
const text = (description || "").trim().replace(/\n/g, " ");
return text ? text.slice(0, 80) : "(no caption)";
}
async function audit(username) {
const profile = await post("/api/v1/tiktok/profile", { username });
const user = profile.data.user;
const secUid = user.sec_uid;
console.log(`@${username} followers=${user.follower_count} videos=${user.video_count}`);
const posts = await post("/api/v1/tiktok/user/posts", { sec_user_id: secUid, count: 20 });
const items = posts.posts || [];
if (items.length === 0) {
console.log("no posts found");
return;
}
const med = median(items.map((p) => p.statistics.play_count));
console.log(`median play_count over ${items.length} posts = ${med}\n`);
const ranked = [...items].sort((a, b) => b.statistics.play_count - a.statistics.play_count);
for (const p of ranked) {
const plays = p.statistics.play_count;
const flag = plays >= med ? "OVER " : "under";
console.log(`[${flag}] ${String(plays).padStart(9)} ${hookLine(p.description)}`);
}
const best = ranked[0];
console.log(`\nbest post: ${best.statistics.play_count} plays`);
console.log(`hook: ${hookLine(best.description)}`);
const comments = await post("/api/v1/tiktok/video/comments", { video_id: best.video_id, count: 30 });
const top = (comments.comments || []).sort((a, b) => (b.digg_count || 0) - (a.digg_count || 0)).slice(0, 5);
console.log("top comments on the winning hook:");
for (const c of top) {
console.log(` ${String(c.digg_count || 0).padStart(5)} likes ${(c.text || "").slice(0, 80)}`);
}
}
audit("somecreator").catch(console.error);