API
POST /classify
Clasifica un clip de audio y devuelve la categoría predicha más los k vecinos más cercanos.
Request
POST /classify HTTP/1.1
Host: poi8bb5go9.execute-api.us-east-1.amazonaws.com
Content-Type: application/json{
"audio_base64": "UklGRn4AAABXQVZFZm10IBAAAAABAAEA...",
"format": "wav",
"filename": "demo_clip.wav"
}| Campo | Tipo | Requerido | Restricciones |
|---|---|---|---|
audio_base64 | string | sí | Base64 estándar (con o sin padding). El audio decodificado debe durar ≤ 30 s y pesar ≤ 5 MB. |
format | enum | sí | "wav" (recomendado), "mp3", "ogg". |
filename | string | no | Hint para logs. Máx 128 chars. No se valida ni se usa para inferencia. |
El frontend no debe convertir el archivo. Que mande lo que tenga (mp3 / wav / ogg). El backend lo manda tal cual a Bedrock, que acepta los tres formatos.
Response 200
{
"request_id": "8e7c2a14-9f1b-4d2e-bc11-8a0e5d4f7c9e",
"timestamp": "2026-05-05T14:32:11.482Z",
"latency_ms": 612,
"prediction": {
"category": "siren",
"category_label": "Sirena",
"confidence": 0.8,
"is_critical": true,
"urgency": "high"
},
"neighbors": [
{ "category": "siren", "category_label": "Sirena", "distance": 0.121, "filename": "1-100032-A-7.wav", "fold": 1 },
{ "category": "siren", "category_label": "Sirena", "distance": 0.158, "filename": "1-138048-A-7.wav", "fold": 1 },
{ "category": "siren", "category_label": "Sirena", "distance": 0.174, "filename": "1-145560-A-7.wav", "fold": 1 },
{ "category": "siren", "category_label": "Sirena", "distance": 0.201, "filename": "1-200337-A-7.wav", "fold": 1 },
{ "category": "car_horn", "category_label": "Claxon", "distance": 0.288, "filename": "1-23996-A-43.wav", "fold": 1 }
]
}| Campo | Tipo | Descripción |
|---|---|---|
request_id | string | UUID v4. Igual al de CloudWatch logs. |
timestamp | string | Cuándo terminó la inferencia (UTC). |
latency_ms | number | Tiempo total del handler (sin contar red ni cold start). |
prediction.category | string | Nombre de la clase ESC-50 en inglés (key estable). Ver catálogo. |
prediction.category_label | string | Etiqueta en español lista para UI. |
prediction.confidence | number | votos_clase / k. Rango [0, 1]. Con k=5: 0.2, 0.4, 0.6, 0.8, 1.0. |
prediction.is_critical | boolean | true si la clase está en la lista de sonidos críticos. |
prediction.urgency | enum | "low" | "medium" | "high". Derivada de is_critical y confidence. |
neighbors | array | Top-k vecinos ordenados por distance ascendente. Mínimo 1, máximo 5. |
neighbors[].distance | number | Distancia coseno. 0 = idéntico, 2 = opuesto. En la práctica [0.05, 0.6]. |
neighbors[].fold | number | Fold ESC-50 al que pertenece el vecino. Hoy siempre 1. |
Sonidos críticos y urgencia
prediction.is_critical = true cuando category ∈:
siren, car_horn, clock_alarm, glass_breaking, crying_baby, fireworks, dog(dog está incluido por contexto de seguridad — un perro ladrando puede ser señal de alerta.)
prediction.urgency se deriva así:
| Condición | urgency |
|---|---|
is_critical = true y confidence ≥ 0.6 | "high" |
is_critical = true y confidence < 0.6 | "medium" |
is_critical = false | "low" |
El frontend debe usar urgency (no derivarla por su cuenta) para decidir el tratamiento visual. Si la regla cambia, cambia aquí y se refleja en todos los clientes.
Errores comunes
// 400 - falta campo
{ "error": { "code": "MISSING_FIELD", "message": "Field 'audio_base64' is required.", "request_id": "..." } }
// 400 - formato no soportado
{ "error": { "code": "INVALID_AUDIO_FORMAT", "message": "Audio format must be one of: wav, mp3, ogg.", "request_id": "..." } }
// 400 - audio largo
{ "error": { "code": "AUDIO_TOO_LONG", "message": "Audio duration 42.3s exceeds maximum of 30s.", "request_id": "..." } }
// 502 - Bedrock falló
{ "error": { "code": "EMBEDDING_FAILED", "message": "Bedrock invoke_model timed out after 8000ms.", "request_id": "..." } }Lista completa en Errores.