# Invia un’email

> Invia email con POST /emails, tra regole del mittente, destinatari, contenuto, template, tracciamento, risposta, eventi webhook e tutti i codici di errore.

Questa guida spiega ogni parte di una richiesta `POST /emails` e cosa ne fa Emailit, dall’indirizzo From agli errori che puoi ricevere. Per il riferimento completo dei parametri, vedi [Invia un’email](/it/docs/api-reference/emails/send/) nel riferimento API.

## Prima di iniziare

- Un dominio di invio verificato nel workspace. Vedi [Aggiungi un dominio](/it/docs/domains/add-a-domain/).
- Una chiave API con permesso **Full Access** o **Sending Only**. Vedi [Chiavi API](/it/docs/developers/api-keys/).
- L’accesso alla produzione, se invii a persone che non sono membri del workspace. Vedi [Accesso alla produzione](/it/docs/workspaces/production-access/).
- Crediti sufficienti per tutti i destinatari (1 credito ciascuno).

## Invia un’email di base

**cURL**

```bash
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme Billing <billing@acme.com>",
    "to": ["ada@example.com", "Grace Hopper <grace@example.com>"],
    "cc": "accounts@example.com",
    "reply_to": "support@acme.com",
    "subject": "Your invoice for October",
    "html": "<p>Your invoice is ready.</p>",
    "text": "Your invoice is ready."
  }'
```

**Node.js**

```javascript
import { Emailit } from '@emailit/node';

const emailit = new Emailit(process.env.EMAILIT_API_KEY);

const email = await emailit.emails.send({
  from: 'Acme Billing <billing@acme.com>',
  to: ['ada@example.com', 'Grace Hopper <grace@example.com>'],
  cc: 'accounts@example.com',
  reply_to: 'support@acme.com',
  subject: 'Your invoice for October',
  html: '<p>Your invoice is ready.</p>',
  text: 'Your invoice is ready.',
});
```

**Python**

```python
import os
from emailit import EmailitClient

client = EmailitClient(os.environ["EMAILIT_API_KEY"])

email = client.emails.send({
    "from": "Acme Billing <billing@acme.com>",
    "to": ["ada@example.com", "Grace Hopper <grace@example.com>"],
    "cc": "accounts@example.com",
    "reply_to": "support@acme.com",
    "subject": "Your invoice for October",
    "html": "<p>Your invoice is ready.</p>",
    "text": "Your invoice is ready.",
})
```

**PHP**

```php
$emailit = Emailit::client(getenv('EMAILIT_API_KEY'));

$email = $emailit->emails()->send([
    'from' => 'Acme Billing <billing@acme.com>',
    'to' => ['ada@example.com', 'Grace Hopper <grace@example.com>'],
    'cc' => 'accounts@example.com',
    'reply_to' => 'support@acme.com',
    'subject' => 'Your invoice for October',
    'html' => '<p>Your invoice is ready.</p>',
    'text' => 'Your invoice is ready.',
]);
```

## Imposta l’indirizzo From

`from` è obbligatorio e accetta un indirizzo in una di queste forme:

- `billing@acme.com`
- `Acme Billing <billing@acme.com>`, oppure con le virgolette, `"Acme, Inc." <billing@acme.com>`

Il dominio dopo la `@` deve essere un dominio di invio verificato nello stesso workspace:

- **La corrispondenza è esatta.** I domini vengono confrontati senza distinzione tra maiuscole e minuscole, ma `mail.acme.com` e `acme.com` sono domini diversi. Aggiungi e verifica ogni sottodominio da cui invii.
- **Va bene qualsiasi parte locale.** Non ti serve una casella per `billing@` o `no-reply@`.
- **I domini in attesa non possono inviare.** Un dominio ancora in attesa di revisione (**Pending verification**) viene trattato come non verificato.
- **Le chiavi limitate restano sul loro dominio.** Una chiave **Sending Only** limitata a un dominio può inviare solo da quel dominio.
- **I domini in pausa sono bloccati.** Se la [salute degli invii](/it/docs/deliverability/sending-health/) ha messo in pausa il dominio, gli invii da quel dominio vengono rifiutati finché la pausa non viene rimossa.

## Aggiungi i destinatari

`to` è obbligatorio. `cc` e `bcc` sono facoltativi. Ogni campo accetta una stringa o un array di stringhe, con o senza nomi visualizzati, e contiene fino a 50 indirizzi. Una stringa può contenere più indirizzi separati da virgole; usa un array quando un nome visualizzato contiene a sua volta una virgola.

Emailit rimuove i duplicati tra `to`, `cc` e `bcc` (senza distinzione tra maiuscole e minuscole), poi crea **un’email per ogni destinatario unico**, ciascuna con il proprio ID `em_`. Ogni copia ha gli stessi header `To` e `Cc`, così i destinatari vedono la conversazione come al solito, e i destinatari in `Bcc` non compaiono mai negli header di nessuna copia.

Quando una richiesta ha più di un destinatario, la risposta include una mappa `ids` dal destinatario all’ID dell’email. `id` è l’email del primo destinatario.

```json
{
  "object": "email",
  "id": "em_33VtK8mRq1xZp7LwN4cY2bHsDfa",
  "ids": {
    "ada@example.com": "em_33VtK8mRq1xZp7LwN4cY2bHsDfa",
    "grace@example.com": "em_33VtK8nB5rTq0YxW3mJk9PdLsUe",
    "accounts@example.com": "em_33VtK8nQ2wErT6yU8iOp4AsDf7g"
  }
}
```

Ogni destinatario costa 1 credito e rientra nei [limiti di frequenza](/it/docs/api-reference/rate-limits/). Un destinatario con una [soppressione](/it/docs/suppressions/) di tipo `recipient` viene accettato e poi segnato come `suppressed` invece di essere consegnato.

## Scrivi il contenuto

| Campo | Regole |
| --- | --- |
| `subject` | Obbligatorio, a meno che non lo fornisca un template. I caratteri non ASCII vengono codificati per te. |
| `html` | Il corpo HTML. Ti serve `html`, `text` o entrambi, a meno che non li fornisca un template. |
| `text` | Il corpo in testo semplice. Invialo insieme a `html`: alcuni client e filtri antispam preferiscono i messaggi con entrambi. |
| `reply_to` | Una stringa o un array di indirizzi a cui devono arrivare le risposte. |

Se `reply_to` indica lo stesso indirizzo di `from`, Emailit rimuove l’header `Reply-To`, perché non aggiunge nulla e alcuni filtri antispam lo penalizzano.

## Invia con un template

Imposta `template` sull’alias di un template o su un ID `tem_`, e passa `variables` per i segnaposto [Temple](/it/docs/templates/temple/) che contiene.

- **Un alias** invia la versione attualmente pubblicata per quell’alias. Se nessuna versione è pubblicata, la richiesta non riesce con `404`.
- **Un ID `tem_`** invia esattamente quella versione, pubblicata o no. Usalo per testare una versione in bozza prima di pubblicarla.

I campi della richiesta hanno la precedenza sul template: un `subject`, `html` o `text` che invii sostituisce il valore del template. Se non invii `reply_to`, viene usato il Reply-To del template. `from` è sempre obbligatorio nella richiesta. Vedi [Versioni dei template](/it/docs/templates/versions/) per come funziona la pubblicazione.

**cURL**

```bash
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <hello@acme.com>",
    "to": "ada@example.com",
    "template": "welcome-email",
    "variables": {
      "first_name": "Ada",
      "plan": "Pro",
      "activation_url": "https://acme.com/activate?token=8f3k2"
    }
  }'
```

**Node.js**

```javascript
const email = await emailit.emails.send({
  from: 'Acme <hello@acme.com>',
  to: 'ada@example.com',
  template: 'welcome-email',
  variables: {
    first_name: 'Ada',
    plan: 'Pro',
    activation_url: 'https://acme.com/activate?token=8f3k2',
  },
});
```

**Python**

```python
email = client.emails.send({
    "from": "Acme <hello@acme.com>",
    "to": "ada@example.com",
    "template": "welcome-email",
    "variables": {
        "first_name": "Ada",
        "plan": "Pro",
        "activation_url": "https://acme.com/activate?token=8f3k2",
    },
})
```

**PHP**

```php
$email = $emailit->emails()->send([
    'from' => 'Acme <hello@acme.com>',
    'to' => 'ada@example.com',
    'template' => 'welcome-email',
    'variables' => [
        'first_name' => 'Ada',
        'plan' => 'Pro',
        'activation_url' => 'https://acme.com/activate?token=8f3k2',
    ],
]);
```

`variables` funziona anche senza template: Emailit elabora i segnaposto Temple nei campi `subject`, `html` e `text` che invii direttamente.

## Controlla il tracciamento

Per impostazione predefinita, ogni email segue le impostazioni **Track loads** e **Track clicks** del suo dominio di invio. Puoi sovrascriverle per singola email con `tracking`:

- `"tracking": true` o `false` attiva o disattiva sia il tracciamento dei caricamenti (aperture) sia quello dei clic.
- `"tracking": { "loads": true, "clicks": false }` li imposta separatamente.

Il tracciamento funziona solo quando il CNAME di tracciamento del dominio è verificato. Senza, l’email viene inviata senza tracciamento e la richiesta riesce comunque. L’oggetto `tracking` nella risposta mostra le impostazioni effettivamente applicate. Vedi [Tracciamento di aperture e clic](/it/docs/tracking/).

## Aggiungi header e metadati

Usa `headers` per gli header email personalizzati, come `List-Unsubscribe`, e `meta` per le tue coppie chiave-valore di tipo stringa. Emailit salva `meta` con l’email e lo include negli eventi webhook. Vedi [Header e metadati](/it/docs/email-api/headers-and-metadata/).

Per allegare file, programmare l’invio o rendere sicuri i nuovi tentativi, vedi [Allegati](/it/docs/email-api/attachments/), [Programmazione](/it/docs/email-api/scheduling/) e [Idempotenza](/it/docs/email-api/idempotency/).

## Leggi la risposta

Una richiesta riuscita restituisce `200`:

| Campo | Descrizione |
| --- | --- |
| `object` | Sempre `email`. |
| `id` | L’ID `em_` dell’email del primo destinatario. |
| `ids` | Mappa dall’indirizzo del destinatario all’ID dell’email. Presente solo quando ci sono più destinatari. |
| `token` | Token interno della prima email, usato anche nel suo Message-ID. |
| `message_id` | L’header `Message-ID` della prima email, nella forma `<token@your-domain>`. |
| `from` | L’indirizzo From così come l’hai inviato. |
| `to` | Gli indirizzi `to`, senza nomi visualizzati. |
| `cc`, `bcc` | Gli indirizzi `cc` e `bcc`. Presenti solo se li hai inviati. |
| `subject` | L’oggetto finale, dopo l’elaborazione del template. |
| `status` | `accepted`, oppure `scheduled` quando l’email ha un orario di invio futuro. |
| `scheduled_at` | L’orario di invio in ISO 8601, oppure `null`. |
| `created_at` | Quando è stata creata l’email. |
| `tracking` | Le impostazioni `loads` e `clicks` applicate. |

Salva l’`id` (o la mappa `ids`) per poter associare gli eventi webhook successivi e recuperare l’email con [Recupera un’email](/it/docs/api-reference/emails/get/).

## Eventi

L’email di ogni destinatario genera i propri eventi:

1. [`email.accepted`](/it/docs/webhooks/events/email/accepted/) subito dopo la richiesta, oppure [`email.scheduled`](/it/docs/webhooks/events/email/scheduled/) se ha un orario di invio futuro.
2. Gli eventi di consegna man mano che l’email attraversa la pipeline: [`email.delivered`](/it/docs/webhooks/events/email/delivered/), [`email.attempted`](/it/docs/webhooks/events/email/attempted/) (errore temporaneo, verrà ritentata), [`email.bounced`](/it/docs/webhooks/events/email/bounced/), [`email.failed`](/it/docs/webhooks/events/email/failed/), [`email.rejected`](/it/docs/webhooks/events/email/rejected/) o [`email.suppressed`](/it/docs/webhooks/events/email/suppressed/). Un’email trattenuta per revisione genera `email.held`.
3. Gli eventi di engagement, se il tracciamento è attivo: [`email.loaded`](/it/docs/webhooks/events/email/loaded/) ed [`email.clicked`](/it/docs/webhooks/events/email/clicked/). Le segnalazioni di spam generano [`email.complained`](/it/docs/webhooks/events/email/complained/).

Vedi [Stati delle email](/it/docs/logs/email-statuses/) per il significato di ogni stato.

## Errori

Gli errori di convalida restituiscono l’elenco di tutti i problemi trovati:

```json
{
  "error": "Validation failed",
  "validation_errors": [
    "Missing required field: subject",
    "Invalid to email address at index 1: grace@"
  ]
}
```

| Stato | `error` | Causa | Soluzione |
| --- | --- | --- | --- |
| `400` | `Validation failed` | Manca un campo obbligatorio, un indirizzo non è valido, un campo ha più di 50 destinatari o un allegato non è valido. | Correggi ogni elemento di `validation_errors`. |
| `400` | `Invalid Idempotency-Key` | L’header `Idempotency-Key` ha un formato non valido. | Usa da 1 a 256 lettere, cifre, `-` o `_`. Vedi [Idempotenza](/it/docs/email-api/idempotency/). |
| `401` | `Unauthorized` | La chiave API manca o non è valida. | Invia `Authorization: Bearer` con una chiave valida. |
| `402` | `Insufficient credits` | Il workspace non può pagare per tutti i destinatari. | [Acquista crediti](/it/docs/billing/credits/) o attiva la [ricarica automatica](/it/docs/billing/auto-refill/). |
| `403` | `Workspace not verified` | Il workspace è in modalità sandbox e un destinatario non è un membro del workspace. `code` è `unverified_workspace_recipient` e `blocked_recipients` elenca gli indirizzi. | [Richiedi l’accesso alla produzione](/it/docs/workspaces/production-access/), oppure fai i test con gli indirizzi dei membri. |
| `403` | `Domain not authorized` | La chiave API è limitata a un altro dominio di invio. | Invia dal dominio della chiave, o usa una chiave senza limitazione di dominio. |
| `403` | `Domain paused` | La salute degli invii ha messo in pausa il dominio From. | Vedi [Salute degli invii](/it/docs/deliverability/sending-health/). |
| `404` | `Template not found` | L’alias non ha una versione pubblicata, oppure l’ID `tem_` non esiste in questo workspace. | Pubblica una versione o controlla l’ID. |
| `409` | `Idempotency key in progress` | Un’altra richiesta con la stessa chiave è ancora in corso. | Attendi, poi ritenta con la stessa chiave. |
| `413` | `Message too large` | Il messaggio codificato supera i 40 MB. | Invia meno allegati o allegati più piccoli, oppure usa link ai file grandi. |
| `422` | `Domain not verified` | Il dominio From non è un dominio di invio verificato in questo workspace. | Verifica il dominio, oppure controlla se si tratta di un sottodominio o di un errore di battitura. |
| `422` | `Attachment error` | L’URL di un allegato non è stato scaricato o supera i 25 MB. | Vedi [Allegati](/it/docs/email-api/attachments/). |
| `429` | `Rate limit exceeded` o `Daily limit exceeded` | Hai superato il limite di invio al secondo o giornaliero. | Attendi i secondi indicati in `retry-after`, oppure richiedi un limite più alto. |
| `503` | `Idempotency unavailable` | L’archivio dell’idempotenza non era raggiungibile. | Ritenta con la stessa chiave. |

Un workspace sospeso riceve `403` con `Workspace is suspended` a ogni invio. Per il formato generale degli errori, vedi [Errori](/it/docs/api-reference/errors/).

## Vedi anche

- [Invia un’email](/it/docs/api-reference/emails/send/) nel riferimento API
- [Template](/it/docs/templates/)
- [Stati delle email](/it/docs/logs/email-statuses/)
- [Tipi di evento](/it/docs/webhooks/event-types/)
- [Perché la mia email non è arrivata?](/it/docs/kb/email-not-delivered-checklist/)

---
Fonte: https://emailit.com/it/docs/email-api/send-email/
