---
title: "Referencia de tipos de evento"
description: "Guía de referencia completa de todos los tipos de evento de webhook de Brevo, con ejemplos de integración con la plataforma de fidelización Tajo"
url: https://tajo.io/es/docs/webhooks-events/event-types/
markdown: https://tajo.io/es/docs/webhooks-events/event-types.md
lang: es-ES
robots: noindex
---

Solicita acceso anticipado

Escribe tu nombre y dirección de correo de trabajo. Te enviaremos un enlace para confirmar tu solicitud de acceso a Tajo.

# Referencia de tipos de evento

Esta referencia completa cubre todos los tipos de evento de webhook disponibles en Brevo, con ejemplos concretos para la integración con la plataforma de fidelización Tajo.

## Eventos de email

### delivered

Se activa cuando un email se entrega correctamente en el buzón del destinatario.

**Ejemplo de payload:**

```json
{
  "event": "delivered",
  "email": "customer@example.com",
  "id": 123456,
  "date": "2024-01-25 14:30:00",
  "ts": 1640995200,
  "message-id": "<202401251430.123456@mail.brevo.com>",
  "template_id": 101,
  "tags": ["loyalty", "points-earned"],
  "sending_ip": "185.107.232.1",
  "event_id": "evt_abc123"
}
```

**Casos de uso en la integración con Tajo:**

- Actualizar la tasa de entregas correctas en los perfiles de cliente
- Lanzar acciones de seguimiento para las campañas de fidelización
- Medir el rendimiento de entrega de los emails por nivel

```javascript
async function handleEmailDelivered(event) {
  const customer = await loyaltyService.getCustomer(event.email);

  // Update delivery stats
  await loyaltyService.updateEngagement(event.email, {
    emailsDelivered: customer.emailsDelivered + 1,
    lastEmailDelivered: new Date(event.date),
    deliveryRate: calculateDeliveryRate(customer)
  });

  // Track loyalty campaign delivery
  if (event.tags.includes('loyalty')) {
    await loyaltyService.trackCampaignMetric('loyalty_email_delivered', {
      email: event.email,
      template_id: event.template_id,
      tier: customer.loyaltyTier
    });
  }
}
```

### opened

Se activa cuando el destinatario abre un email (se registra la carga del píxel de seguimiento).

**Ejemplo de payload:**

```json
{
  "event": "opened",
  "email": "customer@example.com",
  "date": "2024-01-25 15:45:00",
  "ts": 1641000300,
  "message-id": "<202401251430.123456@mail.brevo.com>",
  "template_id": 101,
  "tags": ["loyalty", "tier-upgrade"],
  "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)",
  "geo": {
    "country": "US",
    "region": "CA",
    "city": "San Francisco"
  }
}
```

**Casos de uso en la integración con Tajo:**

- Aumentar la puntuación de interacción del cliente
- Medir la eficacia de las campañas de fidelización
- Activar recompensas basadas en el comportamiento
- Personalizar las comunicaciones futuras

```javascript
async function handleEmailOpened(event) {
  const customer = await loyaltyService.getCustomer(event.email);

  // Significant engagement - boost score
  await loyaltyService.updateEngagement(event.email, {
    emailsOpened: customer.emailsOpened + 1,
    lastEmailOpened: new Date(event.date),
    engagementScore: customer.engagementScore + 5,
    preferredDevice: getDeviceType(event['user-agent'])
  });

  // Reward engagement for loyalty members
  if (event.tags.includes('loyalty') && customer.loyaltyTier) {
    await loyaltyService.awardEngagementBonus(event.email, {
      type: 'email_engagement',
      points: getEngagementPoints(customer.loyaltyTier),
      reason: 'Email opened'
    });
  }

  // Track timing patterns for optimization
  await loyaltyService.recordEngagementTime(event.email, {
    campaign: event.template_id,
    openTime: new Date(event.date),
    timezone: getTimezone(event.geo)
  });
}
```

### clicked

Se activa cuando el destinatario hace clic en un enlace del email.

**Ejemplo de payload:**

```json
{
  "event": "clicked",
  "email": "customer@example.com",
  "date": "2024-01-25 16:20:00",
  "ts": 1641002400,
  "message-id": "<202401251430.123456@mail.brevo.com>",
  "template_id": 101,
  "tags": ["loyalty", "rewards-reminder"],
  "link": "https://yourdomain.com/rewards?utm_source=brevo&utm_campaign=loyalty",
  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
```

**Casos de uso en la integración con Tajo:**

- Medir el rendimiento del embudo de conversión
- Conceder bonificaciones por clic
- Identificar el contenido de mayor valor
- Optimizar el recorrido del email al sitio web

```javascript
async function handleEmailClicked(event) {
  const customer = await loyaltyService.getCustomer(event.email);
  const clickedUrl = new URL(event.link);

  // High-value engagement
  await loyaltyService.updateEngagement(event.email, {
    emailsClicked: customer.emailsClicked + 1,
    lastEmailClicked: new Date(event.date),
    engagementScore: customer.engagementScore + 15,
    clickThroughRate: calculateCTR(customer)
  });

  // Track specific link types
  if (clickedUrl.pathname.includes('/rewards')) {
    await loyaltyService.trackEvent(event.email, 'Rewards Page Clicked', {
      source: 'email',
      campaign: event.template_id,
      utm_campaign: clickedUrl.searchParams.get('utm_campaign')
    });

    // Award exploration bonus
    await loyaltyService.awardEngagementBonus(event.email, {
      type: 'rewards_exploration',
      points: 10,
      reason: 'Clicked rewards link'
    });
  }

  // Track product interest
  if (clickedUrl.pathname.includes('/products')) {
    const productId = extractProductId(clickedUrl);
    await loyaltyService.trackProductInterest(event.email, productId, {
      source: 'email_click',
      timestamp: new Date(event.date)
    });
  }
}
```

### bounced / hard\_bounced

Se activa cuando un email rebota (fallo temporal) o rebota de forma permanente (hard bounce).

**Ejemplo de payload:**

```json
{
  "event": "hard_bounced",
  "email": "invalid@example.com",
  "date": "2024-01-25 14:35:00",
  "ts": 1640995500,
  "message-id": "<202401251430.123456@mail.brevo.com>",
  "template_id": 101,
  "tags": ["loyalty"],
  "reason": "550 5.1.1 User unknown",
  "bounce_type": "hard"
}
```

**Casos de uso en la integración con Tajo:**

- Actualizar el estado de validez del email
- Cambiar a otros canales de comunicación
- Depurar la base de datos de clientes
- Evitar nuevos envíos a direcciones no válidas

```javascript
async function handleEmailBounced(event) {
  const isHardBounce = event.event === 'hard_bounced' || event.bounce_type === 'hard';

  if (isHardBounce) {
    // Permanent failure - mark email as invalid
    await loyaltyService.updateCustomerStatus(event.email, {
      emailStatus: 'invalid',
      emailBounced: true,
      bounceReason: event.reason,
      lastBounce: new Date(event.date),
      communicationPreference: 'sms' // Switch to SMS if available
    });

    // Remove from email marketing lists
    await loyaltyService.removeFromEmailMarketing(event.email);

    // Suggest phone verification
    const customer = await loyaltyService.getCustomer(event.email);
    if (customer?.phone) {
      await loyaltyService.suggestPhoneVerification(customer.phone);
    }

  } else {
    // Soft bounce - temporary issue
    await loyaltyService.updateEngagement(event.email, {
      softBounceCount: customer.softBounceCount + 1,
      lastSoftBounce: new Date(event.date)
    });

    // Retry logic for soft bounces
    if (customer.softBounceCount < 5) {
      await loyaltyService.scheduleEmailRetry(event.email, event.template_id);
    }
  }
}
```

### spam

Se activa cuando el destinatario marca un email como spam.

**Ejemplo de payload:**

```json
{
  "event": "spam",
  "email": "customer@example.com",
  "date": "2024-01-25 17:10:00",
  "ts": 1641005400,
  "message-id": "<202401251430.123456@mail.brevo.com>",
  "template_id": 101,
  "tags": ["loyalty", "promotional"]
}
```

**Casos de uso en la integración con Tajo:**

- Detener de inmediato las comunicaciones por email
- Revisar y mejorar el contenido de los emails
- Analizar los patrones de spam por segmento
- Aplicar procesos de opt-in más estrictos

```javascript
async function handleEmailSpam(event) {
  // Immediately disable email marketing
  await loyaltyService.updateCustomerPreferences(event.email, {
    emailMarketing: false,
    marketingEnabled: false,
    spamReported: true,
    spamReportDate: new Date(event.date)
  });

  // Alert marketing team for review
  await loyaltyService.alertMarketing('spam_complaint', {
    email: event.email,
    template: event.template_id,
    campaign_tags: event.tags,
    severity: 'high'
  });

  // Analyze spam patterns
  await loyaltyService.analyzeSpamPattern({
    template_id: event.template_id,
    tags: event.tags,
    customer_segment: await loyaltyService.getCustomerSegment(event.email)
  });

  // Consider account review if multiple spam reports
  const customer = await loyaltyService.getCustomer(event.email);
  if (customer.spamReports > 2) {
    await loyaltyService.flagForReview(event.email, 'multiple_spam_reports');
  }
}
```

## Eventos de SMS

### sms\_delivered

Se activa cuando un SMS se entrega correctamente en el teléfono del destinatario.

**Ejemplo de payload:**

```json
{
  "event": "sms_delivered",
  "phone": "+1234567890",
  "date": "2024-01-25 14:45:00",
  "ts": 1640996700,
  "message-id": "sms_abc123",
  "tags": ["loyalty", "points-alert"],
  "sender": "TAJO",
  "content": "🎉 Great news! You earned 150 points from your recent purchase. Total: 1,250 points."
}
```

**Casos de uso en la integración con Tajo:**

- Confirmar que el SMS se ha entregado
- Medir las tasas de interacción por SMS
- Validar que el número de teléfono es correcto
- Vigilar el rendimiento de entrega de cada operador

```javascript
async function handleSMSDelivered(event) {
  const customer = await loyaltyService.getCustomerByPhone(event.phone);

  await loyaltyService.updateEngagement(customer.email, {
    smsDelivered: customer.smsDelivered + 1,
    lastSMSDelivered: new Date(event.date),
    smsDeliveryRate: calculateSMSDeliveryRate(customer),
    phoneStatus: 'valid'
  });

  // Track loyalty SMS performance
  if (event.tags.includes('loyalty')) {
    await loyaltyService.trackCampaignMetric('loyalty_sms_delivered', {
      phone: event.phone,
      content_type: getSMSContentType(event.content),
      customer_tier: customer.loyaltyTier
    });
  }
}
```

### sms\_failed

Se activa cuando falla la entrega de un SMS.

**Ejemplo de payload:**

```json
{
  "event": "sms_failed",
  "phone": "+1234567890",
  "date": "2024-01-25 14:32:00",
  "ts": 1640996320,
  "message-id": "sms_def456",
  "tags": ["loyalty", "urgent"],
  "sender": "TAJO",
  "reason": "Invalid phone number format",
  "error_code": "30006"
}
```

**Casos de uso en la integración con Tajo:**

- Actualizar la validez del número de teléfono
- Cambiar a las notificaciones por email
- Depurar la base de datos de números de teléfono
- Avisar al equipo de atención al cliente para una verificación manual

```javascript
async function handleSMSFailed(event) {
  const customer = await loyaltyService.getCustomerByPhone(event.phone);

  await loyaltyService.updateCustomerStatus(customer.email, {
    phoneStatus: 'invalid',
    smsEnabled: false,
    smsFailureReason: event.reason,
    lastSMSFailure: new Date(event.date),
    communicationPreference: 'email'
  });

  // For urgent loyalty notifications, fall back to email
  if (event.tags.includes('urgent') || event.tags.includes('loyalty')) {
    await loyaltyService.sendEmailFallback(customer.email, {
      originalSMS: event.content,
      reason: 'SMS delivery failed'
    });
  }

  // Flag for phone number verification
  await loyaltyService.flagForPhoneVerification(customer.email);
}
```

### sms\_reply

Se activa cuando el destinatario responde a un SMS.

**Ejemplo de payload:**

```json
{
  "event": "sms_reply",
  "phone": "+1234567890",
  "date": "2024-01-25 15:20:00",
  "ts": 1641000000,
  "message-id": "sms_reply_123",
  "text": "BALANCE",
  "original_message_id": "sms_abc123"
}
```

**Casos de uso en la integración con Tajo:**

- Procesar los comandos del programa de fidelización
- Atender las solicitudes de atención al cliente
- Actualizar las preferencias de comunicación
- Lanzar respuestas automáticas

```javascript
async function handleSMSReply(event) {
  const customer = await loyaltyService.getCustomerByPhone(event.phone);
  const replyText = event.text.toUpperCase().trim();

  // High engagement - customer actively participating
  await loyaltyService.updateEngagement(customer.email, {
    smsReplies: customer.smsReplies + 1,
    lastSMSReply: new Date(event.date),
    engagementScore: customer.engagementScore + 10
  });

  // Process loyalty commands
  switch (replyText) {
    case 'BALANCE':
      await loyaltyService.sendPointsBalance(event.phone);
      break;

    case 'REWARDS':
      await loyaltyService.sendAvailableRewards(event.phone, customer.loyaltyTier);
      break;

    case 'TIER':
      await loyaltyService.sendTierInfo(event.phone, customer);
      break;

    case 'HELP':
      await loyaltyService.sendSMSHelp(event.phone);
      break;

    case 'STOP':
    case 'UNSUBSCRIBE':
      await loyaltyService.unsubscribeFromSMS(event.phone);
      break;

    default:
      // Forward to customer service
      await loyaltyService.forwardToSupport(customer.email, {
        channel: 'sms',
        message: event.text,
        timestamp: new Date(event.date)
      });
  }
}
```

## Eventos de contacto

### contact\_created

Se activa cuando se añade un contacto nuevo a Brevo.

**Ejemplo de payload:**

```json
{
  "event": "contact_created",
  "email": "newcustomer@example.com",
  "date": "2024-01-25 13:15:00",
  "ts": 1640992500,
  "attributes": {
    "FIRSTNAME": "John",
    "LASTNAME": "Doe",
    "LOYALTY_ID": "LYL-2024-001",
    "LOYALTY_TIER": "Bronze",
    "LOYALTY_POINTS": 0
  },
  "lists": [1, 5]
}
```

**Casos de uso en la integración con Tajo:**

- Lanzar campañas de bienvenida
- Dar de alta al cliente en el programa de fidelización
- Iniciar el recorrido del cliente
- Conceder puntos de bienvenida por el registro

```javascript
async function handleContactCreated(event) {
  const isLoyaltyMember = event.attributes?.LOYALTY_ID;

  if (isLoyaltyMember) {
    // New loyalty member - trigger welcome flow
    await loyaltyService.triggerWelcomeFlow(event.email, {
      loyaltyId: event.attributes.LOYALTY_ID,
      tier: event.attributes.LOYALTY_TIER || 'Bronze',
      signupBonus: 500
    });

    // Award signup bonus
    await loyaltyService.awardPoints(event.email, {
      amount: 500,
      reason: 'Welcome bonus',
      type: 'signup_bonus'
    });

    // Schedule onboarding emails
    await loyaltyService.scheduleOnboardingSequence(event.email, {
      tier: event.attributes.LOYALTY_TIER,
      preferences: event.attributes
    });
  }

  // Track signup source
  await loyaltyService.trackSignupSource(event.email, {
    lists: event.lists,
    attributes: event.attributes,
    timestamp: new Date(event.date)
  });
}
```

### contact\_updated

Se activa cuando se actualiza la información de un contacto.

**Ejemplo de payload:**

```json
{
  "event": "contact_updated",
  "email": "customer@example.com",
  "date": "2024-01-25 16:45:00",
  "ts": 1641003900,
  "updated_attributes": {
    "LOYALTY_POINTS": 1250,
    "LOYALTY_TIER": "Silver",
    "TOTAL_SPENT": 899.99
  },
  "previous_attributes": {
    "LOYALTY_POINTS": 750,
    "LOYALTY_TIER": "Bronze",
    "TOTAL_SPENT": 549.99
  }
}
```

**Casos de uso en la integración con Tajo:**

- Detectar los ascensos de nivel
- Seguir los cambios en el saldo de puntos
- Comprobar si el perfil está completo
- Lanzar campañas específicas por nivel

```javascript
async function handleContactUpdated(event) {
  const updated = event.updated_attributes;
  const previous = event.previous_attributes;

  // Check for tier upgrade
  if (updated.LOYALTY_TIER && updated.LOYALTY_TIER !== previous.LOYALTY_TIER) {
    await loyaltyService.handleTierUpgrade(event.email, {
      previousTier: previous.LOYALTY_TIER,
      newTier: updated.LOYALTY_TIER,
      pointsBalance: updated.LOYALTY_POINTS
    });

    // Send congratulations
    await loyaltyService.sendTierUpgradeEmail(event.email, {
      newTier: updated.LOYALTY_TIER,
      benefits: loyaltyService.getTierBenefits(updated.LOYALTY_TIER)
    });
  }

  // Track significant point increases
  const pointIncrease = updated.LOYALTY_POINTS - previous.LOYALTY_POINTS;
  if (pointIncrease > 0) {
    await loyaltyService.trackPointsEarned(event.email, {
      amount: pointIncrease,
      newTotal: updated.LOYALTY_POINTS,
      source: 'profile_update'
    });
  }

  // Monitor spending milestones
  if (updated.TOTAL_SPENT > previous.TOTAL_SPENT) {
    await loyaltyService.checkSpendingMilestones(event.email, {
      currentSpend: updated.TOTAL_SPENT,
      previousSpend: previous.TOTAL_SPENT
    });
  }
}
```

## Buenas prácticas para procesar eventos

### 1. Gestión de la idempotencia

```javascript
class WebhookProcessor {
  constructor() {
    this.processedEvents = new Set();
  }

  async processEvent(event) {
    const eventKey = `${event.event}_${event.email}_${event.ts}`;

    if (this.processedEvents.has(eventKey)) {
      console.log('Duplicate event ignored:', eventKey);
      return;
    }

    this.processedEvents.add(eventKey);

    try {
      await this.handleEvent(event);
    } catch (error) {
      this.processedEvents.delete(eventKey); // Allow retry
      throw error;
    }
  }
}
```

### 2. Orden de los eventos

```javascript
async function processEventInSequence(event) {
  const customer = await loyaltyService.getCustomer(event.email);
  const lastProcessedTime = customer.lastWebhookProcessed || 0;

  // Ensure events are processed in chronological order
  if (event.ts < lastProcessedTime) {
    console.warn('Out-of-order event received, queuing for later processing');
    await loyaltyService.queueEventForLaterProcessing(event);
    return;
  }

  await handleWebhookEvent(event);

  // Update last processed timestamp
  await loyaltyService.updateCustomer(event.email, {
    lastWebhookProcessed: event.ts
  });
}
```

### 3. Procesamiento por lotes

```javascript
class BatchEventProcessor {
  constructor() {
    this.eventBatch = [];
    this.batchSize = 100;
    this.flushInterval = 5000; // 5 seconds

    setInterval(() => this.flushBatch(), this.flushInterval);
  }

  addEvent(event) {
    this.eventBatch.push(event);

    if (this.eventBatch.length >= this.batchSize) {
      this.flushBatch();
    }
  }

  async flushBatch() {
    if (this.eventBatch.length === 0) return;

    const batch = this.eventBatch.splice(0);

    try {
      await loyaltyService.processBatchEvents(batch);
    } catch (error) {
      console.error('Batch processing failed:', error);
      // Re-queue failed events
      this.eventBatch.unshift(...batch);
    }
  }
}
```

## Próximos pasos

- **Guía de seguridad de webhooks** - Buenas prácticas de seguridad
- **[Probar webhooks](https://tajo.io/es/docs/testing-debug/)** - Pruebas y depuración
- **Analítica de webhooks** - Monitorización del rendimiento
- **[Integración de la plataforma](https://tajo.io/es/docs/platform-integration/tajo-brevo-integration)** - Guía de integración completa
