Curva de retenção e pitch
Onde os espectadores saem do vídeo, quantos chegam ao pitch e onde clicam e compram
Três perguntas moldam um vídeo de vendas: onde as pessoas param de assistir, quantas ainda estão lá quando o pitch começa e em que momento elas clicam e compram. Cada uma tem a sua consulta, e juntas elas desenham o vídeo segundo a segundo.
Você precisa do ID do player, da duração do vídeo e do tempo de pitch. O GET /players/list devolve os três (id, duration, pitch_time).
Curva de retenção
O POST /times/user_engagement devolve onde cada visualização terminou:
curl -X POST 'https://analytics.vturb.com/times/user_engagement' \
-H "X-Api-Token: $VTURB_API_TOKEN" \
-H 'X-Api-Version: v1' \
-H 'User-Agent: minha-integracao/1.0' \
-H 'Content-Type: application/json' \
-d '{
"player_id": "64a5c8072e6fd10009828db2",
"video_duration": 2340,
"start_date": "2026-09-01 00:00:00",
"end_date": "2026-09-07 23:59:59",
"timezone": "America/Sao_Paulo"
}'video_duration, a duração do vídeo em segundos, é obrigatório aqui, assim como as duas datas. Envie a duração real, o duration do GET /players/list: uma sessão cujo ponto mais distante passa mais de 60 segundos de video_duration fica de fora.
{
"grouped_timed": [
{ "timed": 0, "total_users": 412 },
{ "timed": 5, "total_users": 96 },
{ "timed": 10, "total_users": 58 }
],
"average_watched_time": 900.9,
"engagement_rate": 38.5
}- Cada item de
grouped_timedconta as sessões cujo ponto mais avançado no vídeo foi exatamente aquele segundo (timed): onde elas pararam. Os segundos em que ninguém parou ficam de fora. - O player informa até onde cada espectador chegou em passos de cinco segundos, por isso
timedvem em múltiplos de 5. average_watched_timeé até onde uma sessão chegou, em média, em segundos.engagement_rateé essa média em proporção avideo_duration:average_watched_time ÷ video_duration × 100.
A curva é o número de sessões que chegaram a cada segundo: todas as que pararam naquele segundo ou depois. Some os itens a partir do fim:
function retentionCurve(groupedTimed, videoDuration) {
const stoppedAt = new Map(groupedTimed.map(({ timed, total_users }) => [timed, total_users]));
const total = groupedTimed.reduce((sum, { total_users }) => sum + total_users, 0);
const curve = [];
let reached = total;
for (let second = 0; second <= videoDuration; second++) {
curve.push({ second, reached, percent: total ? (reached / total) * 100 : 0 });
reached -= stoppedAt.get(second) ?? 0;
}
return curve;
}Uma queda acentuada nos primeiros segundos aponta para a abertura; uma queda logo antes do pitch, para a construção que leva até ele.
Pitch retention
O número de sessões que chegaram ao pitch vem pronto no POST /sessions/stats:
curl -X POST 'https://analytics.vturb.com/sessions/stats' \
-H "X-Api-Token: $VTURB_API_TOKEN" \
-H 'X-Api-Version: v1' \
-H 'User-Agent: minha-integracao/1.0' \
-H 'Content-Type: application/json' \
-d '{
"player_id": "64a5c8072e6fd10009828db2",
"start_date": "2026-09-01 00:00:00",
"end_date": "2026-09-07 23:59:59",
"timezone": "America/Sao_Paulo"
}'Na resposta, total_over_pitch conta as sessões que chegaram a pitch_time, total_under_pitch as que saíram antes dele, e over_pitch_rate é a parcela que chegou a ele. Sem pitch_time no corpo, ou com 0, a API usa o configurado no player; envie-o, em segundos, para testar outro momento, como um pitch que você está prestes a mudar de lugar. Quando o player não tem tempo de pitch e você não envia um, o pitch é o segundo 0: toda sessão chega a ele, e over_pitch_rate é 100. Os outros campos são os mesmos do relatório diário.
Onde compram
O POST /conversions/video_timed posiciona cada venda no segundo do vídeo em que o espectador clicou para comprar:
curl -X POST 'https://analytics.vturb.com/conversions/video_timed' \
-H "X-Api-Token: $VTURB_API_TOKEN" \
-H 'X-Api-Version: v1' \
-H 'User-Agent: minha-integracao/1.0' \
-H 'Content-Type: application/json' \
-d '{
"player_id": "64a5c8072e6fd10009828db2",
"start_date": "2026-09-01 00:00:00",
"end_date": "2026-09-07 23:59:59",
"timezone": "America/Sao_Paulo",
"pitch_time": 1260
}'[
{
"timed": 1260,
"timed_conversions": 9,
"cumulative_conversions": 9,
"timed_amount_usd": 0,
"cumulative_amount_usd": 0,
"timed_amount_brl": 179100,
"cumulative_amount_brl": 179100,
"timed_amount_eur": 0,
"cumulative_amount_eur": 0
},
{
"timed": 1305,
"timed_conversions": 4,
"cumulative_conversions": 13,
"timed_amount_usd": 0,
"cumulative_amount_usd": 0,
"timed_amount_brl": 79600,
"cumulative_amount_brl": 258700,
"timed_amount_eur": 0,
"cumulative_amount_eur": 0
}
]timed_conversionsconta as sessões com uma venda inicial cujo clique aconteceu emtimed;cumulative_conversionsas soma até aquele segundo.timed_amount_*soma, por moeda e como um inteiro em centavos, os valores de todas as compras clicadas naquele segundo, order bumps incluídos;cumulative_amount_*os soma até aquele segundo.start_dateeend_dateselecionam as vendas pelo momento do clique.- Com
pitch_time, uma venda cujo clique veio antes do pitch é contada no segundo do pitch, por isso a primeira linha reúne tudo até o pitch. Deixe-o de fora para ver cada clique no seu próprio segundo.
Onde clicam
O POST /clicks/total_by_company_timed recebe o player, as datas e timezone, e devolve os cliques nas chamadas para ação do player em cada segundo:
[
{ "timed": 1260, "total_users": 31 },
{ "timed": 1261, "total_users": 12 }
]total_users é o número de cliques registrados naquele segundo.
Junte tudo
Plote a curva de retenção, marque pitch_time nela e sobreponha os cliques e as vendas nos mesmos segundos. A diferença entre os cliques e as vendas depois do pitch mostra quanto do interesse o checkout transforma em vendas.
A seguir: descubra quais origens de tráfego trazem os espectadores que ficam.