ED
Agronorte · Cobranzas

Iniciar sesión

Portal operativo del servicio de envíos

ED

Agronorte

Email Dispatcher

Operación

Envíos

Monitoreo y gestión operativa

ID Destinatario Template Estado Intentos Error
Seleccioná un envío para ver el detalle.
0 templates Página 1
Acciones
Página 1 de 1
0 plantillas Página 1
Acciones
Página 1 de 1
0 usuarios Página 1
Acciones
Página 1 de 1
CódigoMailboxProviderAuth flowExpiraRefresh
Base URL

URL base del servicio

Todas las APIs REST documentadas acá cuelgan de esta URL base:

https://email-dispatcher.myagronorte.com.ar
Autenticación

Regla general

Las APIs aceptan dos modos de autenticación:

  1. API key configurada en EMAIL_DISPATCHER_API_KEYS
  2. JWT válido de Supabase de un usuario presente en messaging.authorized_user con los permisos correspondientes
Authorization: Bearer <API_KEY_O_SUPABASE_JWT>

No hay integración soportada por SQL directo. No hay integración soportada desde frontend.

Email · flujo completo

Crear template → enviar → consultar estado

Ejemplo mínimo y completo para modelar el flujo real de email con variables simples.

  1. Crear el template con un code reutilizable.
  2. Enviar usando ese mismo template_code.
  3. Consultar la ejecución devuelta en 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.

Templates · listado

GET /api/rest/templates

Devuelve el catálogo de templates disponibles.

curl -X GET \
  https://email-dispatcher.myagronorte.com.ar/api/rest/templates \
  -H "Authorization: Bearer <API_KEY>"
Templates · alta

POST /api/rest/templates

Crea una plantilla de email reutilizable. El asunto es obligatorio y debe resolver a un valor no vacío al enviar.

Payload completo (tipos)
{
  "code": "string",
  "name": "string",
  "description": "string|null",
  "active": "boolean",
  "version": "integer",
  "subject_template": "string",
  "html_template": "string",
  "text_template": "string",
  "metadata": "object"
}
Referencia de campos
CampoTipoObligatorioQué es
codestringSíCódigo técnico único de la plantilla. Es el valor estable para integrarla desde otras apps.
namestringSíNombre visible/operativo de la plantilla.
descriptionstring | nullNoDescripción funcional para operadores o integradores.
activebooleanNoDefine si la plantilla queda habilitada para usar.
versionintegerNoVersión lógica de la plantilla. Si no se envía, se crea como 1.
subject_templatestringSíTemplate del asunto. Acepta tokens {{variable}}. No puede quedar vacío.
html_templatestringSíCuerpo HTML del email. Acepta tokens {{variable}}.
text_templatestringNoVersión en texto plano del email. Recomendado para compatibilidad.
metadataobjectNoDatos auxiliares para trazabilidad, origen o clasificación.
Ejemplo de payload
{
  "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"
  }
}
Templates · detalle

GET /api/rest/templates/{id}

Devuelve el template completo, incluyendo HTML, texto plano y metadata.

Templates · edición

PATCH /api/rest/templates/{id}

Actualiza parcialmente una plantilla existente. Sólo enviar los campos que querés cambiar.

Payload completo (tipos)
{
  "code": "string",
  "name": "string",
  "description": "string|null",
  "active": "boolean",
  "version": "integer",
  "subject_template": "string",
  "html_template": "string",
  "text_template": "string",
  "metadata": "object"
}
Referencia de campos
CampoTipoObligatorioQué es
codestringNoNuevo código técnico de la plantilla.
namestringNoNuevo nombre visible.
descriptionstring | nullNoDescripción operativa actualizada.
activebooleanNoPermite activar o desactivar la plantilla.
versionintegerNoVersión lógica de la plantilla.
subject_templatestringNoNuevo template del asunto. Si se envía, no puede ser vacío.
html_templatestringNoNuevo cuerpo HTML.
text_templatestringNoNueva versión en texto plano.
metadataobjectNoMetadatos auxiliares actualizados.
Ejemplo de payload
{
  "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
}
Templates · baja

DELETE /api/rest/templates/{id}

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.

Envío simple

POST /api/rest/email/send

Crea una ejecución individual. El asunto final sale del subject_template de la plantilla y debe resolverse a un valor no vacío.

Payload completo (tipos)
{
  "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"
}
Referencia de campos
CampoTipoObligatorioQué es
provider_codestringNoProvider de salida. Si se omite, usa default_graph.
template_idintegerNo*ID numérico de la plantilla.
template_codestringNo*Código técnico de la plantilla. Recomendado para integraciones.
subjectstringNo***Asunto explícito del email. Si se envía, pisa el subject_template de la plantilla.
subject_overridestringNo***Alias técnico de override de asunto. Si se envía junto con subject, tiene prioridad.
toarrayNo**Lista explícita de destinatarios con address y opcionalmente name.
recipientobjectNo**Atajo para envío a un solo destinatario.
payloadobjectSíVariables que completan subject_template, html_template y text_template.
attachmentsarrayNoAdjuntos opcionales. Cada item define origen y nombre del archivo.
scheduled_forstringNoNOW para envío inmediato o fecha/hora en formato RFC3339.
external_refstringNoReferencia externa de negocio para trazabilidad.
metadataobjectNoMetadatos auxiliares de origen, módulo o contexto.
priorityintegerNoPrioridad 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.

Ejemplo de payload
{
  "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"
}
Estado de ejecución

GET /api/rest/executions/{id}

Devuelve el estado actual de la ejecución, sus intentos y sus adjuntos.

Envío batch

POST /api/rest/email/send-batch

Recibe una lista de requests equivalentes a la API de envío simple y devuelve una lista de ids de ejecución.

Payload completo (tipos)
{
  "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"
    }
  ]
}
Referencia de campos
CampoTipoObligatorioQué es
itemsarraySíLista de requests. Cada item usa exactamente el mismo contrato que POST /api/rest/email/send.
Ejemplo de payload
{
  "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" }
  ]
}
WhatsApp · flujo recomendado

Plug and play

  1. Listar templates reales con GET /api/rest/whatsapp/templates
  2. Inspeccionar el template exacto con GET /api/rest/whatsapp/templates/{idOrName}
  3. Usar ese mismo name/id en intent_id_or_name al llamar POST /api/rest/whatsapp/send

Para WhatsApp no hay que inventar el nombre de la plantilla: use exactamente el name o el id devuelto por la API de templates.

WhatsApp · listado de plantillas

GET /api/rest/whatsapp/templates

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" }
      ]
    }
  ]
}
WhatsApp · detalle de plantilla

GET /api/rest/whatsapp/templates/{idOrName}

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>"
WhatsApp · envío simple

POST /api/rest/whatsapp/send

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}.

Payload completo (tipos)
{
  "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"
}
Referencia de campos
CampoTipoObligatorioQué es
provider_codestringNoProvider WhatsApp a usar. Si se omite, usa el default configurado.
channel_idstringNoCanal Botmaker/WhatsApp específico si querés forzarlo.
intent_id_or_namestringSíNombre o id real de la plantilla Botmaker. No inventarlo.
contact_idstringSíIdentificador del contacto destino.
phone_e164stringNoTeléfono normalizado. Hoy el camino soportado principal sigue siendo contact_id.
variablesobjectNoVariables que exige la plantilla real de Botmaker.
tagsobjectNoTags auxiliares para segmentación o seguimiento.
webhook_payloadstringNoPayload de correlación para callbacks/webhooks.
notification_namestringNoNombre técnico único del envío en Botmaker.
scheduled_forstringNoNOW o fecha/hora programada.
external_refstringNoReferencia externa de negocio.
metadataobjectNoMetadatos auxiliares del emisor.
priorityintegerNoPrioridad interna en cola.
Ejemplo de payload
{
  "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.

WhatsApp · envío batch

POST /api/rest/whatsapp/send-batch

Recibe una lista de requests equivalentes al envío simple de WhatsApp y devuelve una lista de ejecuciones encoladas.

Payload completo (tipos)
{
  "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"
    }
  ]
}
Referencia de campos
CampoTipoObligatorioQué es
itemsarraySíLista de requests. Cada item usa el mismo contrato que POST /api/rest/whatsapp/send.
Ejemplo de payload
{
  "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"
      }
    }
  ]
}
WhatsApp · estado

GET /api/rest/whatsapp/executions/{id}

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.

Reglas

Guardrails

  • Integración soportada: sólo API HTTP.
  • No usar SQL directo desde otras apps.
  • No usar service role desde frontend.
  • Usar external_ref y metadata.origin para trazabilidad.
  • Para adjuntos entre runtimes, usar base64.
  • Para Botmaker, el destinatario soportado hoy es contact_id.
  • Para WhatsApp, primero liste o lea la plantilla real y después use ese name/id exacto en intent_id_or_name.
  • Template validado actualmente para cobranzas: api_aviso_cierre_lote.

            

Nuevo template

Nueva plantilla WhatsApp

Nuevo usuario autorizado

Buscar usuario de Supabase Auth Busque por email, nombre o fragmento del correo y selecciónelo para completar email + user_id.
Acciones
Email User ID Confirmado Último acceso
Debe indicar al menos un email o un user_id.