> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchbord.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Invii di template transazionali

> Invia template WhatsApp Utility approvati tramite telefono o id destinatario esterno da sistemi esterni.

Gli invii di template transazionali consentono a sistemi esterni fidati di attivare messaggi WhatsApp previsti tramite Switchbord. L'endpoint è progettato per la messaggistica Utility come ricevute di pagamento, ricevute di rata, conferme di prenotazione, voucher e altri eventi operativi attesi dal cliente.

<Warning>
  Questo endpoint non è un'API di marketing bulk. Switchbord valida il workspace del chiamante, lo stato del template e la categoria del template prima di accodare un invio. Usa template `UTILITY` approvati per i flussi transazionali.
</Warning>

## Endpoint

```text theme={null}
POST /api/v1/template-sends
```

L'endpoint risiede sull'app API. I workspace hosted chiamano:

```text theme={null}
https://api.switchbord.ai/api/v1/template-sends
```

I deployment self-hosted dovrebbero sostituire l'host con il proprio dominio API.

## Autenticazione

Usa una API Key Switchbord con scope sul workspace. Il workspace viene risolto dalla API Key; non inviare gli id di workspace nel corpo della richiesta.

```http theme={null}
Authorization: Bearer sk_live_...
Content-Type: application/json
Idempotency-Key: receipt-event-123
```

Puoi anche inviare la chiave di idempotenza come `idempotencyKey` nel corpo JSON. Preferisci l'header quando il sistema upstream lo supporta.

## Struttura della richiesta

```json theme={null}
{
  "templateName": "payment_receipt_link",
  "templateLocale": "it",
  "recipient": {
    "phoneE164": "+393331234567",
    "externalId": "traveller-123",
    "name": "Giulia Rossi"
  },
  "variables": {
    "body": {
      "1": "Giulia",
      "2": "R-1001",
      "3": "€ 240,00"
    },
    "buttons": {
      "url": [
        { "index": 0, "suffix": "R-1001" }
      ]
    }
  },
  "metadata": {
    "source": "booking-system",
    "eventType": "payment.receipt.created"
  }
}
```

| Campo                  | Tipo   | Obbligatorio                                                                       | Note                                                                                                                         |
| ---------------------- | ------ | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `templateName`         | string | Sì                                                                                 | Deve risolversi in un template Utility approvato visibile al workspace del chiamante.                                        |
| `templateLocale`       | string | No                                                                                 | Locale Meta come `it`, `it_IT` o `en_US`. Se omesso, la ricerca del template usa il comportamento predefinito del workspace. |
| `recipient.phoneE164`  | string | Sì, a meno che una ricerca contatto/esterna non sia fornita da un contratto futuro | Telefono in formato E.164.                                                                                                   |
| `recipient.externalId` | string | No                                                                                 | Id cliente esterno da persistere sul contatto risolto.                                                                       |
| `recipient.name`       | string | No                                                                                 | Nome visualizzato per il contesto del contatto risolto/creato di recente.                                                    |
| `variables`            | object | No                                                                                 | Valori body/header/button compilati nei componenti del template Meta.                                                        |
| `components`           | object | No                                                                                 | Alias per `variables`; usane uno o l'altro.                                                                                  |
| `idempotencyKey`       | string | Consigliato                                                                        | Previene invii duplicati per lo stesso evento upstream.                                                                      |
| `metadata`             | object | No                                                                                 | Memorizzato con il messaggio per il contesto di audit/debug. Non includere segreti.                                          |

## Risposte

Una richiesta riuscita accoda un job `message.dispatch` in uscita e restituisce le identità Switchbord per l'audit e la riconciliazione.

I nuovi invii restituiscono HTTP `201`:

```json theme={null}
{
  "data": {
    "contactId": "contact_123",
    "conversationId": "conversation_123",
    "messageId": "message_123",
    "clientMessageId": "receipt-event-123",
    "status": "queued",
    "reused": false,
    "idempotent": true
  }
}
```

Se la stessa chiave di idempotenza viene inviata nuovamente, Switchbord restituisce HTTP `200` con l'identità del messaggio esistente e `reused: true` invece di creare un invio duplicato.

## Variabili

### Variabili del corpo

Per i template posizionali, usa chiavi numeriche a base 1:

```json theme={null}
{
  "variables": {
    "body": {
      "1": "Giulia",
      "2": "R-1001",
      "3": "€ 240,00"
    }
  }
}
```

Le variabili del corpo con nome sono supportate dal compilatore transazionale interno di Switchbord per le mappature dei webhook inbound, ma la route API pubblica attualmente accetta solo variabili del corpo posizionali. Usa chiavi del corpo numeriche o un array quando chiami direttamente `POST /api/v1/template-sends`.

### Variabili dei bottoni URL dinamici

Per i template con un bottone URL come `https://example.com/r/{{1}}`, fornisci il suffisso dinamico tramite l'indice del bottone a base 0:

```json theme={null}
{
  "variables": {
    "buttons": {
      "url": [
        { "index": 0, "suffix": "R-1001" }
      ]
    }
  }
}
```

`text` e `suffix` sono alias accettati. Il valore deve essere non vuoto.

### Variabili dell'header documento

Per i template con un header DOCUMENT, fornisci un link HTTPS pubblico. `filename` è opzionale ma consigliato.

```json theme={null}
{
  "variables": {
    "header": {
      "document": {
        "link": "https://cdn.example.com/receipts/R-1001.pdf",
        "filename": "R-1001.pdf"
      }
    }
  }
}
```

I link ai documenti devono usare HTTPS. Link non validi o non HTTPS vengono rifiutati prima dell'accodamento.

## Risposte di errore

| HTTP  | Errore                          | Significato                                                                      |
| ----- | ------------------------------- | -------------------------------------------------------------------------------- |
| `400` | `invalid_json`                  | Il corpo della richiesta non è stato analizzabile come JSON.                     |
| `400` | `invalid_request`               | Il JSON è stato analizzato ma non corrispondeva allo schema dell'endpoint.       |
| `400` | `template_not_approved`         | Il template esiste ma non è approvato da Meta.                                   |
| `400` | `template_category_not_allowed` | Il template non è Utility; gli invii transazionali sono di default solo Utility. |
| `400` | `invalid_media_link`            | Un link a documento o immagine è mancante, non valido o non HTTPS.               |
| `400` | `missing_button_url_variable`   | È richiesta una variabile del bottone URL dinamico ma è vuota.                   |
| `401` | `missing_authorization`         | Header `Authorization: Bearer ...` mancante.                                     |
| `403` | `invalid_or_insufficient_key`   | La API Key non è valida o non ha lo scope `data_write`.                          |
| `404` | `template_not_found`            | Il nome/locale del template non è stato risolvibile per il workspace.            |
| `429` | Accesso API negato              | Il middleware di rate/security dell'API pubblica ha negato la richiesta.         |

I riutilizzi idempotenti non sono errori. Restituiscono HTTP `200` con `data.reused: true`.

## Note operative

* Il worker mantiene la proprietà finale del dispatch a Meta. La risposta dell'API indica che il messaggio è stato accettato nell'outbox di Switchbord, non necessariamente che è stato consegnato da Meta.
* Le transizioni di consegna (`queued`, `sent`, `delivered`, `read`, `failed`) sono visibili nei record di messaggio/conversazione e negli eventi di stato webhook.
* Non includere dettagli di carta grezzi, token di ricevuta privati o segreti a lunga durata nelle variabili del template o nei metadata. Preferisci id di ricevuta brevi o URL pre-firmati con una scadenza appropriata.

## Guide correlate

* [Guida al link della ricevuta](/it/guides/receipt-link-webhook)
* [Guida alla ricevuta PDF](/it/guides/pdf-receipt-webhook)
* [Webhook inbound](/it/api-reference/inbound-webhooks)
