Webhooks provide real-time delivery updates for messages sent via messages sent by using Netcore APIs. Each time a message’s state changes (e.g., sent, delivered, read), Netcore triggers a webhook to your configured endpoint with a standardized JSON payload.
These events help you:
- Track the message lifecycle accurately
- Improve reporting and analytics
- Trigger workflows based on message status
- Ensure billing accuracy
Webhook Structure
All webhook events follow a consistent format:
{
"delivery_status": [
{
"ncmessage_id": "string",
"phoneNumber": "string",
"pricing": {
"billable": boolean,
"category": "string",
"pricing_model": "string",
"type": "string"
},
"received_at": "epoch_timestamp",
"recipient": "string",
"source": "string",
"status": "string",
"status_remark": "string",
"x-apiheader": "string"
}
]
}
Fields
Refer to the given table to know the descriptions for the webhook fields.
| Field | Type | Description |
|---|---|---|
| delivery_status | array | An array of webhook event objects. Multiple events may be sent in a single webhook batch. |
| ncmessage_id | string | Unique message identifier generated by Netcore. |
| phoneNumber | string | Sender’s phone number or virtual number used to send the message. |
| recipient | string | Destination number to which the message was sent. |
| received_at | integer(epoch) | Timestamp when the event was generated. |
| source | string | Internal routing or originating source (e.g., partner, app system). |
| status | string | Current delivery stage (e.g., sent, delivered, read). |
| status_remark | string | Additional remarks from the operator/carrier (may be empty). |
| x-apiheader | string | Custom header passed during API request—echoed back for correlation. |
Pricing Object
Refer to the given table to know the descriptions for the pricing object fields.
| Field | Values | Description |
|---|---|---|
| billable | true / false | Indicates whether the event is billable. |
| category | marketing/utility/marketing_lite | Classifies the message type. |
| pricing_model | PMP / other | Pricing model applied. |
| type | regular / other | Type of message. |
Webhook Event Examples
Read Event
Triggered when the recipient reads the message.
{
"delivery_status": [
{
"ncmessage_id": "3694d58b-fc29-4563-b0d4-923c2ae43555",
"phoneNumber": "919867644673",
"pricing": {
"billable": true,
"category": "marketing",
"pricing_model": "PMP",
"type": "regular"
},
"received_at": "1764693401",
"recipient": "916361467892",
"source": "kiran",
"status": "read",
"status_remark": "",
"x-apiheader": "kiran"
}
]
}
Delivered Event
Triggered when the operator/carrier confirms delivery.
{
"delivery_status": [
{
"ncmessage_id": "bab1e073-51c9-4566-8008-30d33b6bedfd",
"phoneNumber": "912249757556",
"pricing": {
"billable": false,
"category": "utility",
"pricing_model": "PMP",
"type": "regular"
},
"received_at": "1764585432",
"recipient": "918657856504",
"source": "",
"status": "delivered",
"status_remark": "",
"x-apiheader": ""
}
]
}
Sent Event
Triggered when the message is accepted and sent to the carrier.
{
"delivery_status": [
{
"ncmessage_id": "859c535b-8d46-46ed-9afb-9082262a8dfb",
"phoneNumber": "912249757556",
"pricing": {
"billable": true,
"category": "marketing_lite",
"pricing_model": "PMP",
"type": "regular"
},
"received_at": "1764585991",
"recipient": "918657856504",
"source": "",
"status": "sent",
"status_remark": "",
"x-apiheader": ""
}
]
}
Failed Event
Triggered when the operator fails to deliver the message. Note: The pricing object is not included because failed messages are not billable.
{
"delivery_status": [
{
"ncmessage_id": "f12a9c22-8b37-4b75-bd1d-12ab45c90877",
"phoneNumber": "912249757556",
"received_at": "1764587102",
"recipient": "918657856504",
"source": "",
"status": "failed",
"status_remark": "Operator rejected the message",
"x-apiheader": ""
}
]
}
Note:
- status_remark may include operator-specific error codes.
- Messages may transition from sent → failed.
Clicked Event
Triggered when a recipient clicks a URL in the message. Note: The structure remains unchanged from Webhooks v1.
Status Lifecycle
A message may pass through the following stages:
- sent – Submitted to the operator.
- delivered – Operator confirms handset delivery.
- read – Message is opened by the user.
- failed – Operator fails to deliver the message.
Not all operators support all statuses.
Security and Verification
Recommended Practices
- Validate request signatures (HMAC-based).
- Verify source IPs (Netcore-provided).
- Use HTTPS-only endpoints.
- Implement retry logic with idempotent processing.
Recommended Response
Respond with HTTP 200 OK within 2–3 seconds. If not acknowledged, Netcore retries as per the retry policy.
Error Handling
If your system rejects a webhook:
- Log the payload.
- Respond with appropriate HTTP status codes (4xx/5xx).
- Use dead-letter queues for delayed or duplicate events.
