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.
The
{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.
integer
required
The ID of the SMS gateway that is delivering the receipt.
string
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.string
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:
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
1
Send request
Your application calls
POST /api/sms-gateways/{id}/send. LaraCopilot creates an SmsMessage with delivery_status: "queued".2
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.3
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.4
DLR callback
The gateway POSTs a delivery receipt to your
callback_url. LaraCopilot matches the message_id, updates delivery_status to "delivered" (or "failed"), and sets delivered_at.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