API Reference

Documentação interativa disponível via Swagger UI quando a aplicação está em execução.

Swagger UI interativo

Com a aplicação rodando localmente, acesse a documentação interativa:

🔗 Swagger UI — http://localhost:8080/swagger-ui.html 📄 OpenAPI JSON — http://localhost:8080/v3/api-docs
⚠️ Os links acima só funcionam com a aplicação em execução localmente. Inicie com ./gradlew bootRun --args='--spring.profiles.active=dev' ou docker compose up -d.

Endpoints

MétodoEndpointDescriçãoAuth
POST /api/transcriptions Transcrever arquivo de áudio (multipart/form-data) 🔒 ROLE_USER
GET /actuator/health Status da aplicação + CircuitBreaker 🔓 público
GET /actuator/prometheus Métricas no formato Prometheus 🔓 público
GET /swagger-ui.html Swagger UI interativo 🔓 público
GET /v3/api-docs Especificação OpenAPI 3.1 (JSON) 🔓 público

POST /api/transcriptions

Request

CampoTipoObrigatórioDescrição
file File (multipart) Arquivo de áudio. Formatos: audio/wav, audio/wave, audio/x-wav, audio/mpeg. Máx: 5MB.

Respostas

StatusDescriçãoBody
200 Sucesso { "text": "...", "fileSizeBytes": 461842 } ou com "cached": true
400 Arquivo inválido ProblemDetail com detalhe do erro e requestId
503 Whisper indisponível ProblemDetail — CircuitBreaker aberto. Tente novamente em ~30s.

Exemplos

# Cache miss — primeiro envio
curl -s -X POST http://localhost:8080/api/transcriptions \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@audio.wav;type=audio/wav" | jq .
# → { "text": "testando o áudio...", "fileSizeBytes": 461842 }

# Cache hit — mesmo arquivo
curl -s -X POST http://localhost:8080/api/transcriptions \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@audio.wav;type=audio/wav" | jq .cached
# → true

# Inspecionar chaves no Redis
docker exec -it redis redis-cli keys 'transcription:*'

Formato de erro (ProblemDetail — RFC 9457)

Todos os erros seguem o padrão RFC 9457 com campo adicional requestId para correlação com os logs do servidor.

{
  "type": "https://api.diospeechai/errors/transcription-exception",
  "title": "Transcription Exception",
  "status": 400,
  "detail": "Tipo de arquivo inválido: 'application/pdf'.",
  "timestamp": "2026-04-11T12:00:00Z",
  "requestId": "a3f2c1d0-7f3e-4b2a-9c1d-e8f5a6b7c8d9"
}

# O requestId está também no header de resposta:
# X-Request-Id: a3f2c1d0-7f3e-4b2a-9c1d-e8f5a6b7c8d9