POST
/meeting-notes
Envía la salida de un tomador de notas — transcripción cruda, resumen, recapitulación enriquecida con IA, items de acción — contra una reunión existente. Diseñado para webhooks de Fathom, Granola, Otter, Zoom AI Companion, o cualquier flujo de toma de notas interno (Make / Zapier / personalizado).
La nota se adjunta a un calendar_event que ya existe en Nexor. Sin notas huérfanas en v1 — si ninguna reunión se resuelve, obtienes un 404.
Resolución de reunión
El endpoint intenta lo siguiente en orden, deteniéndose en la primera coincidencia:
calendar_event_id — directo.
external_calendar_provider + external_calendar_event_id — coincide reuniones creadas vía POST /meetings con esas claves de dedup.
meeting_url — coincidencia exacta con la URL de reunión del calendar_event.
lead_email + meeting_date — reunión del lead dentro de +-60 minutos de meeting_date.
lead_email solo — la reunión pasada más reciente del lead. Sin límite de ventana de tiempo.
Si ninguna resuelve una reunión -> 404. Crea la reunión primero vía POST /meetings o pasa un identificador válido.
Idempotencia
Si proporcionas external_meeting_id junto con un provider, repeticiones del mismo (provider, external_meeting_id) bajo tu cliente actualizan la fila existente en lugar de crear duplicados. Seguro para reintentos de webhook. La actividad note_added en la línea de tiempo solo se dispara en la primera inserción, no en repeticiones.
Proveedores reservados
Los siguientes valores se rechazan para proteger los pipelines de sincronización internos: fireflies, diio, gemini, retell. Escoge cualquier otro string alfanumérico en minúsculas (ej. fathom, granola, otter, manual, zoom_ai). Regex: ^[a-z0-9_-]{1,64}$.
Cuerpo de la Solicitud
Todos los campos son opcionales a menos que se indique. Como mínimo debes proporcionar:
- una forma de resolver una reunión (
calendar_event_id, external_calendar_event_id+external_calendar_provider, meeting_url, o lead_email), y
- un campo de contenido no vacío (
notes, transcript_text, summary, manual_ai_summary, o action_items).
| Campo | Tipo | Descripción |
|---|
provider | string | Origen de la nota. Por defecto "manual". Nombres reservados son rechazados. |
external_meeting_id | string | ID estable del tomador de notas (ej. Recording ID de Fathom). Habilita repetición idempotente. ≤ 255 caracteres. |
calendar_event_id | string (uuid) | Enlace directo — resolución nivel 1. |
external_calendar_provider | string | Par con external_calendar_event_id — nivel 2. |
external_calendar_event_id | string | ID del evento del proveedor desde POST /meetings. |
meeting_url | string | URL de Meet / Zoom / Fathom — nivel 3. |
lead_email | string | Coincide con el lead (alcance de cliente); también impulsa niveles 4 y 5. |
meeting_date | string (ISO 8601) | Usado con lead_email para coincidencia difusa de +-60 min. |
meeting_title | string | |
duration_seconds | integer | |
organizer_email | string | Email del anfitrión. |
notes | string | Texto libre crudo. Alias de transcript_text — si ambos se proporcionan, transcript_text gana. ≤ 1 MB. |
transcript_text | string | Transcripcion completa. ≤ 1 MB. |
summary | string | Resumen nativo del tomador de notas (recapitulación de Fathom / Granola / Otter). |
manual_ai_summary | string | Resumen personalizado enriquecido con IA (ej. paso posterior con ChatGPT en Make). Se almacena separado de summary. |
action_items | array | ["Send pricing", ...] o [{ text, assignee }, ...]. ≤ 512 KB. |
questions | array | ["What's the monthly cost?", ...]. ≤ 512 KB. |
keywords | array | ["pricing", "enterprise", ...]. ≤ 512 KB. |
sentences | array | Enunciados a nivel de hablante (formato compatible con Fireflies). ≤ 512 KB. |
status | string | completed (por defecto), pending o failed. |
Cuerpo de la Solicitud — texto libre mínimo
Ideal para escenarios de Make / Zapier que construyen un blob markdown y lo adjuntan a la reunión más reciente del lead:
{
"lead_email": "tony.stark@gmail.com",
"notes": "Revisamos propuesta. Cliente preguntó por plazos de implementación. Budget Q2 aprobado.",
"manual_ai_summary": "Alta intención. Enterprise. Siguiente paso: propuesta formal antes del viernes."
}
Cuerpo de la Solicitud — Webhook de Fathom vía Make
Usando la salida del trigger “Watch New Recordings” de Fathom mapeada a campos de la API:
{
"provider": "fathom",
"external_meeting_id": "133148102",
"meeting_url": "https://fathom.video/call/133148102",
"meeting_title": "Discovery — Stark Industries",
"meeting_date": "2026-04-15T17:18:02Z",
"organizer_email": "pepper@starkindustries.com",
"lead_email": "tony.stark@gmail.com",
"summary": "## Deal Information\n### Prospect\n[...Fathom markdown summary...]",
"manual_ai_summary": "ChatGPT-enriched recap: strong buying intent, Q2 budget confirmed.",
"action_items": ["Send pricing by Friday", "Intro CTO for technical deep-dive"]
}
Resolviendo lead_email en Make: El flag is_external de Fathom no es confiable (el anfitrión a veces se marca como externo). Filtra Calendar Invitees[] por dominio en su lugar:
Array filter:
Input: Calendar Invitees[]
Condition: email_domain ≠ {{Recorded By.email_domain}}
Then:
lead_email = {{first(filtered).Email}}
Respuesta — 201 Created (o 200 en repetición upsert)
{
"success": true,
"upserted": false,
"meeting_note": {
"id": "0f9230e0-a5e3-4245-8995-afc61007c992",
"client_id": "2c0911d1-25f9-47c2-8795-fe9407b8d67e",
"calendar_event_id": "5a76ac77-523d-4100-843c-1105212de877",
"lead_id": "0433aeee-44af-4148-9ca0-9e2ac41501a7",
"provider": "manual",
"external_meeting_id": null,
"meeting_title": null,
"meeting_date": "2025-12-29T17:00:00+00:00",
"duration_seconds": null,
"organizer_email": null,
"summary": null,
"manual_ai_summary": "Alta intención. Siguiente paso: propuesta formal antes del viernes.",
"transcript_text": "Revisamos propuesta. Budget Q2 aprobado. Interés Enterprise.",
"action_items": null,
"questions": null,
"keywords": null,
"status": "completed",
"created_at": "2026-04-15T20:52:35.426356+00:00",
"updated_at": "2026-04-15T20:52:35.426356+00:00"
}
}
upserted es true cuando una fila previa con el mismo (provider, external_meeting_id) fue actualizada en lugar de insertar una nueva fila.
Línea de Tiempo
En la primera inserción, una actividad note_added se escribe en la línea de tiempo del lead con un enlace a la fila meeting_transcripts creada. Las repeticiones no emiten actividades duplicadas.
Códigos de Error
| Código | Significado |
|---|
400 | Campo faltante o inválido; proveedor reservado; payload excede límites de tamaño; sin campos de contenido; nada para resolver la reunión |
401 | X-API-Key faltante o inválida |
404 | Ningún calendar_event resuelto vía ninguna de las 5 estrategias |
409 | (provider, external_meeting_id) ya vinculado a un calendar_event diferente |
500 | Error inesperado del servidor |
Última modificación el 18 de junio de 2026