SmsMessage record by its external message ID, and updates both delivery_status and delivered_at. No further action is required on your side: the status is immediately visible on the message record.
DLR webhook endpoint
LaraCopilot exposes two equivalent URLs that accept inbound DLR callbacks. Both resolve to the same handler logic.| Route | Description |
|---|---|
POST /api/sms-gateways/{smsGateway}/dlr | REST API route — recommended for new integrations. |
POST /webhooks/jasmin/{smsGateway}/dlr | Web route alias retained for Jasmin gateway compatibility. |
{smsGateway} path segment is the integer ID of the gateway record in LaraCopilot. You typically configure this URL directly in your gateway or include it as the callback_url when calling POST /api/sms-gateways//send.
The ID of the SMS gateway that is delivering the receipt.
The external message identifier returned by the gateway when the SMS was submitted. Also accepted as
id or messageId — LaraCopilot checks all three in that order.Delivery status string from the gateway. Also accepted as
message_status. When neither field is present, LaraCopilot defaults the status to "delivered".SmsMessage records for a row matching both sms_gateway_id and external_message_id. If a match is found it performs the following updates on that record:
delivery_status— set to the lowercased value ofstatusormessage_statusfrom the payload (default:"delivered").delivered_at— set to the current timestamp.remote_response— the inbound DLR payload is merged into the existingremote_responseobject so the full gateway conversation is preserved.
200 OK with {"message": "DLR received"} and takes no further action.
Response
200. Gateway retry logic based on non-2xx responses will not be triggered.
Configuring the callback URL
When you call POST /api/sms-gateways//send, includecallback_url in the request body to tell LaraCopilot where the gateway should send the DLR.
Send with explicit callback URL
callback_url is omitted, LaraCopilot automatically sets it to:
Message status values
delivery_status on an SmsMessage record moves through the following states:
| Status | When it is set |
|---|---|
queued | Immediately when the send request is received, before the gateway is contacted. |
submitted | After the gateway responds with a success status. |
delivered | After a DLR callback confirms the message reached the handset. |
failed | When the gateway returns an error, the request times out, or a DLR reports failure. |
The
status value sent in the DLR payload is lowercased and written directly to delivery_status. If your gateway sends values such as "DELIVRD" or "UNDELIV", those exact lowercased strings will appear on the record.Example DLR payload
The following is a representative payload that a Jasmin-compatible gateway sends to the callback URL. Your gateway documentation should confirm the exact fields it uses.Example DLR payload from gateway
message_id and status from this payload. All other fields are merged into remote_response on the matching SmsMessage record for your records.
Full SMS lifecycle
Send request
Your application calls
POST /api/sms-gateways/{id}/send. LaraCopilot creates an SmsMessage with delivery_status: "queued".Gateway dispatch
LaraCopilot forwards the message to the gateway over HTTP(S) with Basic Auth. The
callback_url (your DLR endpoint) is included in the payload as dlr-url.Submitted
On a successful gateway response,
delivery_status is updated to "submitted" and submitted_at is recorded. The send API returns the message object at this point.Security: validating callback_token
Each gateway record has acallback_token field. When configuring your gateway in LaraCopilot, set a long random string as the token and configure your gateway to include it in every DLR request — typically as a query parameter or custom header.
Your gateway configuration or a reverse-proxy rule should reject DLR requests that do not carry the expected token before they reach LaraCopilot. The callback_token value is available on the gateway object returned by GET /api/sms-gateways/.
Retrieve a gateway's callback_token