Receive incoming SMS messages directly on your application using the Text.lk Incoming SMS Webhook.
When an SMS is sent to a Sender ID or virtual number configured for your Text.lk account, Text.lk can send the received message to an HTTP/HTTPS endpoint on your server.
This allows your application to automatically process incoming SMS messages for applications such as:
- Customer support
- Two-way SMS
- Automated replies
- SMS-based applications
- Customer enquiries
- Notifications
- Ticketing systems
- CRM integrations
- Order or service requests
How It Works #
The integration works as follows:
Mobile User
│
│ SMS
▼
Text.lk
│
│ HTTP POST
▼
Your Webhook Endpoint
│
▼
Your Application
For example, a customer sends:
From: 94710000000
To: YOUR-SENDER-ID
Hello! Can I know pricing of your product?
Text.lk receives the SMS and sends the following JSON payload to your configured webhook endpoint:
{
"from": "94710000000",
"to": "SenderID",
"message": "Hello! Can I know pricing of your product?",
"received_at": "2026-08-25 16:54:01"
}1. Create Your Webhook Endpoint #
You need to create an HTTP/HTTPS endpoint on your own server that can receive the incoming SMS notification.
For example:
https://example.com/api/textlk/inbound
Your endpoint must accept:
HTTP POST
Content-Type: application/json
Recommended #
Use HTTPS rather than HTTP:
https://example.com/api/textlk/inbound
Avoid sending production webhook traffic to an unsecured HTTP endpoint.
2. Request Format #
Text.lk sends an HTTP POST request containing a JSON body.
HTTP Request #
POST /api/textlk/inbound HTTP/1.1
Host: example.com
Content-Type: application/json
{
"from": "94710000000",
"to": "SenderID",
"message": "Hello! Can I know pricing of your product?",
"received_at": "2026-08-25 16:54:01"
}3. JSON Payload #
The request body contains the following fields:
| Field | Type | Description |
|---|---|---|
from | string | Mobile number that sent the SMS |
to | string | Sender ID or destination configured on Text.lk |
message | string | Full SMS message |
received_at | string | Date and time when the SMS was received |
Example:
{
"from": "94710000000",
"to": "SenderID",
"message": "Hello! Can I know pricing of your product?",
"received_at": "2026-08-25 16:54:01"
}from #
The from field contains the originating mobile number.
Example:
"from": "94710000000"
The number is represented using the international format.
Do not assume that the value is an integer. Treat it as a string.
Correct:
$from = $request->input('from');
Avoid converting the number to an integer because phone numbers should be handled as strings.
to #
The to field contains the Sender ID or destination associated with the incoming SMS.
Example:
"to": "SenderID"
Your application can use this value if you have multiple Sender IDs or services connected to the same webhook.
message #
The message field contains the actual SMS content.
Example:
"message": "Hello! Can I know pricing of your product?"
Treat this value as user-provided input.
Your application should validate and sanitize the content before displaying it or using it in other systems.
received_at #
The received_at field contains the date and time when Text.lk received the SMS.
Example:
"received_at": "2026-08-25 16:54:01"
The format is:
YYYY-MM-DD HH:MM:SS
Example:
2026-08-25 16:54:01
Your application should store this value as a datetime rather than treating it as an ordinary text field.
4. Your Endpoint Must Return a Success Response #
After successfully receiving and processing the webhook, your server should return an HTTP 2xx response.
Recommended:
HTTP/1.1 200 OK
Content-Type: application/json
For example:
{
"success": true
}
The important part is the HTTP status code.
A successful response should use a status code in the 200–299 range.
5. Do Not Perform Long Processing Before Responding #
Your webhook should acknowledge the request quickly.
For example, avoid doing this directly inside the webhook request:
Receive SMS
↓
Insert into multiple tables
↓
Call CRM API
↓
Send notification
↓
Process business logic
↓
Generate report
↓
Return HTTP 200
Instead, use:
Receive SMS
↓
Validate payload
↓
Store / queue message
↓
Return HTTP 200
↓
Process message asynchronously
This makes your integration more reliable.
For example:
Text.lk
│
│ POST
▼
Your Webhook
│
├── Validate
├── Store message
└── Return 200 OK
│
▼
Background Worker
│
├── CRM
├── Database
├── Notifications
└── Business Logic
6. Example: PHP #
A simple PHP endpoint could look like this:
<?php
header('Content-Type: application/json');
$data = json_decode(file_get_contents('php://input'), true);
$from = $data['from'] ?? null;
$to = $data['to'] ?? null;
$message = $data['message'] ?? null;
$receivedAt = $data['received_at'] ?? null;
if (!$from || !$to || !$message || !$receivedAt) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'Invalid payload'
]);
exit;
}
// Process or queue the incoming SMS here.
http_response_code(200);
echo json_encode([
'success' => true
]);7. Example: Laravel #
If your application uses Laravel, define a route:
use App\Http\Controllers\TextLkInboundController;
use Illuminate\Support\Facades\Route;
Route::post('/api/textlk/inbound', [
TextLkInboundController::class,
'handle'
]);Then create a controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class TextLkInboundController extends Controller
{
public function handle(Request $request): JsonResponse
{
$data = $request->validate([
'from' => ['required', 'string'],
'to' => ['required', 'string'],
'message' => ['required', 'string'],
'received_at' => ['required', 'date'],
]);
// Store or queue the incoming SMS here.
return response()->json([
'success' => true,
]);
}
}For a production application, we recommend storing the received message and processing business logic asynchronously.
8. Example: Node.js / Express #
For Node.js applications using Express:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/api/textlk/inbound', async (req, res) => {
const {
from,
to,
message,
received_at
} = req.body;
if (!from || !to || !message || !received_at) {
return res.status(400).json({
success: false,
message: 'Invalid payload'
});
}
// Store or queue the incoming SMS here.
return res.status(200).json({
success: true
});
});
app.listen(3000);
9. Example: Python / Flask #
For Python applications using Flask:
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/api/textlk/inbound", methods=["POST"])
def inbound_sms():
data = request.get_json()
if not data:
return jsonify({
"success": False,
"message": "Invalid JSON"
}), 400
from_number = data.get("from")
to = data.get("to")
message = data.get("message")
received_at = data.get("received_at")
if not all([from_number, to, message, received_at]):
return jsonify({
"success": False,
"message": "Missing required fields"
}), 400
# Store or queue the incoming SMS here.
return jsonify({
"success": True
}), 200
10. Security #
Your webhook endpoint is publicly accessible to Text.lk, so it should be protected appropriately.
HTTPS #
We strongly recommend using HTTPS:
https://example.com/api/textlk/inbound
Do not expose sensitive customer data through an unencrypted HTTP endpoint.
Authentication #
If your application requires authentication, use an authentication mechanism supported by your Text.lk webhook configuration.
For example, your application may use a secret token:
Authorization: Bearer YOUR_SECRET_TOKEN
Your server should verify the token before processing the message.
Never hard-code sensitive credentials into frontend JavaScript or expose them publicly.
11. Validate Incoming Data #
Your application should validate every incoming request.
At minimum, verify that:
- The request is a
POSTrequest. - The request contains valid JSON.
fromexists.toexists.messageexists.received_atexists.- Values have reasonable lengths and formats.
- Authentication requirements are satisfied, if enabled.
Do not blindly trust webhook data.
12. Duplicate Messages #
Your application should be designed to tolerate duplicate webhook deliveries.
For example, if the same SMS is delivered more than once, your system should avoid creating duplicate business records where possible.
Use an appropriate idempotency strategy in your application.
For example:
Incoming SMS
│
▼
Check whether already processed
│
├── Yes → Ignore duplicate
│
└── No
│
▼
Process SMS
Your database design should account for this if duplicate processing would cause problems.
13. Error Responses #
If your server cannot accept the request, return an appropriate HTTP status code.
For example:
Invalid request #
400 Bad Request
{
"success": false,
"message": "Invalid payload"
}
Authentication failure #
401 Unauthorized
Forbidden request #
403 Forbidden
Temporary server problem #
500 Internal Server Error
Only return a successful 2xx response after your application has successfully accepted the message.
14. Webhook Endpoint Requirements #
Before configuring your endpoint with Text.lk, make sure it satisfies the following:
- Endpoint is publicly accessible from the internet.
- Endpoint supports HTTPS.
- Endpoint accepts HTTP
POST. - Endpoint accepts
application/json. - Endpoint can parse JSON requests.
- Endpoint validates the incoming payload.
- Endpoint returns an HTTP
2xxresponse after successfully accepting the message. - Endpoint responds quickly.
- Your application can handle duplicate deliveries safely.
- Authentication/security controls are configured where required.
- Your server/firewall allows incoming requests from Text.lk.
15. Example Complete Request #
Your server should be prepared to receive a request similar to:
POST /api/textlk/inbound HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 145
{
"from": "94710000000",
"to": "SenderID",
"message": "Hello! Can I know pricing of your product?",
"received_at": "2026-08-25 16:54:01"
}Your application processes the request and returns:
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true
}16. Testing Your Endpoint #
Before configuring the endpoint with Text.lk, you can test it manually.
Using curl:
curl -X POST "https://example.com/api/textlk/inbound" \
-H "Content-Type: application/json" \
-d '{
"from": "94710000000",
"to": "SenderID",
"message": "Hello! Can I know pricing of your product?",
"received_at": "2026-08-25 16:54:01"
}'A successful response should look similar to:
{
"success": true
}
And the HTTP response status should be:
200 OK
17. Recommended Architecture #
For applications that receive a high volume of incoming SMS, we recommend separating webhook reception from message processing.
Recommended #
Text.lk
│
│ HTTP POST
▼
Customer Webhook
│
▼
Message Queue
│
▼
Background Worker
│
┌────────────┼────────────┐
▼ ▼ ▼
Database CRM Automation
The webhook should primarily:
- Receive the request.
- Validate the payload.
- Store or queue the message.
- Return
200 OK.
The background worker can then perform slower operations.
This architecture prevents your webhook from timing out when your application needs to perform additional processing.
18. Multiple Sender IDs #
If your account has multiple Sender IDs, your application can use the to field to determine which service received the message.
Example:
{
"from": "94710000000",
"to": "SALES",
"message": "I need a quotation",
"received_at": "2026-08-25 16:54:01"
}Your application could route this message to a sales workflow.
Another message might be:
{
"from": "94710000000",
"to": "SUPPORT",
"message": "I need help with my account",
"received_at": "2026-08-25 17:02:10"
}Your application can then route it to a support workflow.
19. Handling User Messages #
Incoming SMS content should be treated as untrusted user input.
For example, never directly insert message content into SQL queries.
Use parameterized queries or your framework’s database abstraction layer.
When displaying an SMS in a web application, properly escape the content to prevent HTML or JavaScript injection.
For example, do not assume this is safe:
$message
Always use the appropriate escaping mechanism provided by your framework.
20. Troubleshooting #
Endpoint is not receiving requests #
Check:
- The endpoint URL is correct.
- DNS resolves correctly.
- Your server is publicly accessible.
- HTTPS certificate is valid.
- Your firewall allows incoming connections.
- Your web server is running.
- Your application route is correct.
- Your application accepts
POST. - Your application accepts JSON.
Getting 404 Not Found #
A 404 usually means the requested URL does not exist on your application.
Check your route.
For example:
/api/textlk/inbound
must match the route configured in your application.
Getting 405 Method Not Allowed #
This usually means the URL exists but does not accept POST.
Make sure your route supports:
POST
Getting 400 Bad Request #
Check whether your application expects all required fields:
from
to
message
received_at
Also verify that the request body is valid JSON.
Getting 500 Internal Server Error #
Check your application logs.
The webhook endpoint should also avoid performing expensive operations synchronously.
21. Payload Reference #
Incoming SMS Webhook #
Method
POST
Content-Type
application/json
Payload
{
"from": "94710000000",
"to": "SenderID",
"message": "Hello! Can I know pricing of your product?",
"received_at": "2026-08-25 16:54:01"
}Fields #
| Field | Required | Type | Example |
|---|---|---|---|
from | Yes | string | 94710000000 |
to | Yes | string | SenderID |
message | Yes | string | Hello! Can I know pricing of your product? |
received_at | Yes | datetime string | 2026-08-25 16:54:01 |
22. Quick Start #
If you already have a web application, the integration is simple:
Step 1 — Create an endpoint #
POST https://your-domain.com/api/textlk/inbound
Step 2 — Accept JSON #
Content-Type: application/json
Step 3 — Read the payload #
{
"from": "94710000000",
"to": "SenderID",
"message": "Hello! Can I know pricing of your product?",
"received_at": "2026-08-25 16:54:01"
}Step 4 — Store or queue the message #
Save the incoming SMS in your application or pass it to your background processing system.
Step 5 — Return success #
200 OK
{
"success": true
}Your application is now ready to receive incoming SMS messages from Text.lk.
23. Integration Checklist #
Before requesting activation of your Incoming SMS Webhook:
- Public HTTPS endpoint created
- HTTP POST supported
- JSON supported
- Payload validation implemented
- Incoming SMS stored or queued
- HTTP
200response implemented - Endpoint responds quickly
- Duplicate handling considered
- Security/authentication configured
- Endpoint tested using
curl - Application logs enabled
Need Help? #
If you have completed the webhook setup but are having problems receiving incoming SMS messages, check your server/application logs first.
When contacting Text.lk support, provide:
- Your Text.lk account details
- Sender ID or number
- Webhook URL
- Approximate time of the test SMS
- Mobile number used for testing
- HTTP status code returned by your server
- Relevant application/server logs
Do not send passwords, API secrets, access tokens, or other confidential credentials to support.