Autenticazione
Ogni richiesta richiede una chiave API, assegnata da SoloPosta al momento dell'attivazione del servizio. Non esiste una procedura di auto-generazione: per ottenere, sostituire o revocare una chiave, contattate il vostro referente SoloPosta.
La chiave va inviata nell'header Authorization, con schema Bearer:
Authorization: Bearer la-vostra-chiave
Una chiave assente o non riconosciuta restituisce sempre 401, indipendentemente dal motivo — per non rivelare se una chiave "quasi giusta" esiste davvero. Un account con la chiave sospesa o il contratto scaduto restituisce invece 403.
Endpoint di invio
Un solo endpoint, un solo scopo: spedire un'email transazionale. Ogni chiamata corrisponde esattamente a un messaggio — non è previsto l'invio di più email in un'unica richiesta (vedi Limiti e buone pratiche).
POST /api/send
Content-Type: application/json
Authorization: Bearer la-vostra-chiave
Corpo della richiesta
- From obbligatorio
- Indirizzo mittente. Può appartenere a un dominio diverso da quello associato al vostro account — vedi Policy sul mittente.
- To obbligatorio
- Uno o più destinatari, separati da virgola.
- Cc
- Destinatari in copia, separati da virgola.
- Bcc
- Destinatari in copia nascosta, separati da virgola.
- Subject obbligatorio
- Oggetto del messaggio. Caratteri accentati e non-ASCII sono gestiti correttamente.
- Body
- Corpo del messaggio, testo semplice o HTML a seconda di
IsBodyHtml. - IsBodyHtml
- Booleano.
trueseBodycontiene markup HTML,falseper testo semplice. Defaultfalse. - Attachments
- Elenco di allegati e/o immagini incorporate. Vedi Allegati e immagini incorporate.
| Campo | Tipo | Obbligatorio |
|---|---|---|
From | stringa | Sì |
To | stringa (indirizzi separati da virgola) | Sì |
Cc | stringa (indirizzi separati da virgola) | No |
Bcc | stringa (indirizzi separati da virgola) | No |
Subject | stringa | Sì |
Body | stringa | No |
IsBodyHtml | booleano | No (default false) |
Attachments | array di oggetti | No |
Allegati e immagini incorporate
Stesso schema usato da altre API di invio transazionale (es. SendGrid): un array Attachments, ogni elemento con il contenuto binario codificato in Base64.
| Campo | Tipo | Obbligatorio | Note |
|---|---|---|---|
FileName | stringa | Sì | Nome file mostrato al destinatario. |
Type | stringa | Sì | MIME type, es. application/pdf, image/png. |
Content | stringa | Sì | Contenuto del file codificato in Base64. |
Disposition | stringa | No | attachment (default) per un allegato scaricabile, inline per un'immagine incorporata nel corpo HTML. |
ContentId | stringa | Solo se Disposition=inline | Identificatore da referenziare nell'HTML come cid:valore. |
{
"Attachments": [
{
"FileName": "fattura.pdf",
"Type": "application/pdf",
"Content": "JVBERi0xLjQK..."
}
]
}
IsBodyHtml: true){
"IsBodyHtml": true,
"Body": "<p>Il nostro logo: <img src='cid:logo1'></p>",
"Attachments": [
{
"FileName": "logo.png",
"Type": "image/png",
"Content": "iVBORw0KGgo...",
"Disposition": "inline",
"ContentId": "logo1"
}
]
}
La somma delle dimensioni (decodificate) di tutti gli allegati di una richiesta non può superare 20 MB. Oltre il limite, l'API risponde 400.
Per immagini che non richiedono di essere incorporate (es. loghi già ospitati sul vostro sito), è più semplice ed efficiente referenziarle con un URL assoluto direttamente nell'HTML di Body, senza passare da Attachments.
Risposte e codici di stato
Una risposta 200 significa che il messaggio è stato accettato per l'invio, non che è già stato recapitato: la consegna effettiva avviene in modo asincrono (vedi sotto).
| Stato | Significato | Corpo risposta |
|---|---|---|
| 200 | Accettato per l'invio. | Vuoto |
| 400 | Richiesta non valida: campo obbligatorio mancante o indirizzo email malformato. | {"Message": "..."} |
| 401 | Header Authorization assente o chiave non riconosciuta. |
Vuoto |
| 403 | Account sospeso, oppure contratto fuori dal periodo di validità. | Testo semplice |
| 503 | Errore temporaneo lato infrastruttura. Riprovare — vedi header Retry-After. |
Testo semplice |
È l'unico codice pensato per essere ritentato automaticamente. Rispettate il valore in secondi indicato da Retry-After prima di ripetere la chiamata, idealmente con un backoff crescente se il problema persiste.
Esempi di integrazione
curl -X POST https://api.soloposta.biz/api/send \
-H "Authorization: Bearer la-vostra-chiave" \
-H "Content-Type: application/json" \
-d '{
"From": "ordini@ilvostrosito.it",
"To": "cliente@example.com",
"Subject": "Conferma ordine #4521",
"Body": "Il tuo ordine è confermato.",
"IsBodyHtml": false
}'
// richiede l'estensione curl
$payload = json_encode([
'From' => 'ordini@ilvostrosito.it',
'To' => 'cliente@example.com',
'Subject' => 'Conferma ordine #4521',
'Body' => 'Il tuo ordine è confermato.',
'IsBodyHtml' => false,
]);
$ch = curl_init('https://api.soloposta.biz/api/send');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer la-vostra-chiave',
'Content-Type: application/json',
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
const response = await fetch('https://api.soloposta.biz/api/send', {
method: 'POST',
headers: {
'Authorization': 'Bearer la-vostra-chiave',
'Content-Type': 'application/json',
},
body: JSON.stringify({
From: 'ordini@ilvostrosito.it',
To: 'cliente@example.com',
Subject: 'Conferma ordine #4521',
Body: 'Il tuo ordine è confermato.',
IsBodyHtml: false,
}),
});
if (!response.ok) {
// 400/401/403: correggere la richiesta o le credenziali.
// 503: rispettare l'header Retry-After e ritentare.
}
Comportamento asincrono
Un 200 conferma che il messaggio è entrato nel sistema di invio — non che è già arrivato nella casella del destinatario. La consegna reale (instradamento verso il server del destinatario, eventuali tentativi ripetuti in caso di rifiuto temporaneo) avviene dopo, in modo asincrono.
L'API non restituisce una conferma di consegna finale nella risposta HTTP: un errore del server ricevente (casella piena, dominio inesistente, rifiuto per policy anti-spam) non è visibile nella risposta alla chiamata, perché si verifica dopo che la risposta è già stata inviata.
Policy sul mittente
Il campo From è libero: potete spedire anche a nome di un dominio diverso da quello del vostro account SoloPosta — è il caso tipico di agenzie che inviano per conto dei propri clienti.
Perché la posta spedita da un dominio di terzi non finisca in spam, quel dominio deve avere una firma DKIM configurata lato SoloPosta. Comunicate ogni nuovo dominio mittente al vostro referente prima di iniziare a usarlo in produzione.
Limiti e buone pratiche
- Un'email per chiamata. Non è previsto l'invio massivo in un'unica richiesta: per spedire a molti destinatari con contenuti diversi, effettuate una chiamata per ciascuno. Per lo stesso contenuto a più persone, elencatele in
To/Cc/Bccseparate da virgola. - Rispettate
Retry-Aftersui 503. È pensato per assorbire picchi temporanei, non per essere ignorato con ritentativi immediati a raffica. - Non serializzate le chiamate inutilmente. L'endpoint è pensato per gestire più richieste in parallelo da parte dello stesso account.
Sicurezza
- Trattate la chiave come una password. Chi la possiede può spedire posta a nome del vostro account.
- Solo HTTPS. L'endpoint non è raggiungibile in chiaro.
- Mai lato client. Non inserite la chiave in codice eseguito nel browser o in app mobile distribuite pubblicamente: passate sempre dal vostro server.
- Chiave compromessa? Contattate subito SoloPosta per la revoca e l'emissione di una nuova chiave.