URL base del servicio
Todas las APIs REST documentadas acá cuelgan de esta URL base:
https://email-dispatcher.myagronorte.com.ar
Monitoreo y gestión operativa
| ID | Destinatario | Template | Estado | Intentos | Error |
|---|
|
Acciones
|
|---|
Acciones |
|---|
|
Acciones
|
|---|
| Código | Mailbox | Provider | Auth flow | Expira | Refresh |
|---|
Todas las APIs REST documentadas acá cuelgan de esta URL base:
https://email-dispatcher.myagronorte.com.ar
Las APIs aceptan dos modos de autenticación:
EMAIL_DISPATCHER_API_KEYSmessaging.authorized_user con los permisos correspondientesAuthorization: Bearer <API_KEY_O_SUPABASE_JWT>
No hay integración soportada por SQL directo. No hay integración soportada desde frontend.
Ejemplo mínimo y completo para modelar el flujo real de email con variables simples.
code reutilizable.template_code.execution_id.curl -X POST \
https://email-dispatcher.myagronorte.com.ar/api/rest/templates \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"code": "demo_email_simple_v1",
"name": "Demo email simple",
"description": "Template mínimo para validar integración completa",
"active": true,
"version": 1,
"subject_template": "Demo simple {{customer_name}}",
"html_template": "<html><body><h1>Hola {{customer_name}}</h1><p>Tu operación {{operation_id}} está lista.</p></body></html>",
"text_template": "Hola {{customer_name}} - Tu operación {{operation_id}} está lista.",
"metadata": {
"origin": "tu-app"
}
}'
curl -X POST \
https://email-dispatcher.myagronorte.com.ar/api/rest/email/send \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"provider_code": "default_graph",
"template_code": "demo_email_simple_v1",
"subject": "Demo simple Cliente Demo",
"recipient": {
"address": "destino@tu-dominio.com",
"name": "Cliente Demo"
},
"payload": {
"customer_name": "Cliente Demo",
"operation_id": "OP-12345"
},
"scheduled_for": "NOW",
"external_ref": "demo-email-simple-op-12345",
"metadata": {
"origin": "tu-app"
}
}'
curl -X GET \
https://email-dispatcher.myagronorte.com.ar/api/rest/executions/<EXECUTION_ID> \
-H "Authorization: Bearer <API_KEY>"
Si después ya no querés usar el template, podés dejarlo active=false. Si el template ya tuvo ejecuciones, puede no ser eliminable por integridad referencial.
Devuelve el catálogo de templates disponibles.
curl -X GET \ https://email-dispatcher.myagronorte.com.ar/api/rest/templates \ -H "Authorization: Bearer <API_KEY>"
Crea una plantilla de email reutilizable. El asunto es obligatorio y debe resolver a un valor no vacío al enviar.
{
"code": "string",
"name": "string",
"description": "string|null",
"active": "boolean",
"version": "integer",
"subject_template": "string",
"html_template": "string",
"text_template": "string",
"metadata": "object"
}
| Campo | Tipo | Obligatorio | Qué es |
|---|---|---|---|
code | string | Sí | Código técnico único de la plantilla. Es el valor estable para integrarla desde otras apps. |
name | string | Sí | Nombre visible/operativo de la plantilla. |
description | string | null | No | Descripción funcional para operadores o integradores. |
active | boolean | No | Define si la plantilla queda habilitada para usar. |
version | integer | No | Versión lógica de la plantilla. Si no se envía, se crea como 1. |
subject_template | string | Sí | Template del asunto. Acepta tokens {{variable}}. No puede quedar vacío. |
html_template | string | Sí | Cuerpo HTML del email. Acepta tokens {{variable}}. |
text_template | string | No | Versión en texto plano del email. Recomendado para compatibilidad. |
metadata | object | No | Datos auxiliares para trazabilidad, origen o clasificación. |
{
"code": "demo_email_simple_v1",
"name": "Demo email simple",
"description": "Template mínimo para validar integración completa",
"active": true,
"version": 1,
"subject_template": "Demo simple {{customer_name}}",
"html_template": "<html><body><h1>Hola {{customer_name}}</h1><p>Tu operación {{operation_id}} está lista.</p></body></html>",
"text_template": "Hola {{customer_name}} - Tu operación {{operation_id}} está lista.",
"metadata": {
"origin": "tu-app"
}
}
Devuelve el template completo, incluyendo HTML, texto plano y metadata.
Actualiza parcialmente una plantilla existente. Sólo enviar los campos que querés cambiar.
{
"code": "string",
"name": "string",
"description": "string|null",
"active": "boolean",
"version": "integer",
"subject_template": "string",
"html_template": "string",
"text_template": "string",
"metadata": "object"
}
| Campo | Tipo | Obligatorio | Qué es |
|---|---|---|---|
code | string | No | Nuevo código técnico de la plantilla. |
name | string | No | Nuevo nombre visible. |
description | string | null | No | Descripción operativa actualizada. |
active | boolean | No | Permite activar o desactivar la plantilla. |
version | integer | No | Versión lógica de la plantilla. |
subject_template | string | No | Nuevo template del asunto. Si se envía, no puede ser vacío. |
html_template | string | No | Nuevo cuerpo HTML. |
text_template | string | No | Nueva versión en texto plano. |
metadata | object | No | Metadatos auxiliares actualizados. |
{
"subject_template": "Demo actualizada {{customer_name}}",
"html_template": "<html><body><h1>Hola {{customer_name}}</h1><p>Tu operación {{operation_id}} fue actualizada.</p></body></html>",
"active": true
}
Elimina el template indicado por id. Si ya fue usado por una ejecución y la base lo referencia, dejarlo inactivo con PATCH active=false.
Crea una ejecución individual. El asunto final sale del subject_template de la plantilla y debe resolverse a un valor no vacío.
{
"provider_code": "string",
"template_id": "integer",
"template_code": "string",
"subject": "string",
"subject_override": "string",
"to": [
{
"address": "string(email)",
"name": "string"
}
],
"recipient": {
"address": "string(email)",
"name": "string"
},
"payload": "object",
"attachments": [
{
"kind": "string",
"file_name": "string",
"content_type": "string",
"source_type": "string(base64|url|path)",
"source_path": "string",
"content_base64": "string",
"external_url": "string",
"metadata": "object"
}
],
"scheduled_for": "string(NOW|RFC3339)",
"external_ref": "string",
"metadata": "object",
"priority": "integer"
}
| Campo | Tipo | Obligatorio | Qué es |
|---|---|---|---|
provider_code | string | No | Provider de salida. Si se omite, usa default_graph. |
template_id | integer | No* | ID numérico de la plantilla. |
template_code | string | No* | Código técnico de la plantilla. Recomendado para integraciones. |
subject | string | No*** | Asunto explícito del email. Si se envía, pisa el subject_template de la plantilla. |
subject_override | string | No*** | Alias técnico de override de asunto. Si se envía junto con subject, tiene prioridad. |
to | array | No** | Lista explícita de destinatarios con address y opcionalmente name. |
recipient | object | No** | Atajo para envío a un solo destinatario. |
payload | object | Sí | Variables que completan subject_template, html_template y text_template. |
attachments | array | No | Adjuntos opcionales. Cada item define origen y nombre del archivo. |
scheduled_for | string | No | NOW para envío inmediato o fecha/hora en formato RFC3339. |
external_ref | string | No | Referencia externa de negocio para trazabilidad. |
metadata | object | No | Metadatos auxiliares de origen, módulo o contexto. |
priority | integer | No | Prioridad interna de cola. Si se omite, usa un valor por defecto. |
* Debés enviar uno entre template_id y template_code.
** Debés enviar uno entre recipient y to.
*** Si no enviás subject ni subject_override, la plantilla igual debe resolver un asunto no vacío desde subject_template.
{
"provider_code": "default_graph",
"template_code": "demo_email_simple_v1",
"subject": "Demo simple Cliente Demo",
"recipient": {
"address": "destino@tu-dominio.com",
"name": "Cliente Demo"
},
"payload": {
"customer_name": "Cliente Demo",
"operation_id": "OP-12345"
},
"scheduled_for": "NOW",
"external_ref": "demo-email-simple-op-12345",
"metadata": {
"origin": "tu-app"
}
}
Para programar una hora específica, usar scheduled_for en formato YYYY-MM-DDTHH:mm:ss.
{
"template_code": "demo_email_simple_v1",
"subject": "Demo simple Cliente Demo",
"recipient": { "address": "destino@tu-dominio.com" },
"payload": {
"customer_name": "Cliente Demo",
"operation_id": "OP-12345"
},
"scheduled_for": "2026-05-30T09:30:00"
}
Respuesta:
{
"execution_id": 123,
"status": "queued",
"provider_code": "default_graph",
"template_code": "demo_email_simple_v1",
"scheduled_for": "2026-05-30T09:30:00Z",
"attachment_count": 0,
"queued_at": "2026-05-27T18:00:00Z"
}
Devuelve el estado actual de la ejecución, sus intentos y sus adjuntos.
Recibe una lista de requests equivalentes a la API de envío simple y devuelve una lista de ids de ejecución.
{
"items": [
{
"provider_code": "string",
"template_id": "integer",
"template_code": "string",
"subject": "string",
"subject_override": "string",
"to": [
{
"address": "string(email)",
"name": "string"
}
],
"recipient": {
"address": "string(email)",
"name": "string"
},
"payload": "object",
"attachments": "array",
"scheduled_for": "string(NOW|RFC3339)",
"external_ref": "string",
"metadata": "object",
"priority": "integer"
}
]
}
| Campo | Tipo | Obligatorio | Qué es |
|---|---|---|---|
items | array | Sí | Lista de requests. Cada item usa exactamente el mismo contrato que POST /api/rest/email/send. |
{
"items": [
{
"template_code": "demo_email_simple_v1",
"subject": "Demo simple Cliente 1",
"recipient": { "address": "cliente1@tu-dominio.com" },
"payload": { "customer_name": "Cliente 1", "operation_id": "OP-1001" },
"scheduled_for": "NOW"
},
{
"template_code": "demo_email_simple_v1",
"subject": "Demo simple Cliente 2",
"recipient": { "address": "cliente2@tu-dominio.com" },
"payload": { "customer_name": "Cliente 2", "operation_id": "OP-1002" },
"scheduled_for": "2026-05-30T09:45:00"
}
]
}
Respuesta:
{
"items": [
{ "index": 0, "execution_id": 2001, "status": "queued" },
{ "index": 1, "execution_id": 2002, "status": "queued" }
]
}
POST /api/rest/whatsapp/templatesGET /api/rest/whatsapp/templates y GET /api/rest/whatsapp/templates/{idOrName}intent_id_or_name al llamar POST /api/rest/whatsapp/sendPara WhatsApp no hay que inventar el nombre de la plantilla: use exactamente el name o el id devuelto por la API de templates.
Crea la plantilla en Botmaker usando el provider configurado. Requiere permiso para gestionar plantillas. La respuesta incluye el estado inicial, que puede quedar pendiente de aprobación.
curl -X POST "https://email-dispatcher.myagronorte.com.ar/api/rest/whatsapp/templates" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"aviso_de_pago","category":"UTILITY","locale":"es_AR","body":{"text":"Hola {{nombre}}"}}'
Especificación OpenAPI autenticada para que Codex u otros agentes puedan descubrir el contrato vigente del dispatcher.
Lista las plantillas reales de Botmaker disponibles para el provider configurado. Se puede filtrar por state.
curl -X GET \ "https://email-dispatcher.myagronorte.com.ar/api/rest/whatsapp/templates?state=APPROVED" \ -H "Authorization: Bearer <API_KEY>"
También acepta provider_code para elegir otro provider si existiera más de uno.
{
"items": [
{
"name": "api_aviso_cierre_lote",
"state": "APPROVED",
"phoneLinesNumbers": ["5493498449387"],
"botName": "agronorte",
"category": "MARKETING",
"locale": "es",
"body": {
"text": "Hola ${ag_nombre} ... ${ag_factura} ... ${ag_serie} ..."
},
"buttons": [
{ "type": "URL", "text": "Contacto Administración", "url": "https://marketing.myagronorte.com.ar/index.php?c=19" }
]
}
]
}
Devuelve una plantilla puntual por id o por name. Use esto para ver las variables exactas que espera antes de enviar.
curl -X GET \ "https://email-dispatcher.myagronorte.com.ar/api/rest/whatsapp/templates/api_aviso_cierre_lote" \ -H "Authorization: Bearer <API_KEY>"
Encola una notificación de WhatsApp por Botmaker. Use en intent_id_or_name el valor real obtenido desde /api/rest/whatsapp/templates o /api/rest/whatsapp/templates/{idOrName}.
{
"provider_code": "string",
"channel_id": "string",
"intent_id_or_name": "string",
"contact_id": "string",
"phone_e164": "string",
"variables": "object",
"tags": "object",
"webhook_payload": "string",
"notification_name": "string",
"scheduled_for": "string(NOW|RFC3339)",
"external_ref": "string",
"metadata": "object",
"priority": "integer"
}
| Campo | Tipo | Obligatorio | Qué es |
|---|---|---|---|
provider_code | string | No | Provider WhatsApp a usar. Si se omite, usa el default configurado. |
channel_id | string | No | Canal Botmaker/WhatsApp específico si querés forzarlo. |
intent_id_or_name | string | Sí | Nombre o id real de la plantilla Botmaker. No inventarlo. |
contact_id | string | Sí | Identificador del contacto destino. |
phone_e164 | string | No | Teléfono normalizado. Hoy el camino soportado principal sigue siendo contact_id. |
variables | object | No | Variables que exige la plantilla real de Botmaker. |
tags | object | No | Tags auxiliares para segmentación o seguimiento. |
webhook_payload | string | No | Payload de correlación para callbacks/webhooks. |
notification_name | string | No | Nombre técnico único del envío en Botmaker. |
scheduled_for | string | No | NOW o fecha/hora programada. |
external_ref | string | No | Referencia externa de negocio. |
metadata | object | No | Metadatos auxiliares del emisor. |
priority | integer | No | Prioridad interna en cola. |
{
"provider_code": "default_botmaker",
"intent_id_or_name": "api_aviso_cierre_lote",
"contact_id": "93498456872",
"variables": {
"ag_nombre": "Matias Santa Cruz",
"ag_fecha": "29/05/2026",
"ag_factura": "https://cobranzas.myagronorte.com.ar/resumen.pdf",
"ag_serie": "https://cobranzas.myagronorte.com.ar/formas-pago.pdf"
},
"notification_name": "aviso-cierre-lote-20260529121812",
"scheduled_for": "NOW",
"external_ref": "botmaker-cierre-lote-test",
"metadata": {
"origin": "monitoring-app"
}
}
Respuesta:
{
"execution_id": 1,
"status": "queued",
"provider_code": "default_botmaker",
"channel_id": "agronorte-whatsapp-5493498449387",
"intent_id_or_name": "api_aviso_cierre_lote",
"notification_name": "aviso-cierre-lote-20260529121812",
"scheduled_for": "2026-05-29T12:18:13Z",
"queued_at": "2026-05-29T12:18:13Z"
}
Si desea usar otra plantilla, primero léala por la API y luego reemplace intent_id_or_name y las variables por las que esa plantilla pida realmente.
Recibe una lista de requests equivalentes al envío simple de WhatsApp y devuelve una lista de ejecuciones encoladas.
{
"items": [
{
"provider_code": "string",
"channel_id": "string",
"intent_id_or_name": "string",
"contact_id": "string",
"phone_e164": "string",
"variables": "object",
"tags": "object",
"webhook_payload": "string",
"notification_name": "string",
"scheduled_for": "string(NOW|RFC3339)",
"external_ref": "string",
"metadata": "object",
"priority": "integer"
}
]
}
| Campo | Tipo | Obligatorio | Qué es |
|---|---|---|---|
items | array | Sí | Lista de requests. Cada item usa el mismo contrato que POST /api/rest/whatsapp/send. |
{
"items": [
{
"provider_code": "default_botmaker",
"intent_id_or_name": "api_aviso_cierre_lote",
"contact_id": "93498456872",
"variables": {
"ag_nombre": "Cliente A",
"ag_fecha": "29/05/2026",
"ag_factura": "https://dominio/resumen-a.pdf",
"ag_serie": "https://dominio/formas-a.pdf"
}
},
{
"provider_code": "default_botmaker",
"intent_id_or_name": "api_aviso_cierre_lote",
"contact_id": "93411112222",
"variables": {
"ag_nombre": "Cliente B",
"ag_fecha": "29/05/2026",
"ag_factura": "https://dominio/resumen-b.pdf",
"ag_serie": "https://dominio/formas-b.pdf"
}
}
]
}
Devuelve la ejecución local y, cuando existe notification_name, sincroniza el estado real desde Botmaker. El detalle útil incluye el payload usado, la respuesta real del provider y el estado final local.
external_ref y metadata.origin para trazabilidad.base64.contact_id.name/id exacto en intent_id_or_name.api_aviso_cierre_lote.