Leveransrapporter
Ta emot meddelandestatus via webhook och hantera bekräftelser, omförsök och idempotens.
Ange deliveryReportUrl när en batch skapas för att få statusuppdateringar per mottagare och status.
Webhook-beteende
iP.1 skickar varje rapport med POST och förväntar sig 200 OK. Den publicerade retry-policyn är:
- en respons som inte är
200 OKutlöser ett nytt försök - omförsök görs med 10 minuters intervall
- högst 10 försök görs
- rapporten tas bort efter det sista misslyckade försöket
Svara därför snabbt med 200 OK efter att payloaden har validerats och lagts i en intern kö. Gör långsam eller felkänslig behandling asynkront.
Exempel på payload
{
"id": "message_abc123",
"batchId": "batch_abc123",
"owner": "ip1-XXXXX",
"recipient": "46700000000",
"code": 201,
"duration": 0,
"created": "2026-10-05T08:03:21Z",
"segments": 1,
"price": 0.0416,
"currency": "SEK",
"reference": "order-123"
}
Den äldre källtabellen hade två felmärkta rader (batchId för owner och recipient för sender). Payloadexemplet och fälten nedan använder de faktiska JSON-nycklarna.
Fält
| Fält | Typ | Beskrivning |
|---|---|---|
id |
string |
Meddelandets ID. |
batchId |
string |
Överliggande batchs ID. |
owner |
string |
Ägande SMS-konto, när fältet inkluderas. |
recipient |
string |
Mottagarens MSISDN. |
code |
integer |
Den nya statuskoden. |
duration |
integer |
Anger enligt den publicerade modellen om statusen är slutlig. |
created |
string |
Tidpunkt för statusen i ISO 8601. |
segments |
integer |
Antal SMS-segment. |
price |
number |
Total kostnad för meddelandet. |
currency |
string |
Prisets valuta. |
reference |
string | null |
Egen referens från batchen. |
Säker och idempotent mottagare
- Tillåt endast HTTPS.
- Begränsa payloadstorleken.
- Validera Content-Type och JSON-schema.
- Använd kombinationen
id,codeochcreatedsom idempotensnyckel. - Acceptera att samma rapport kan komma flera gånger.
- Jämför händelsetid innan en lokal status skrivs över.
- Logga inte fullständiga telefonnummer eller meddelandetext om det inte behövs.
export async function POST({ request }) {
const report = await request.json();
if (!report.id || !Number.isInteger(report.code)) {
return new Response('Invalid report', { status: 400 });
}
await queue.add('ip1-delivery-report', report);
return new Response(null, { status: 200 });
}
Exemplet visar principen; komplettera med autentisering eller nätverkskontroller enligt de möjligheter som avtalats för integrationen.
Se statuskoder för betydelsen av code och meddelanden för hur full historik kan hämtas.
