Referência
Referência da API
API do Chasca v1: JSON sobre HTTPS, com chaves de API do tipo bearer. O que leva tempo (geração, mudanças e edições) retorna 202 com um registro na fila, que você pode consultar periodicamente ou acompanhar em streaming.
https://app.trychasca.com/api Autenticação
Todo endpoint /v1, exceto os de vozes e idiomas, exige uma chave de API, enviada como
Authorization: Bearer chk_live_…. Crie as chaves no app, em Settings → API keys.
O acesso à API começa no plano Plus, e as gerações pela API contam em dobro (2x) nos minutos do plano.
Convenções
- Os corpos são JSON (
Content-Type: application/json). Os timestamps seguem a ISO 8601, em UTC. - Operações enfileiradas respondem 202; a criação de uma cópia responde 201; a exclusão responde 204.
-
O status do vídeo explicativo passa por
queued → generating → rendering → ready, ou termina emfailed, com a causa legível emerror.stageeprogress(0–1) descrevem a etapa em andamento. - As URLs de mídia são assinadas e expiram depois de cerca de uma semana. Busque o vídeo explicativo de novo para obter links novos.
Endpoints
POST /v1/explainer
Enfileira um novo vídeo explicativo. Retorna 202 com o registro enfileirado.
| Campo | Tipo | Descrição |
|---|---|---|
input | string | O que explicar: um tema, uma pergunta ou o texto completo de um documento (até 200.000 caracteres). Alias: prompt. É obrigatório enviar um destes campos: input, source ou sceneGraph. |
length | string | number | "M:SS" (como "1:30") ou segundos, em múltiplos de 30 até 1800 (30 minutos). Acima de 360, o vídeo é contado em capítulos. Omita para usar a duração automática. Alias: lengthSeconds. |
aspect | string | 16:9 (padrão), 9:16 ou 1:1. |
voice | string | O id de um narrador, como chasca:sulafat (padrão) ou chasca:kore. Todo narrador fala todos os idiomas. Veja Vozes. |
language | string | Código do idioma da narração, por exemplo en, es-419, ja. Veja Idiomas. |
source | string | Texto-fonte que serve de base para a explicação (até 400.000 caracteres). O roteiro se mantém fiel a ele. |
preset | string | Estilo de desenho: marker (padrão), chalkboard, pencil, blueprint, crayon ou clean. |
fillMode | string | Como a cor é aplicada depois de cada contorno: A fade, B varredura, C preenchimento por região (padrão), D rabisco. |
hand | string | Uma mão que desenha o quadro, com a caneta em cada linha enquanto ela aparece: marker-light, marker-medium, marker-dark, pencil ou sketch, off, ou auto (padrão: uma mão só quando o pedido pede para vê-la). |
pace | string | relaxed, balanced (padrão) ou brisk. |
music | boolean | Adiciona uma trilha de fundo discreta sob a narração. Padrão: false. |
sceneGraph | object | Pula a etapa de escrita e renderiza um grafo de cenas enviado por você (cenas com narração, título e elementos). |
curl -X POST https://app.trychasca.com/api/v1/explainer \
-H "Authorization: Bearer $CHASCA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": "How does compound interest snowball?",
"length": "1:30",
"aspect": "9:16",
"voice": "chasca:sulafat",
"language": "en",
"preset": "chalkboard",
"pace": "balanced"
}' {
"id": "0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60",
"status": "queued",
"stage": null,
"progress": 0,
"title": null,
"prompt": "How does compound interest snowball?",
"lengthSeconds": 90,
"voice": "chasca:sulafat",
"language": "en",
"aspect": "9:16",
"preset": "chalkboard",
"fillMode": "C",
"pace": "balanced",
"music": false,
"videoUrl": null,
"posterUrl": null,
"subtitlesUrl": null,
"durationSeconds": null,
"watermarked": false,
"sceneGraph": null,
"headVersionId": null,
"source": null,
"error": null,
"createdVia": "api",
"createdAt": "2026-09-23T09:14:02.118Z",
"updatedAt": "2026-09-23T09:14:02.118Z"
} GET /v1/explainer/:id
Um vídeo explicativo com tudo: status, videoUrl, posterUrl, subtitlesUrl, o
sceneGraph editável, os tempos de cada cena em scenes e todas as entradas de
versions.
curl https://app.trychasca.com/api/v1/explainer/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60 \
-H "Authorization: Bearer $CHASCA_API_KEY" {
"id": "0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60",
"status": "ready",
"stage": null,
"progress": 1,
"title": "How compound interest snowballs",
"lengthSeconds": 90,
"durationSeconds": 88.4,
"videoUrl": "https://app.trychasca.com/media/explainers/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60/v1/video.mp4?exp=1790000000&sig=…",
"posterUrl": "https://app.trychasca.com/media/explainers/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60/v1/poster.jpg?exp=1790000000&sig=…",
"subtitlesUrl": "https://app.trychasca.com/media/explainers/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60/v1/subtitles.vtt?exp=1790000000&sig=…",
"sceneGraph": {
"title": "How compound interest snowballs",
"language": "en",
"scenes": [
{
"id": "s1",
"heading": "THE MONEY THAT GROWS ITSELF",
"narration": "Picture planting a tiny seed…",
"elements": [
{ "id": "seed", "type": "icon", "icon": "seedling", "label": "SEED", "revealWord": "seed" }
]
}
]
},
"scenes": [
{ "id": "s1", "index": 0, "heading": "THE MONEY THAT GROWS ITSELF", "start": 0, "duration": 19.3 }
],
"versions": [
{
"id": "5f1d…",
"number": 1,
"status": "ready",
"note": null,
"changedScenes": [],
"videoUrl": "https://app.trychasca.com/media/…",
"durationSeconds": 88.4,
"minutesCharged": 2.947,
"createdAt": "2026-09-23T09:14:02.301Z",
"readyAt": "2026-09-23T09:14:49.870Z",
"error": null
}
],
"shareUrl": null,
"error": null
} GET /v1/explainer?limit=50
Seus vídeos explicativos, do mais recente ao mais antigo. limit vai de 1 a 100, com padrão de 50. Os resumos omitem o grafo de cenas e as versões.
curl "https://app.trychasca.com/api/v1/explainer?limit=20" \
-H "Authorization: Bearer $CHASCA_API_KEY" {
"explainers": [
{ "id": "0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60", "status": "ready", "title": "How compound interest snowballs", "durationSeconds": 88.4, "createdAt": "2026-09-23T09:14:02.118Z" }
]
} POST /v1/explainer/:id/change
Uma única mudança em um vídeo explicativo pronto; todo o resto fica exatamente como estava. O corpo é uma única mudança, escolhida por kind:
captions:captions(true ou false) e, opcionalmente,captionStyle(pop,bold,clean,marker,typewriteroustory).style:preset,fillModeou os dois.hand:hand, o id de uma mão ouoff.music:music(true ou false).logooucredit:position, comotop-right(a linha de créditos também pode ficar emtop-centeroubottom-center), ouoff. A partir do Pro.voice:voicee, opcionalmente,pace.aspect:aspect,16:9,9:16ou1:1.
Retorna 202. Legendas, estilo, música, logo e linha de créditos geram uma nova versão gratuita deste
vídeo, { "made": "version", "version": { ... } }: ela mantém a narração e não consome minutos, e,
quando o status dela chega a ready, o videoUrl do vídeo explicativo passa a
apontar para ela. Uma voz ou um formato novos geram um vídeo explicativo separado a partir do mesmo roteiro e dos
mesmos desenhos, cobrado como um vídeo novo: { "made": "video", "explainer": { ... } }.
curl -X POST https://app.trychasca.com/api/v1/explainer/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60/change \
-H "Authorization: Bearer $CHASCA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "kind": "style", "preset": "chalkboard" }' {
"made": "version",
"version": {
"id": "5d0e93b4-…",
"number": 2,
"status": "queued",
"note": "Board style: Chalkboard",
"changedScenes": [],
"videoUrl": null,
"posterUrl": null,
"durationSeconds": null,
"minutesCharged": 0,
"createdAt": "2026-09-23T09:20:11.004Z",
"readyAt": null,
"error": null
}
} POST /v1/explainer/:id/edit
Mude você mesmo as palavras ou os desenhos: busque o vídeo explicativo, edite o sceneGraph dele e envie de
volta como { "sceneGraph": { ... } }. Retorna 202 com a versão enfileirada. Só as
cenas que mudaram são desenhadas de novo, e a primeira nova renderização de cada vídeo é gratuita. Aguarde o
status da versão chegar a ready; a partir daí, o videoUrl do vídeo explicativo aponta para ela.
# graph.json: { "sceneGraph": { ... } }, the explainer's sceneGraph with your changes
curl -X POST https://app.trychasca.com/api/v1/explainer/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60/edit \
-H "Authorization: Bearer $CHASCA_API_KEY" \
-H "Content-Type: application/json" \
-d @graph.json {
"id": "8a2c7e10-…",
"number": 3,
"status": "queued",
"note": null,
"changedScenes": [],
"videoUrl": null,
"posterUrl": null,
"durationSeconds": null,
"minutesCharged": 0,
"createdAt": "2026-09-23T09:24:37.512Z",
"readyAt": null,
"error": null
} POST /v1/explainer/:id/revert
Restaura como atual uma versão anterior já concluída. Corpo: { "versionId": "..." }. Retorna o vídeo explicativo.
curl -X POST https://app.trychasca.com/api/v1/explainer/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60/revert \
-H "Authorization: Bearer $CHASCA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "versionId": "5f1d…" }' POST /v1/explainer/:id/duplicate
Copia um vídeo explicativo, com grafo de cenas e tudo, para você seguir com ele em outra direção. Retorna 201 com a cópia.
curl -X POST https://app.trychasca.com/api/v1/explainer/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60/duplicate \
-H "Authorization: Bearer $CHASCA_API_KEY" DELETE /v1/explainer/:id
Exclui um vídeo explicativo. Retorna 204 sem corpo.
curl -X DELETE https://app.trychasca.com/api/v1/explainer/0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60 \
-H "Authorization: Bearer $CHASCA_API_KEY" GET /v1/explainer/events
Um stream de Server-Sent Events
com um frame event: status a cada mudança de status de qualquer um dos seus vídeos explicativos. Mantenha
uma única conexão aberta em vez de fazer polling.
curl -N https://app.trychasca.com/api/v1/explainer/events \
-H "Authorization: Bearer $CHASCA_API_KEY" event: status
data: {"type":"status","explainerId":"0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60","status":"generating","stage":"storyboard","progress":0.3}
event: status
data: {"type":"status","explainerId":"0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60","status":"rendering","stage":"drawing","progress":0.72}
event: status
data: {"type":"status","explainerId":"0b9c6f2e-5d1a-4c3e-9a47-2f8e1c7d4b60","status":"ready","stage":null,"progress":1} GET /v1/voices Não precisa de chave
O catálogo de vozes. Todo narrador fala todos os idiomas, então a lista é a mesma para qualquer idioma. Cada voz
tem um tone, um group e uma preview_url. Mais detalhes na página
Vozes.
curl "https://app.trychasca.com/api/v1/voices" {
"default": "chasca:sulafat",
"voices": [
{
"id": "chasca:sulafat",
"name": "Sulafat",
"description": "Warm and natural, like a favorite teacher. The all-purpose default.",
"tone": "Warm",
"group": "warm",
"language": "en",
"gender": "female",
"isDefault": true,
"multilingual": true,
"kind": "narrator",
"preview_url": "https://app.trychasca.com/api/v1/voices/chasca%3Anova/preview.mp3"
},
{
"id": "edge:es-MX-DaliaNeural",
"name": "Dalia",
"description": "Friendly, Positive. Native es-MX speaker.",
"language": "es-MX",
"gender": "female",
"isDefault": false,
"multilingual": false,
"kind": "native",
"preview_url": "https://app.trychasca.com/api/v1/voices/edge%3Aes-MX-DaliaNeural/preview.mp3"
}
]
} GET /v1/languages Não precisa de chave
Todos os idiomas de narração. Os idiomas beta são mais recentes no modelo de voz, então a qualidade da narração pode variar.
curl https://app.trychasca.com/api/v1/languages {
"languages": [
{ "code": "en", "label": "English", "native": "English", "beta": false },
{ "code": "es-419", "label": "Spanish (Latin America)", "native": "Español (Latinoamérica)", "beta": false },
{ "code": "pa", "label": "Punjabi", "native": "ਪੰਜਾਬੀ", "beta": true }
]
} GET /v1/account/state
A conta dona da chave e quantos vídeos ela já criou.
curl https://app.trychasca.com/api/v1/account/state \
-H "Authorization: Bearer $CHASCA_API_KEY" { "videosGenerated": 14, "image": null, "isAdmin": false, "name": "Ada Lovelace" } GET /v1/billing/status
O plano associado à chave e em que ponto do período você está: minutos usados e restantes e recursos do
plano. Contas gratuitas recebem videoAllowance, videosUsed e videosRemaining no lugar desses campos.
curl https://app.trychasca.com/api/v1/billing/status \
-H "Authorization: Bearer $CHASCA_API_KEY" {
"plan": "pro",
"planLabel": "Pro",
"billingInterval": "monthly",
"status": "active",
"trialStatus": null,
"quotaMinutes": 200,
"bonusMinutes": 0,
"minutesUsedThisPeriod": 41.5,
"minutesRemaining": 158.5,
"periodStart": "2026-09-01T00:00:00.000Z",
"periodEnd": "2026-10-01T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"overageEnabled": false,
"overagePerMinute": 0.5,
"pricePerMonth": 49.99,
"maxLengthSeconds": 1800,
"entitlements": { "api": true, "branding": true, "voiceClone": true, "priority": false, "watermark": false, "maxLength": 1800, "videoAllowance": null }
} GET /config Não precisa de chave
Configuração pública para clientes: onde ficam o site, o app e a API.
curl https://app.trychasca.com/api/config {
"authEnforced": true,
"googleEnabled": false,
"requireEmailVerification": false,
"siteUrl": "https://trychasca.com",
"appUrl": "https://app.trychasca.com",
"apiUrl": "https://app.trychasca.com/api",
"devMail": false
} GET /health Não precisa de chave
Verificação de liveness para balanceadores de carga e monitores de uptime.
curl https://app.trychasca.com/api/health { "status": "ok", "service": "chasca-api", "time": "2026-09-23T09:14:00.000Z", "db": "postgres", "tts": "edge", "llmConfigured": true } Erros
Todo erro tem o mesmo formato, com um code estável e legível por máquina e uma mensagem que você pode mostrar aos seus usuários:
{
"error": true,
"code": "api_requires_plan",
"message": "API and MCP access start on the Plus plan.",
"status": 402
} | Status | Código | Significado |
|---|---|---|
| 400 | bad_request, empty_input, bad_voice | A requisição está malformada ou não informa o que explicar. |
| 400 | instruction_edits_retired | Uma edição enviou uma instrução em linguagem natural. Envie uma única mudança ou um grafo de cenas editado. |
| 401 | unauthenticated | Nenhuma chave enviada, ou a chave está incorreta ou foi revogada. |
| 402 | api_requires_plan, branding_requires_plan | O acesso à API e ao MCP começa no plano Plus; as mudanças de logo e de linha de créditos, no Pro. |
| 402 | minutes_exhausted, minutes_short | Não restam minutos neste período, ou eles não bastam para a duração pedida. |
| 404 | not_found | Nenhum vídeo explicativo com esse id na sua conta. |
| 409 | still_rendering, no_changes | O vídeo ainda está sendo renderizado, ou a mudança ou a edição não altera nada. |
| 409 | no_logo, no_credit_line | Ainda não há um logo ou uma linha de créditos para posicionar. Adicione o que faltar no app, em Settings → Branding. |
| 429 | rate_limited | Requisições demais. Aguarde o tempo indicado no cabeçalho Retry-After e tente de novo. |
| 500 | internal | Erro nosso. Os detalhes ficam registrados do nosso lado e nunca são expostos. |
Limites de requisições
- Geração, mudanças e edições (
POST /v1/explainer,…/change,…/edit): 20 requisições por minuto. - Todo o resto: 200 requisições por minuto.
-
Acima do limite, você recebe 429
rate_limited, com um cabeçalhoRetry-Afterem segundos. O SDK tenta de novo as requisições de leitura uma vez, depois desse intervalo, e expõe o valor nos erros comoretryAfter.