Documentação da API do OnBriefing

Tudo para integrar a verificação de vídeos de influenciadores ao seu sistema: do primeiro curl ao webhook em produção.

API v1 · atualizada em 09/10/2026

Visão geral

A API do OnBriefing verifica se vídeos publicados por creators no TikTok, Instagram e YouTube cumprem o briefing de uma campanha. Você cria a campanha com o briefing, envia as URLs dos vídeos e recebe um laudo por vídeo, com um veredito e uma linha por regra, cada uma com evidência.

Base URL
https://onbriefing.com/api/v1
  • Corpo das requisições e respostas em JSON (Content-Type: application/json), UTF-8.
  • Datas em ISO 8601, UTC, por exemplo 2026-10-09T14:30:00.000Z.
  • IDs são strings opacas. Não presuma formato nem tamanho.
  • Campos novos podem ser adicionados às respostas a qualquer momento; ignore os que não conhecer.
  • A análise é assíncrona: o envio responde na hora, o laudo fica pronto em minutos.

Autenticação

Toda chamada exige uma chave de API no header Authorization, no formato Bearer. As chaves começam com obk_.

Authorization: Bearer obk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Como obter uma chave

  • Crie uma conta em onbriefing.com/cadastro (10 vídeos grátis, sem cartão) ou entre na sua. Toda conta pode gerar chaves de API.
  • No painel, abra Configurações → Chaves de API → Gerar chave e dê um nome (por exemplo, integração-produção).
  • Copie o valor na hora: ele aparece uma única vez. O OnBriefing guarda só um hash da chave e não consegue mostrá-la de novo.

Escopo e segurança

  • A chave pertence à organização e dá acesso a todas as campanhas e verificações dela.
  • Recursos de outra organização respondem 404, como se não existissem.
  • Guarde a chave como segredo do servidor (variável de ambiente ou cofre). Nunca a use em código que roda no navegador ou no app do usuário.
  • Uma chave revogada no painel para de funcionar imediatamente. Para trocar sem downtime, gere a nova, faça o deploy e só então revogue a antiga.

Início rápido

Do zero ao primeiro laudo em três chamadas.

1. Crie a campanha

curl
curl -X POST https://onbriefing.com/api/v1/campaigns \
  -H "Authorization: Bearer $ONBRIEFING_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Verão 2026: lançamento",
    "brand": "Marca X",
    "rulesText": "O vídeo deve ter no mínimo 30s, mostrar o produto em uso, citar o cupom VERAO26 na fala e usar #MarcaXVerao e #publi na legenda. Não pode citar concorrentes."
  }'

Guarde o id da resposta.

2. Envie os vídeos

curl
curl -X POST https://onbriefing.com/api/v1/campaigns/$CAMPAIGN_ID/verifications \
  -H "Authorization: Bearer $ONBRIEFING_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "urls": ["https://www.tiktok.com/@creator/video/7300000000000000001"] }'

Cada URL com status: "queued" traz o id da verificação.

3. Busque o laudo

curl
curl https://onbriefing.com/api/v1/verifications/$VERIFICATION_ID \
  -H "Authorization: Bearer $ONBRIEFING_KEY"

Quando status for COMPLETED, o laudo está em verdict, summary e findings. Em produção, troque a consulta pelo webhook.

Exemplo completo em Node.js

node (18+)
const BASE = "https://onbriefing.com/api/v1";
const headers = {
  Authorization: `Bearer ${process.env.ONBRIEFING_KEY}`,
  "Content-Type": "application/json",
};

async function api(path, init = {}) {
  const res = await fetch(BASE + path, { ...init, headers });
  const body = await res.json();
  if (!res.ok) throw new Error(`${res.status}: ${body.error}`);
  return body;
}

const campaign = await api("/campaigns", {
  method: "POST",
  body: JSON.stringify({ name: "Pilot", brand: "Brand X", rulesText: BRIEF }),
});

const { outcomes } = await api(`/campaigns/${campaign.id}/verifications`, {
  method: "POST",
  body: JSON.stringify({ urls: VIDEO_URLS }),
});

const ids = outcomes.filter((o) => o.status === "queued").map((o) => o.id);

async function waitFor(id) {
  for (;;) {
    const v = await api(`/verifications/${id}`);
    if (v.status === "COMPLETED" || v.status === "FAILED") return v;
    await new Promise((r) => setTimeout(r, 30_000));
  }
}

const reports = await Promise.all(ids.map(waitFor));

Exemplo em Python

python 3 + requests
import os, time, requests

BASE = "https://onbriefing.com/api/v1"
s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['ONBRIEFING_KEY']}"

campaign = s.post(f"{BASE}/campaigns", json={
    "name": "Pilot", "brand": "Brand X", "rulesText": BRIEF,
}).json()

outcomes = s.post(f"{BASE}/campaigns/{campaign['id']}/verifications",
                  json={"urls": VIDEO_URLS}).json()["outcomes"]

for o in outcomes:
    if o["status"] != "queued":
        continue
    while True:
        v = s.get(f"{BASE}/verifications/{o['id']}").json()
        if v["status"] in ("COMPLETED", "FAILED"):
            print(v["videoUrl"], v["status"], v["verdict"])
            break
        time.sleep(30)

Conceitos

CampoTipoDescrição
CampanhaCampaignNome, marca e o briefing (rulesText). Agrupa as verificações.
BriefingrulesTextO texto que você já manda aos creators, em linguagem livre. O OnBriefing separa as regras sozinho e marca as que não dá para conferir por vídeo.
VerificaçãoVerificationA análise de uma URL de vídeo dentro de uma campanha.
Laudoverdict + findingsO resultado: veredito geral, resumo e uma linha por regra, com evidência.
AchadoFindingO resultado de uma regra: status, severidade, justificativa, confiança e evidências.

O briefing é congelado no envio

Cada verificação guarda o briefing que valia no momento em que a URL foi enviada. Editar a campanha depois afeta só os próximos envios; laudos já emitidos continuam explicáveis contra a régua original.

Ciclo de vida de uma verificação

QUEUED → DOWNLOADING → TRANSCRIBING → ANALYZING → COMPLETED
                                                     ↘ FAILED

COMPLETED e FAILED são estados finais. Quando a plataforma de vídeo limita o acesso temporariamente, a verificação espera e tenta de novo sozinha, e pode ficar alguns minutos a mais em QUEUED ou DOWNLOADING.

Criar campanha

POST/campaigns

Corpo

CampoTipoDescrição
namestringObrigatório. Nome da campanha; não pode ser vazio.
brandstring | nullOpcional. Marca anunciante.
rulesTextstringObrigatório. Briefing em texto livre, com pelo menos 20 caracteres.
Requisição
POST /api/v1/campaigns
{
  "name": "Verão 2026: lançamento",
  "brand": "Marca X",
  "rulesText": "O vídeo deve ter no mínimo 30s, mostrar o produto em uso e citar o cupom VERAO26."
}
Resposta 201
{
  "id": "cm8x1a2b3c4d5e6f7g8h9i0j",
  "orgId": "cm7o...",
  "name": "Verão 2026: lançamento",
  "brand": "Marca X",
  "rulesText": "O vídeo deve ter no mínimo 30s, mostrar o produto em uso e citar o cupom VERAO26.",
  "active": true,
  "archivedAt": null,
  "hasWebhook": false,
  "webhookUrl": null,
  "createdAt": "2026-10-09T14:00:00.000Z",
  "updatedAt": "2026-10-09T14:00:00.000Z"
}

Erros: 400 se o corpo não for JSON ou faltar campo; 422 se name for vazio ou rulesText tiver menos de 20 caracteres. O campo com problema vem em field.

Ler campanha

GET/campaigns/:id

Devolve o mesmo objeto da criação, mais verificationCount , o total de vídeos já enviados para a campanha. O webhookSecret nunca aparece aqui.

Resposta 200 (trecho)
{
  "id": "cm8x1a2b3c4d5e6f7g8h9i0j",
  "name": "Verão 2026: lançamento",
  "hasWebhook": true,
  "webhookUrl": "https://seu-sistema.com/webhooks/onbriefing",
  "verificationCount": 128,
  ...
}

Atualizar campanha

PATCH/campaigns/:id

Envie só os campos que quer mudar.

CampoTipoDescrição
namestringNovo nome; não pode ser vazio.
brandstring | nullNova marca; null remove.
rulesTextstringNovo briefing, com pelo menos 20 caracteres. Vale para os próximos envios.
webhookUrlstring | nullURL que recebe os laudos. null remove o webhook e o segredo.

O segredo do webhook aparece uma vez

Ao definir webhookUrl numa campanha que ainda não tinha webhook, a resposta traz um campo webhookSecret. Guarde-o nessa hora : ele assina todos os webhooks e não volta em nenhuma leitura.

Requisição
PATCH /api/v1/campaigns/cm8x1a2b3c4d5e6f7g8h9i0j
{ "webhookUrl": "https://seu-sistema.com/webhooks/onbriefing" }
Resposta 200 (trecho)
{
  "id": "cm8x1a2b3c4d5e6f7g8h9i0j",
  "hasWebhook": true,
  "webhookUrl": "https://seu-sistema.com/webhooks/onbriefing",
  "webhookSecret": "9f2c6b1e...64 caracteres hex"
}
  • Trocar a URL de um webhook que já existe mantém o mesmo segredo.
  • Para gerar um segredo novo, mande { "webhookUrl": null } e depois configure a URL de novo.

Enviar vídeos

POST/campaigns/:id/verifications
CampoTipoDescrição
urlsstring[]De 1 a 500 URLs de vídeos publicados no TikTok, Instagram ou YouTube.
Requisição
POST /api/v1/campaigns/cm8x1a2b3c4d5e6f7g8h9i0j/verifications
{
  "urls": [
    "https://www.tiktok.com/@creator1/video/7300000000000000001",
    "https://www.instagram.com/reel/ABC123/",
    "https://www.youtube.com/shorts/dQw4w9WgXcQ",
    "https://example.com/video"
  ]
}

A resposta vem linha a linha, na ordem do envio. Uma URL com problema não derruba as outras.

Resposta 200
{
  "outcomes": [
    { "url": "https://www.tiktok.com/@creator1/video/7300000000000000001", "status": "queued", "id": "cm8x9z..." },
    { "url": "https://www.instagram.com/reel/ABC123/", "status": "duplicate" },
    { "url": "https://www.youtube.com/shorts/dQw4w9WgXcQ", "status": "insufficient_credits", "detail": "..." },
    { "url": "https://example.com/video", "status": "invalid", "detail": "Host não permitido: example.com. Aceitos: TikTok, Instagram e YouTube." }
  ]
}
CampoTipoDescrição
queuedstatusEntrou na fila. Guarde o id da verificação.
duplicatestatusEssa URL já foi enviada para esta campanha. Nada é cobrado; consulte a verificação existente.
invalidstatusURL malformada ou de plataforma não suportada. detail explica.
insufficient_creditsstatusA organização não tem créditos para nem um minuto de vídeo. detail mostra quantos créditos restam.

Quais URLs são aceitas

  • Só https, sem porta e sem usuário/senha na URL.
  • Hosts: tiktok.com, www.tiktok.com, m.tiktok.com, vm.tiktok.com, vt.tiktok.com, instagram.com, www.instagram.com, youtube.com, www.youtube.com, m.youtube.com e youtu.be.
  • A URL é normalizada: query string e # são descartados (exceto o v do YouTube). A URL devolvida em outcomes[].url é a normalizada, e é ela que identifica o vídeo na campanha.
  • URLs repetidas dentro do mesmo envio contam uma vez só.
  • O vídeo precisa ser público. Vídeo privado ou que exige login falha com AUTH_REQUIRED.

Listar verificações

GET/campaigns/:id/verifications?status=&cursor=
CampoTipoDescrição
statusquery, opcionalFiltra por estado: QUEUED, DOWNLOADING, TRANSCRIBING, ANALYZING, COMPLETED ou FAILED.
cursorquery, opcionalO nextCursor da página anterior.

Páginas de 50 itens, das verificações mais recentes para as mais antigas. nextCursor é null na última página. Os itens trazem o resumo; para os achados, use Consultar verificação.

Resposta 200
{
  "items": [
    {
      "id": "cm8x9z...",
      "videoUrl": "https://www.tiktok.com/@creator1/video/7300000000000000001",
      "platform": "TIKTOK",
      "status": "COMPLETED",
      "verdict": "APPROVED",
      "finalVerdict": null,
      "errorCode": null,
      "createdAt": "2026-10-09T14:01:00.000Z",
      "completedAt": "2026-10-09T14:04:12.000Z"
    }
  ],
  "nextCursor": "cm8x9y..."
}
Percorrer todas as páginas (Node)
let cursor = null;
do {
  const qs = new URLSearchParams({ status: "COMPLETED", ...(cursor ? { cursor } : {}) });
  const page = await api(`/campaigns/${campaignId}/verifications?${qs}`);
  for (const item of page.items) handle(item);
  cursor = page.nextCursor;
} while (cursor);

Consultar verificação

GET/verifications/:id

Devolve a verificação completa, com o laudo e as evidências de cada regra.

Resposta 200
{
  "id": "cm8x9z...",
  "campaignId": "cm8x1a2b3c4d5e6f7g8h9i0j",
  "videoUrl": "https://www.tiktok.com/@creator1/video/7300000000000000001",
  "platform": "TIKTOK",
  "status": "COMPLETED",
  "verdict": "REJECTED",
  "finalVerdict": null,
  "summary": "Mostra o produto e usa a hashtag, mas não cita o cupom e dura 22s.",
  "contentCategories": ["REVIEW", "DEPOIMENTO"],
  "errorCode": null,
  "error": null,
  "createdAt": "2026-10-09T14:01:00.000Z",
  "startedAt": "2026-10-09T14:01:05.000Z",
  "completedAt": "2026-10-09T14:04:12.000Z",
  "findings": [
    {
      "ruleText": "Citar o cupom VERAO26 na fala",
      "scope": "VERIFIABLE",
      "status": "FAIL",
      "severity": "MAJOR",
      "rationale": "O cupom não aparece na transcrição nem no texto da tela.",
      "confidence": 0.86,
      "evidence": [
        { "type": "ABSENT", "note": "Transcrição completa e texto da tela; nenhuma menção a VERAO26.",
          "frameIndex": null, "timestampMs": null, "quote": null, "field": null, "value": null }
      ]
    },
    {
      "ruleText": "Usar #MarcaXVerao na legenda",
      "scope": "VERIFIABLE",
      "status": "PASS",
      "severity": "MAJOR",
      "rationale": "A hashtag está na legenda.",
      "confidence": 0.97,
      "evidence": [
        { "type": "METADATA", "field": "hashtags", "value": "marcaxverao, publi",
          "frameIndex": null, "timestampMs": null, "quote": null, "note": null }
      ]
    }
  ]
}

Enquanto a análise não termina, verdict, summary e completedAt vêm null e findings vem vazio.

O laudo

Verificação

CampoTipoDescrição
statusenumQUEUED · DOWNLOADING · TRANSCRIBING · ANALYZING · COMPLETED · FAILED
platformenumTIKTOK · INSTAGRAM · YOUTUBE
verdictenum | nullVeredito automático: APPROVED (on briefing), REJECTED (off briefing) ou INCONCLUSIVE (a evidência não basta e precisa de revisão humana).
finalVerdictenum | nullVeredito depois de revisão humana no painel. null até alguém revisar. Quando preenchido, é a palavra final.
summarystring | nullResumo do laudo em português.
contentCategoriesstring[]Até 3 categorias de formato do vídeo, da mais para a menos relevante. Vazio quando não categorizado.
errorCodestring | nullSó em FAILED. Veja Erros.
errorstring | nullSó em FAILED. Mensagem legível sobre a falha.

Achado (finding)

CampoTipoDescrição
ruleTextstringA regra, como o OnBriefing a extraiu do briefing.
scopeenumVERIFIABLE: dá para conferir no vídeo. OUT_OF_SCOPE: depende de dado externo (impulsionamento, data de publicação, permanência do post) e vem sempre com status: UNVERIFIABLE.
statusenumPASS · FAIL · UNVERIFIABLE
severityenumBLOCKER (proibição ou exigência legal), MAJOR (entrega central) ou MINOR (detalhe). É o peso da regra e vale mesmo quando ela passou.
rationalestringPor que a regra passou, falhou ou não pôde ser verificada.
confidencenumberDe 0 a 1.
evidenceEvidence[]Uma ou mais evidências que sustentam o resultado.

Evidência

Todo objeto de evidência tem os mesmos campos; os que não se aplicam ao type vêm null.

CampoTipoDescrição
FRAMEtypeAlgo visto num frame. Usa frameIndex, timestampMs e note (o que se vê).
TRANSCRIPTtypeAlgo dito. Usa timestampMs e quote (trecho literal da fala).
SCREEN_TEXTtypeTexto sobreposto ao vídeo. Usa timestampMs e quote.
METADATAtypeCampo do post. Usa field (caption, hashtags, mentions, durationMs, author, dimensions) e value.
SOURCE_MATCHtypeTrecho que casa com o material oficial da campanha. Usa note.
ABSENTtypeO resultado se apoia numa ausência. note diz onde se procurou.

Categorias de conteúdo

Valores possíveis de contentCategories. A lista pode crescer; trate um código desconhecido como OUTRO.

CampoTipoDescrição
MEMEcategoriaMeme / humor
CASALcategoriaCasal
ESQUETEcategoriaEsquete / encenação
TRENDcategoriaTrend / dança
REVIEWcategoriaReview / unboxing
TUTORIALcategoriaTutorial / dica
RECEITAcategoriaReceita / culinária
BELEZA_MODAcategoriaBeleza / moda
VLOGcategoriaVlog / rotina
DEPOIMENTOcategoriaDepoimento / opinião
REACTcategoriaReact / comentário
CORTEcategoriaCorte de live / podcast
GAMEPLAYcategoriaGameplay
OUTROcategoriaOutro

Como usar o veredito

  • Use verdict para triagem automática: APPROVED segue, REJECTED volta para o creator com os achados FAIL, INCONCLUSIVE vai para revisão humana.
  • Se finalVerdict estiver preenchido, ele prevalece sobre verdict.
  • Para o feedback ao creator, mostre ruleText e rationale dos achados com status: FAIL, ordenando por severity.

Webhooks

Com webhookUrl configurado na campanha, o OnBriefing faz um POST para essa URL sempre que uma verificação chega a um estado final.

CampoTipoDescrição
verification.completedeventoA análise terminou e o laudo está pronto.
verification.failedeventoA análise falhou. Veja errorCode. O crédito já foi devolvido.

Requisição

POST https://seu-sistema.com/webhooks/onbriefing
Content-Type: application/json
X-OnBriefing-Event: verification.completed
X-OnBriefing-Signature: sha256=5d41402abc4b2a76b9719d911017c592...

{
  "event": "verification.completed",
  "verification": {
    "id": "cm8x9z...",
    "campaignId": "cm8x1a2b3c4d5e6f7g8h9i0j",
    "videoUrl": "https://www.tiktok.com/@creator1/video/7300000000000000001",
    "platform": "TIKTOK",
    "status": "COMPLETED",
    "verdict": "REJECTED",
    "summary": "Mostra o produto e usa a hashtag, mas não cita o cupom e dura 22s.",
    "contentCategories": ["REVIEW"],
    "errorCode": null,
    "completedAt": "2026-10-09T14:04:12.000Z",
    "findings": [
      { "ruleText": "Citar o cupom VERAO26 na fala", "scope": "VERIFIABLE",
        "status": "FAIL", "severity": "MAJOR",
        "rationale": "O cupom não aparece na transcrição.", "confidence": 0.86 }
    ]
  }
}

O payload do webhook é enxuto: os achados vêm sem evidence. Para as evidências (frames, falas, metadados), chame GET /verifications/:id.

Validar a assinatura

X-OnBriefing-Signature é o HMAC-SHA256, em hexadecimal, do corpo bruto da requisição, assinado com o webhookSecret da campanha. Calcule sobre os bytes recebidos (não sobre o JSON re-serializado) e compare em tempo constante. Rejeite com 401 se não bater.

Node.js (Express)
import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";

const app = express();

app.post(
  "/webhooks/onbriefing",
  express.raw({ type: "application/json" }), // corpo bruto, sem parse
  (req, res) => {
    const expected = createHmac("sha256", process.env.ONBRIEFING_WEBHOOK_SECRET)
      .update(req.body)
      .digest("hex");
    const received = String(req.get("X-OnBriefing-Signature") ?? "").replace("sha256=", "");

    const valid =
      expected.length === received.length &&
      timingSafeEqual(Buffer.from(expected), Buffer.from(received));
    if (!valid) return res.sendStatus(401);

    const { event, verification } = JSON.parse(req.body);
    // Responda rápido; processe em segundo plano.
    queue.add({ event, verification });
    res.sendStatus(200);
  },
);
Next.js (route handler)
import { createHmac, timingSafeEqual } from "node:crypto";

export async function POST(request: Request) {
  const raw = await request.text();
  const expected = createHmac("sha256", process.env.ONBRIEFING_WEBHOOK_SECRET!).update(raw).digest("hex");
  const received = (request.headers.get("x-onbriefing-signature") ?? "").replace("sha256=", "");

  if (expected.length !== received.length ||
      !timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
    return new Response("assinatura inválida", { status: 401 });
  }

  const { event, verification } = JSON.parse(raw);
  // ...
  return new Response(null, { status: 200 });
}
Python (Flask)
import hmac, hashlib, os
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = os.environ["ONBRIEFING_WEBHOOK_SECRET"].encode()

@app.post("/webhooks/onbriefing")
def onbriefing_webhook():
    raw = request.get_data()  # corpo bruto
    expected = hmac.new(SECRET, raw, hashlib.sha256).hexdigest()
    received = request.headers.get("X-OnBriefing-Signature", "").removeprefix("sha256=")
    if not hmac.compare_digest(expected, received):
        abort(401)

    payload = request.get_json()
    # ...
    return "", 200

Entrega e novas tentativas

  • Responda com qualquer status 2xx em até 10 segundos para confirmar o recebimento.
  • Resposta fora de 2xx, erro de rede ou timeout geram novas tentativas: até 5, com intervalo crescente a partir de 30 segundos.
  • A mesma verificação pode chegar mais de uma vez. Trate o handler como idempotente, usando verification.id como chave.
  • A ordem de chegada não é garantida entre verificações diferentes.
  • Mantenha uma consulta periódica de segurança (por exemplo, a cada hora, listando por status) para recuperar qualquer webhook perdido.

Erros

Erros da API vêm com status HTTP e um corpo JSON com error (mensagem em português) e, em erros de validação de campo, field.

{ "error": "Cole o briefing da campanha. É ele que define o que será verificado.", "field": "rulesText" }

Status HTTP

CampoTipoDescrição
200 / 201sucessoRequisição aceita. 201 na criação de campanha.
400requisiçãoCorpo não é JSON, campo com tipo errado, lote com mais de 500 URLs ou status de filtro inválido.
401autenticaçãoChave ausente, inválida ou revogada.
404não encontradoCampanha ou verificação inexistente ou de outra organização.
422validaçãoCampo com valor inválido (name vazio, rulesText curto). Veja field. No PATCH, esses casos podem vir como 400.
5xxservidorErro do OnBriefing. Tente de novo com espera exponencial; reenviar URLs é seguro.

Falhas de verificação

Uma verificação em FAILED traz errorCode e error. Os créditos da análise são devolvidos.

CampoTipoDescrição
AUTH_REQUIREDerrorCodeO vídeo é privado ou exige login para ser visto. Peça ao creator para torná-lo público.
VIDEO_UNAVAILABLEerrorCodeO vídeo foi removido ou não existe.
GEO_BLOCKEDerrorCodeO vídeo existe, mas a plataforma não o libera para a região de onde a verificação baixa.
VIDEO_TOO_LONGerrorCodeO vídeo passa de 10 minutos, o limite atual.
RATE_LIMITEDerrorCodeA plataforma de vídeo bloqueou o acesso mesmo depois das novas tentativas automáticas.
NETWORK_ERRORerrorCodeNão foi possível alcançar a plataforma de vídeo.
DOWNLOAD_FAILEDerrorCodeO download falhou por outro motivo.
PIPELINE_FAILEDerrorCodeFalha interna na análise.

Uma verificação em FAILED continua ocupando a URL na campanha: reenviar a mesma URL volta como duplicate. Para reprocessar, fale com a gente.

Limites e créditos

  • Até 500 URLs por chamada de envio. Para mais, divida em lotes.
  • Vídeos de até 10 minutos.
  • Listagem paginada em 50 itens por página.
  • Não há limite publicado de requisições por minuto hoje. O que tem fila é o processamento: enviar 500 vídeos de uma vez é normal, eles ficam prontos ao longo dos minutos seguintes.
  • A cobrança é em créditos: 1 crédito por minuto de vídeo, e a fração conta como minuto inteiro. Os créditos vêm do plano mensal da conta ou de créditos adicionais. O envio confere se há ao menos um crédito por vídeo; o débito exato acontece quando o processamento começa, já com a duração conhecida. Sem créditos, a URL volta como insufficient_credits e não entra na fila. URLs duplicate e invalid não custam nada, e análises que falham são estornadas.
  • O plano e os créditos adicionais ficam no painel, em Créditos, com cartão (contas em dólar pagam com cartão internacional). Volume alto ou contrato: plano Enterprise, pelo formulário de contato.

Boas práticas

  • Configure o webhook antes de enviar os vídeos, para não perder nenhum resultado.
  • Guarde o id da verificação junto com o registro da entrega no seu sistema. É ele que liga o webhook à entrega certa.
  • Use a URL normalizada de outcomes[].url para cruzar dados, não a URL que você enviou.
  • Sem webhook, consulte a cada 30–60 segundos e só as verificações que ainda não terminaram.
  • Em caso de timeout no envio, reenvie o mesmo lote: o que já entrou volta como duplicate, sem cobrança dupla.
  • Escreva o briefing como você escreveria para o creator, com regras concretas ("citar o cupom VERAO26 na fala") em vez de genéricas ("falar bem do produto").
  • Uma campanha por briefing: se as regras mudam por grupo de creators, crie campanhas separadas.

Versões

A versão atual é a v1, no caminho /api/v1. Mudanças compatíveis, como campos novos em respostas e novos valores de categoria, entram sem mudar a versão. Mudanças incompatíveis vão para uma nova versão, com aviso prévio aos clientes da API.

Ficou alguma dúvida?

Fale direto com quem constrói a API. A gente ajuda a desenhar a integração.

Falar com a equipe

Fale com a gente

Conte sobre a sua campanha. Respondemos por e-mail.

Usamos estes dados só para responder você.