Inbound SMS is webhook-driven: Telnyx POSTs a message.received event to your messaging profile’s webhook, and your Edge Compute function is that webhook. Replying to another Telnyx number is on-net — no 10DLC campaign required.
1. Write the handler
// index.ts
import * as http from "node:http";
import { env } from "@telnyx/edge-runtime";
const port = Number(process.env.PORT ?? 8080);
const received: any[] = []; // in-memory; use KV or SQL DB for durable storage
function body(req: http.IncomingMessage): Promise<string> {
return new Promise((r) => {
let b = "";
req.on("data", (c) => (b += c));
req.on("end", () => r(b));
});
}
http.createServer(async (req, res) => {
// GET: see what's been received
if (req.method === "GET") {
res.writeHead(200, { "content-type": "application/json" });
res.end(JSON.stringify({ received }, null, 2));
return;
}
// POST: Telnyx inbound webhook — parse it through the binding
const evt = env.MY_TELNYX.webhooks.unsafeUnwrap<{ data: any }>(await body(req)).data;
if (evt?.event_type === "message.received") {
const p = evt.payload;
const from = p.from.phone_number;
const to = p.to[0].phone_number;
received.unshift({ from, to, text: p.text, at: evt.occurred_at });
// Auto-reply on-net (no 10DLC when the recipient is a Telnyx number)
await env.MY_TELNYX.messages.send({ from: to, to: from, text: `You said: ${p.text}` });
}
res.writeHead(200);
res.end();
}).listen(port);
Declare the binding in func.toml (see the Quick start):
[telnyx]
binding = "MY_TELNYX"
2. Ship
3. Point a messaging profile at it
Set a messaging profile’s inbound webhook to your function URL, then assign your number to that profile:
# webhook -> your function
curl -X POST https://api.telnyx.com/v2/messaging_profiles \
-H "Authorization: Bearer $TELNYX_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"inbound-demo","webhook_url":"https://YOUR-FUNC.telnyxcompute.com","whitelisted_destinations":["US"]}'
# assign your number to the profile (use the profile id from the response)
curl -X PATCH https://api.telnyx.com/v2/phone_numbers/YOUR-NUMBER-ID/messaging \
-H "Authorization: Bearer $TELNYX_API_KEY" -H "Content-Type: application/json" \
-d '{"messaging_profile_id":"YOUR-PROFILE-ID"}'
4. Test on-net
Send from another Telnyx number on your account to your function’s number:
curl -X POST https://api.telnyx.com/v2/messages \
-H "Authorization: Bearer $TELNYX_API_KEY" -H "Content-Type: application/json" \
-d '{"from":"+1ANOTHER_TELNYX_NUMBER","to":"+1YOUR_FUNC_NUMBER","text":"hello"}'
You get back “You said: hello” on-net, and GET https://YOUR-FUNC.telnyxcompute.com shows what arrived. The inbound event the function parses looks like:
{
"data": {
"event_type": "message.received",
"occurred_at": "2026-06-19T16:06:17.464+00:00",
"payload": {
"from": { "phone_number": "+1..." },
"to": [ { "phone_number": "+1..." } ],
"text": "hello"
}
}
}
Only on-net replies skip 10DLC. Receiving is always free. Replying to a Telnyx number is on-net (no campaign). Replying to an off-net number — e.g. a personal mobile — is application-to-person traffic and requires 10DLC registration.