{"openapi":"3.1.0","info":{"title":"diascribe","version":"1.0.0","description":"Transcrição + diarização de áudio (PT-BR como especialidade) por jobs assíncronos. Fluxo: crie o job → suba o áudio na upload_url (PUT direto, sem passar pelo gateway — até 600 MB / 4 h) → o processamento dispara sozinho → acompanhe por GET ou webhook. Alternativa: envie audio_url (https) no create e pule o upload. Resultado: JSON com words (timestamps + confidence + falante), segments por falante e proveniência do pipeline."},"servers":[{"url":"https://api.diascribe.io"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Chave de API (ata_...)."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}},"Job":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["created","queued","processing","done","failed","expired"],"description":"created: aguardando upload · queued: na fila da frota · processing: numa GPU · done/failed: terminal · expired: upload não veio em 24h"},"language":{"type":["string","null"]},"diarize":{"type":"boolean"},"duration_seconds":{"type":["number","null"],"description":"Duração do áudio processado."},"error":{"type":["string","null"],"description":"Formato 'codigo: detalhe' quando failed."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"result_url":{"type":"string","description":"Presente quando done: URL assinada do JSON de resultado (expira em result_expires_in segundos)."},"result_expires_in":{"type":"number"}}}},"responses":{"Internal":{"description":"internal_error — erro inesperado; re-tente ou contate o suporte.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}}}},"paths":{"/v1/jobs":{"post":{"summary":"Criar job de transcrição","description":"Sem audio_url: devolve upload_url (PUT presigned, 24 h) e o job dispara quando o upload termina. Com audio_url: o worker baixa direto da URL e o job dispara imediatamente. Idempotency-Key opcional: replay devolve o job original (200 + header idempotency-replayed; o corpo do replay é ignorado).","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"Chave única por criação; retry de rede com a mesma chave devolve o mesmo job."}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"language":{"type":"string","pattern":"^[a-z]{2,3}$","description":"ISO-639-1 (ex.: pt). Omitido = auto-detecção."},"diarize":{"type":"boolean","default":true},"webhook_url":{"type":"string","format":"uri","description":"https obrigatório. Eventos: job.completed | job.failed | job.expired, assinados no formato Standard Webhooks quando a chave tem webhook_secret."},"audio_url":{"type":"string","format":"uri","description":"https obrigatório. Quando presente, não há upload_url — o áudio é baixado desta URL (limites de 600 MB / 4 h valem igual)."}}}}}},"responses":{"200":{"description":"Replay de Idempotency-Key: devolve o job original.","headers":{"idempotency-replayed":{"schema":{"type":"string","enum":["true"]}},"Location":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"upload_url":{"type":"string"},"upload_expires_in":{"type":"number"}},"required":["id","status"]}}}},"201":{"description":"Job criado (header Location). upload_url/upload_expires_in presentes apenas no modo upload.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["created"]},"upload_url":{"type":"string"},"upload_expires_in":{"type":"number"}},"required":["id","status"]}}}},"400":{"description":"invalid_request | invalid_language | invalid_webhook_url | invalid_audio_url | invalid_diarize | invalid_idempotency_key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"401":{"description":"unauthorized (WWW-Authenticate: Bearer)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"429":{"description":"daily_limit_reached (Retry-After presente)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"500":{"$ref":"#/components/responses/Internal"}}}},"/v1/jobs/{id}":{"get":{"summary":"Consultar job","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Estado do job (+ result_url quando done).","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["created","queued","processing","done","failed","expired"],"description":"created: aguardando upload · queued: na fila da frota · processing: numa GPU · done/failed: terminal · expired: upload não veio em 24h"},"language":{"type":["string","null"]},"diarize":{"type":"boolean"},"duration_seconds":{"type":["number","null"],"description":"Duração do áudio processado."},"error":{"type":["string","null"],"description":"Formato 'codigo: detalhe' quando failed."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"result_url":{"type":"string","description":"Presente quando done: URL assinada do JSON de resultado (expira em result_expires_in segundos)."},"result_expires_in":{"type":"number"}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"500":{"$ref":"#/components/responses/Internal"}}}},"/v1/jobs/{id}/transcript":{"get":{"summary":"Exportar transcrição (txt | srt | vtt)","description":"Derivada do JSON canônico. Legendas com cues reais (≤6 s / ≤84 chars, quebra por falante/pausa). Content-Disposition com filename.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["txt","srt","vtt"],"default":"txt"}}],"responses":{"200":{"description":"text/plain (txt) | application/x-subrip (srt) | text/vtt (vtt); Content-Disposition com filename."},"400":{"description":"bad_format — format fora de txt|srt|vtt (o corpo traz formats).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"404":{"description":"not_found | result_missing","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"409":{"description":"not_ready — o job ainda não está done (o corpo traz o status atual).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável para máquina (contrato — nunca muda)."},"message":{"type":"string","description":"Mensagem humana."}},"required":["code","message"]}}}}}},"500":{"$ref":"#/components/responses/Internal"}}}},"/v1/health":{"get":{"summary":"Health check","security":[],"responses":{"200":{"description":"{ ok: true }"}}}}},"webhooks":{"job.completed":{"post":{"summary":"Job terminou com sucesso (também: job.failed, job.expired)","description":"POST na webhook_url do job. Envelope {type, timestamp, data:{id, status, duration_seconds, error}}. Headers Standard Webhooks: webhook-id (estável por evento — deduplique por ele), webhook-timestamp e, quando a chave tem webhook_secret, webhook-signature = 'v1,' + base64(HMAC-SHA256(secret, id.timestamp.payload)). Retries com backoff por ~21 h; confirme sempre pelo GET /v1/jobs/{id} se preferir.","responses":{"2XX":{"description":"Qualquer 2xx interrompe os retries."}}}}}}