Stato e Ciclo di Vita dell'Email

Comprendi gli stati di status e gli eventi di tracciamento

Ogni email in Tratto ha uno status (lo stato dell'email) e eventi (cosa le è successo). Comprendi la differenza e come tracciarla.

Status vs Eventi

  • Status: Lo stato attuale dell'email (scheduled, queued, sending, sent, delivered, bounced, complained, failed, skipped, canceled)
  • Eventi: Record discreti di tracciamento (opened, clicked, bounced, complained)

Esempio: Un'email può avere status delivered e anche avere eventi opened, clicked, e clicked di nuovo.

Ciclo di Vita dello Status dell'Email

Un'email progredisce attraverso questi status:

(solo con scheduledAt)
  scheduled ──→ queued ──→ sending ──→ sent ──→ delivered
      │           │           │          │          │
      ▼           ▼           ▼          └────┬─────┘
  canceled     skipped      failed            ▼
  skipped      failed                bounced, complained

Un'email inviata senza scheduledAt parte da queued. Aperture, clic e disiscrizioni sono eventi, non status: non cambiano mai lo status.

Definizioni dello Status

StatusDescrizione
scheduledL'email è programmata per una consegna futura (hai impostato scheduledAt). Passa a queued quando arriva l'ora
queuedL'email è in coda, verrà inviata a breve (minuti)
sendingTratto ha preso in carico l'email e la sta consegnando al provider di posta. Dura pochi secondi
sentL'email è stata consegnata al server di posta, ma non ancora confermata dal server del destinatario
deliveredIl server di posta del destinatario ha confermato la ricezione
bouncedIl server di posta del destinatario ha rifiutato l'email
complainedIl destinatario ha segnalato l'email come spam
failedTratto non ha inviato l'email (un dominio mittente non verificato, un template non pubblicato, un allegato eliminato, un rifiuto del provider di posta, ecc.). Con l'API 0.29.0 o successiva il motivo è in failureReason: vedi Perché un'email è fallita
skippedTratto non ha inviato l'email perché il destinatario si è disiscritto o è nella lista di soppressione. Non è partito niente
canceledHai annullato un'email scheduled con DELETE /v1/emails/:id prima dell'invio

GET /v1/emails?status= filtra per uno qualsiasi di questi valori, sending compreso; se ne possono combinare più separati da virgole (?status=queued,sending).

failed, bounced e complained sono definitivi: niente di quello che arriva dopo li cambia, con l'unica eccezione qui sotto.

Quando la consegna viene interrotta

Se la consegna si interrompe mentre Tratto sta passando l'email al provider di posta (per esempio si ferma il worker che la stava inviando), Tratto non può sapere se il provider l'ha accettata. In quel caso l'email diventa failed e non viene ritentata: Tratto preferisce non inviare un'email piuttosto che inviarla due volte. L'email potrebbe comunque essere arrivata al destinatario. Se in seguito il provider segnala una consegna, un rimbalzo o un reclamo, lo status passa a delivered, bounced o complained.

Un'email che resta in sending per più di qualche minuto è in questa situazione e verrà chiusa come failed quando Tratto la riprende in mano.

Perché un'email è fallita

Richiede l'API 0.29.0 o successiva.

GET /v1/emails/{id} e GET /v1/emails restituiscono failureReason su un'email failed: un codice stabile come template_not_published, provider_rejected o attachment_unavailable. Lo stesso codice arriva come data.reason nell'evento webhook failed, il cui data.error aggiunge una frase leggibile. L'elenco dei codici e il loro significato è in Evento failed. Possono aggiungersi codici nuovi, quindi gestisci anche i valori che non conosci. Le email fallite prima che il campo esistesse non hanno failureReason.

interrupted è l'unico codice non definitivo: vedi Quando la consegna viene interrotta.

Transizioni di Stato

scheduled (solo se scheduledAt è stato impostato)
  ├─→ canceled (DELETE /v1/emails/:id)
  ├─→ skipped (il destinatario si è disiscritto)
  └─→ queued (è arrivata l'ora programmata)
queued
  ├─→ skipped (destinatario disiscritto o soppresso)
  ├─→ failed (l'email non può essere costruita o inviata)
  └─→ sending (Tratto passa l'email al provider di posta)
      ├─→ failed (rifiutata dal provider, o consegna interrotta)
      └─→ sent (il server di posta ha accettato l'email)
          ├─→ delivered (il server del destinatario conferma la consegna)
          │   └─→ bounced, complained
          └─→ bounced, complained

Ottieni lo Status dell'Email

Recupera lo status attuale e i dettagli di un'email.

cURL

curl https://api.tratto.email/v1/emails/email_abc123 \
  -H "Authorization: Bearer tratto_live_..."

Node.js

const response = await fetch('https://api.tratto.email/v1/emails/email_abc123', {
  headers: { 'Authorization': 'Bearer tratto_live_...' },
});
const { data } = await response.json();
console.log('Status:', data.status);
console.log('Creata:', data.createdAt);
console.log('Inviata:', data.sentAt);

Python

import requests

response = requests.get(
  'https://api.tratto.email/v1/emails/email_abc123',
  headers={'Authorization': 'Bearer tratto_live_...'},
)
data = response.json()['data']
print(f"Status: {data['status']}")
print(f"Creata: {data['createdAt']}")

PHP

$tratto = new \Tratto\Client(getenv('TRATTO_API_KEY'));

$email = $tratto->emails->get('email_abc123');
echo "Status: {$email['status']}\n";
echo "Creata: {$email['createdAt']}\n";

Risposta

{
  "data": {
    "id": "email_abc123",
    "status": "delivered",
    "from": "hello@tuodominio.it",
    "to": "user@example.com",
    "subject": "Benvenuto!",
    "createdAt": "2025-06-30T12:00:00Z",
    "sentAt": "2025-06-30T12:00:05Z",
    "deliveredAt": "2025-06-30T12:00:10Z",
    "scheduledAt": null,
    "tags": []
  }
}

Eventi Email

Gli eventi sono record discreti di tracciamento per quello che è successo a un'email dopo l'invio. A differenza dello status (uno stato singolo), un'email può avere molti eventi.

Tipi di Evento

Tipo EventoDescrizione
sentEmail è stata accettata dal server di posta
deliveredServer di posta ha confermato consegna alla mailbox del destinatario
openedDestinatario ha aperto l'email (tracciamento pixel)
clickedDestinatario ha cliccato un link nell'email
bouncedServer di posta ha rifiutato consegna (rimbalzo hard o soft)
complainedDestinatario ha segnalato l'email come spam
unsubscribedDestinatario ha cliccato il link di annullamento iscrizione
failedL'email non è stata inviata; data.reason e data.error dicono perché (richiede l'API 0.29.0 o successiva)

Ottieni Eventi Email

Recupera tutti gli eventi per un'email specifica.

cURL

curl https://api.tratto.email/v1/emails/email_abc123/events \
  -H "Authorization: Bearer tratto_live_..."

Node.js

const response = await fetch('https://api.tratto.email/v1/emails/email_abc123/events', {
  headers: { 'Authorization': 'Bearer tratto_live_...' },
});
const { data } = await response.json();
data.forEach(event => {
  console.log(`${event.type} at ${event.occurredAt}`);
});

Python

import requests

response = requests.get(
  'https://api.tratto.email/v1/emails/email_abc123/events',
  headers={'Authorization': 'Bearer tratto_live_...'},
)
events = response.json()['data']
for event in events:
  print(f"{event['type']} at {event['occurredAt']}")

PHP

$tratto = new \Tratto\Client(getenv('TRATTO_API_KEY'));

$events = $tratto->emails->listEvents('email_abc123');
foreach ($events as $event) {
    echo "{$event['type']} at {$event['occurredAt']}\n";
}

Risposta

{
  "data": [
    {
      "id": "evt_001",
      "type": "sent",
      "emailId": "email_abc123",
      "occurredAt": "2025-06-30T12:00:05Z"
    },
    {
      "id": "evt_002",
      "type": "delivered",
      "emailId": "email_abc123",
      "occurredAt": "2025-06-30T12:00:10Z"
    },
    {
      "id": "evt_003",
      "type": "opened",
      "emailId": "email_abc123",
      "occurredAt": "2025-06-30T12:05:00Z"
    },
    {
      "id": "evt_004",
      "type": "clicked",
      "emailId": "email_abc123",
      "occurredAt": "2025-06-30T12:06:00Z",
      "metadata": {
        "url": "https://tuodominio.it/offerta?ref=email"
      }
    }
  ]
}

Polling vs Webhook

Polling (GET /v1/emails/{id})

Quando usare:

  • Controlla status su richiesta (utente visualizza dettagli email nel tuo dashboard)
  • Scenari a basso volume
  • Verifiche di status singole

Vantaggi:

  • Semplice da implementare
  • Nessuna necessità di infrastruttura webhook

Svantaggi:

  • Non real-time (esegui il polling periodicamente)
  • Rate-limited
  • Latenza più elevata

Esempio:

// Controlla ogni 10 secondi
setInterval(async () => {
  const response = await fetch('https://api.tratto.email/v1/emails/email_abc123', {
    headers: { 'Authorization': 'Bearer tratto_live_...' },
  });
  const { data } = await response.json();
  if (data.status === 'delivered') {
    console.log('Email consegnata!');
    clearInterval();
  }
}, 10000);

Webhook (Push Real-Time)

Quando usare:

  • Elaborazione eventi real-time
  • Scenari ad alto volume
  • Attivare azioni downstream (automazione email, analytics, ecc.)

Vantaggi:

  • Real-time
  • Nessun overhead di polling
  • Efficiente

Svantaggi:

  • Richiede endpoint webhook
  • Deve verificare le firme HMAC
  • Gestire i retry e l'idempotenza

Esempio:

// Il tuo endpoint webhook riceve gli eventi
app.post('/webhooks/tratto', (req, res) => {
  const event = req.body;
  console.log(`Email ${event.emailId} was ${event.type}`);
  
  if (event.type === 'delivered') {
    // Attiva automazione
  }
  
  res.status(200).json({ ok: true });
});

Vedi Webhook per la configurazione.

Tracciare la Consegna Email

Comprendi i Tipi di Rimbalzo

Hard Bounce: Fallimento permanente della consegna

  • Indirizzo email non valido
  • Dominio non esiste
  • Utente non esiste

Soft Bounce: Fallimento temporaneo della consegna

  • Mailbox piena
  • Server temporaneamente non disponibile
  • Messaggio troppo grande

Complaint: Destinatario ha segnalato come spam (non ri-inviare)

Auto-Unsubscribe

Quando un'email rimbalza o è segnalata, Tratto automaticamente:

  1. Aggiorna lo status del contatto a bounced o complained
  2. Crea un evento bounce/complaint
  3. Invia un evento webhook (se configurato)

Puoi quindi:

  • Smettere di inviare a indirizzi con rimbalzo
  • Implementare campagne di re-engagement per indirizzi segnalati
  • Monitorare i tassi di rimbalzo per la salute del dominio

API Riepilogo Status

Ottieni statistiche aggregate su più email.

Coming soon: Endpoint per interrogare gli status email per status, intervallo di date, o tag.


Prossimi Passi


Modifica questa pagina su GitHub

Ultimo aggiornamento