Skip to main content
POST
/
marketplace
/
messaging
/
send-email
Enviar email
curl --request POST \
  --url http://api.gu1.ai/marketplace/messaging/send-email \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "to": "<string>",
  "fromEmail": "<string>",
  "fromSenderId": {},
  "templateParams": {},
  "templateId": {},
  "subject": "<string>",
  "htmlBody": "<string>",
  "textBody": "<string>"
}
'

Documentation Index

Fetch the complete documentation index at: https://docs.gu1.ai/llms.txt

Use this file to discover all available pages before exploring further.

Envía un email transaccional para la organización autenticada. Requiere la integración Email en Marketplace y proveedor configurado. Requisitos generales en Resumen de mensajería.

Endpoint

POST https://api.gu1.ai/marketplace/messaging/send-email

Cabeceras

Authorization: Bearer TU_API_KEY
Content-Type: application/json
X-Organization-ID: <uuid>   # opcional si hay varias orgs

Cuerpo de la petición

Común

to
string
required
Email del destinatario.
fromEmail
string
Dirección completa de envío (ej. noreply@mi-dominio.com). El dominio debe estar registrado y verificado en tu organización (Configuración → Email → Dominios). No hace falta dar de alta esa dirección exacta en Remitentes si el dominio ya está verificado. Excluyente con fromSenderId.
fromSenderId
string (UUID)
UUID del remitente en Configuración → Email → Remitentes. Excluyente con fromEmail.
Si no envías fromEmail ni fromSenderId, la API usa el remitente por defecto de la plataforma Gu1. Eso es el comportamiento esperado, no un error.

Remitente personalizado (fromEmail)

Si envías fromEmail, por ejemplo example@mi-dominio.com, la API valida el dominio (mi-dominio.com) antes de intentar el envío. La respuesta es siempre 400 con { "success": false, "error": "<mensaje en inglés>" }; no se envía el correo hasta que el dominio esté verificado.
SituaciónQué devuelve la API
El dominio nunca se agregó en Gu1 para tu orgDomain "mi-dominio.com" is not registered in Gu1. Add and verify it under Settings → Email → Domains before using sender "example@mi-dominio.com".
El dominio está en Gu1 pero aún no verificaste DNS (o falló Verificar)Domain "mi-dominio.com" is not verified yet. Complete DNS records and click Verify under Settings → Email → Domains.
El dominio está verificadoLa petición sigue; puedes usar cualquier local-part en ese dominio (example@…, noreply@…, etc.) sin crear la fila en Remitentes. Si la dirección existe en Remitentes, se usa el nombre configurado allí.
Ejemplo de rechazo (dominio no verificado):
{
  "success": false,
  "error": "Domain \"mi-dominio.com\" is not verified yet. Complete DNS records and click Verify under Settings → Email → Domains."
}
templateParams
object
Valores para {{placeholders}} en asunto, HTML, texto o plantilla. Por defecto {}.

Modo A — Plantilla

templateId
string (UUID)
required
Plantilla con canal email.
No envíes htmlBody ni textBody.
subject
string
Opcional si la plantilla define asunto o queda vacío tras variables.

Modo B — Contenido inline

Sin templateId.
subject
string
required
Asunto; admite {{variables}} con templateParams.
htmlBody
string
HTML (~500k caracteres máx.).
textBody
string
Texto plano; si no hay HTML se envuelve en HTML mínimo.
Obligatorio al menos uno de htmlBody o textBody.

Ejemplo — plantilla

{
  "to": "usuario@ejemplo.com",
  "templateId": "550e8400-e29b-41d4-a716-446655440000",
  "templateParams": { "name": "Ada", "token": "482910" },
  "fromEmail": "noreply@tudominio.com"
}

Ejemplo — HTML con variables

{
  "to": "usuario@ejemplo.com",
  "subject": "Tu código: {{token}}",
  "htmlBody": "<p>Tu código es <strong>{{token}}</strong></p>",
  "templateParams": { "token": "482910" }
}

Errores y códigos HTTP

En la mayoría de los casos la API responde con JSON { "success": false, "error": "<mensaje en inglés>" }. Los cuerpos inválidos pueden devolver otro formato (p. ej. detalle Zod) con 400. Todos los error de negocio van en inglés.
SituaciónHTTPEjemplo de error (texto real de la API)
Integración Email desactivada para la org400Email integration is not active. Enable Email (global_sender_email) in Applications (Marketplace) for this organization.
Servidor sin URL del proveedor de mensajería400MS_PROVIDER_URL is not configured on the server. Configure the messaging provider to send email.
Precio > 0 y sin saldo ni cupo de pack400Insufficient balance for this send (cost … credits). … (ver respuesta completa)
Envío OK pero fallo al registrar cobro400Insufficient balance to record billing for this send. Current balance (…) is below required (…). …
templateId y cuerpo inline a la vez400 (validación)Use either templateId + templateParams, or htmlBody/textBody only — not both.
Sin plantilla ni cuerpo400 (validación)Provide templateId or htmlBody/textBody.
Modo inline sin subject400 (validación)subject is required when not using a template.
Plantilla inexistente u otra organización404Template not found or not accessible for this organization.
Plantilla con otro canal (no email)400Template channel is "<channel>"; email is required.
Plantilla sin asunto tras variables400The template has no subject or it is empty after replacing variables. Send subject in the request body or set the subject on the template.
fromSenderId y fromEmail juntos400Send only one of fromSenderId or fromEmail, not both.
fromSenderId desconocido400fromSenderId does not match a sender for this organization. Check Settings → Email → Senders.
Dominio del fromEmail no registrado en la org400Domain "…" is not registered in Gu1. Add and verify it under Settings → Email → Domains before using sender "…".
Dominio registrado pero sin verificar (DNS)400Domain "…" is not verified yet. Complete DNS records and click Verify under Settings → Email → Domains.
Asunto vacío tras {{…}} (inline)400Subject is empty after replacing variables.
Cuerpo vacío tras render400htmlBody or textBody is empty after rendering.
Sin organización en sesión401{ "error": "Organization ID not found" } (sin campo success)
Tras pasar validaciones, el proveedor externo puede devolver { "success": false, "error": "…" } con 200; comprueba siempre success y error.