Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt

Use this file to discover all available pages before exploring further.

Bite-sized code snippets for common edge function patterns. Each example is self-contained — copy, paste, deploy.

Return JSON

const http = require('http');

http.createServer((req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
        success: true,
        data: { id: 123, name: "John" }
    }));
});

server.listen(8080);

Return HTML

const http = require('http');

http.createServer((req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const html = `
        <!DOCTYPE html>
        <html>
            <body><h1>Hello from Edge</h1></body>
        </html>
    `;

    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(html);
});

server.listen(8080);

Return Binary

const http = require('http');

http.createServer(async (req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const imageResponse = await fetch("https://your-bucket.s3.amazonaws.com/logo.png");
    const imageData = Buffer.from(await imageResponse.arrayBuffer());

    res.writeHead(200, { 'Content-Type': 'image/png' });
    res.end(imageData);
});

server.listen(8080);

Parse Query Parameters

const http = require('http');
const { URL } = require('url');

http.createServer((req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const url = new URL(req.url, `http://${req.headers.host}`);
    const name = url.searchParams.get('name') || 'World';

    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
        message: `Hello ${name} from Telnyx Edge Compute!`,
        status: "success"
    }));
});

server.listen(8080);

Handle HTTP Methods

const http = require('http');

http.createServer((req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    let message;
    let status = 200;

    switch (req.method) {
        case 'GET':
            message = 'Hello from GET request!';
            break;
        case 'POST':
            message = 'Data received via POST!';
            break;
        default:
            message = 'Method not supported';
            status = 405;
    }

    res.writeHead(status, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
        message,
        status: status === 200 ? 'success' : 'error'
    }));
});

server.listen(8080);

Read Request Body

const http = require('http');

http.createServer((req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    if (req.method !== 'POST') {
        res.writeHead(405, { 'Content-Type': 'application/json' });
        return res.end(JSON.stringify({ error: 'Method not allowed' }));
    }

    let body = '';
    req.on('data', chunk => { body += chunk; });
    req.on('end', () => {
        try {
            const data = JSON.parse(body);
            if (!data.email) {
                res.writeHead(400, { 'Content-Type': 'application/json' });
                return res.end(JSON.stringify({ error: 'Email is required' }));
            }
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ status: 'success', email: data.email }));
        } catch {
            res.writeHead(400, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: 'Invalid JSON' }));
        }
    });
});

server.listen(8080);

Use Environment Variables

const http = require('http');

http.createServer((req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const greeting = process.env.GREETING || 'Hello';

    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
        message: `${greeting} from Telnyx Edge Compute!`,
        status: 'success'
    }));
});

server.listen(8080);

Access Secrets

Secrets are injected as environment variables but stored encrypted. Use them for API keys, tokens, and credentials.
const http = require('http');

http.createServer(async (req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const apiKey = process.env.EXTERNAL_API_KEY;

    if (!apiKey) {
        res.writeHead(500, { 'Content-Type': 'application/json' });
        return res.end(JSON.stringify({ error: 'API key not configured' }));
    }

    const response = await fetch('https://api.example.com/data', {
        headers: { 'Authorization': `Bearer ${apiKey}` }
    });

    const data: unknown = await response.json();
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(data));
});

server.listen(8080);

KV Read/Write

Coming Soon — KV storage is in development. The examples below show the expected API pattern.
Access KV storage for low-latency key-value data.
const http = require('http');

const KV_ID = process.env.KV_MY_STORE_ID;
const API_KEY = process.env.TELNYX_API_KEY;
const BASE_URL = `https://api.telnyx.com/v2/storage/kvs/${KV_ID}`;

async function kvGet(key) {
    const response = await fetch(`${BASE_URL}/keys/${key}`, {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
    });
    if (response.status === 404) return null;
    const data = await response.json();
    return data.value;
}

async function kvPut(key, value, ttl) {
    await fetch(`${BASE_URL}/keys/${key}`, {
        method: 'PUT',
        headers: {
            'Authorization': `Bearer ${API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ value, ttl })
    });
}

http.createServer(async (req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const cachedValue = await kvGet('user:123');

    if (cachedValue) {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        return res.end(cachedValue);
    }

    const userData = JSON.stringify({ id: 123, name: 'Alice' });
    await kvPut('user:123', userData, 3600);

    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(userData);
});

server.listen(8080);

Cron Trigger

Coming Soon — Native cron triggers are planned. The examples below show the expected pattern. Until then, use an external scheduler (GitHub Actions, AWS EventBridge) to call your function’s HTTP endpoint.
Functions can be triggered on a schedule via cron triggers. The request includes cron metadata.
const http = require('http');

http.createServer(async (req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const isCron = req.headers['x-telnyx-cron'] === 'true';
    const scheduleName = req.headers['x-telnyx-cron-schedule'] || '';

    if (isCron) {
        console.log(`Cron job triggered: ${scheduleName}`);

        // Your cron logic here

        res.writeHead(200, { 'Content-Type': 'application/json' });
        return res.end(JSON.stringify({ status: 'cron completed' }));
    }

    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ status: 'ok' }));
});

server.listen(8080);

WebSocket Handling

Coming Soon — WebSocket support is planned. The examples below show the expected pattern.
Handle WebSocket connections for real-time communication.
import (
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool { return true },
}

func handler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        http.Error(w, "WebSocket upgrade failed", http.StatusBadRequest)
        return
    }
    defer conn.Close()

    conn.WriteJSON(map[string]interface{}{
        "type":      "connected",
        "timestamp": time.Now().Unix(),
    })

    for {
        var msg map[string]interface{}
        if err := conn.ReadJSON(&msg); err != nil {
            break
        }

        conn.WriteJSON(map[string]interface{}{
            "type":       "echo",
            "original":   msg,
            "serverTime": time.Now().Unix(),
        })
    }
}

Service-to-Service Calls

Call other edge functions or external services with proper error handling and timeouts.
const http = require('http');

const INTERNAL_SERVICE_URL = process.env.USER_SERVICE_URL;

http.createServer(async (req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    let body = '';
    req.on('data', chunk => { body += chunk; });
    req.on('end', async () => {
        try {
            const { userId } = JSON.parse(body);

            const controller = new AbortController();
            const timeout = setTimeout(() => controller.abort(), 5000);

            const userResponse = await fetch(`${INTERNAL_SERVICE_URL}/users/${userId}`, {
                headers: {
                    'Authorization': req.headers['authorization'],
                    'X-Request-ID': req.headers['x-request-id'] || crypto.randomUUID()
                },
                signal: controller.signal
            });

            clearTimeout(timeout);

            if (!userResponse.ok) {
                res.writeHead(userResponse.status, { 'Content-Type': 'application/json' });
                return res.end(JSON.stringify({ error: 'User service error' }));
            }

            const user = await userResponse.json();
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ user }));

        } catch (error) {
            if (error.name === 'AbortError') {
                res.writeHead(504, { 'Content-Type': 'application/json' });
                return res.end(JSON.stringify({ error: 'Service timeout' }));
            }
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: 'Internal error' }));
        }
    });
});

server.listen(8080);

Connection Reuse

Initialize HTTP clients once at module level to reuse connections across requests.
const http = require('http');

// Module-level config (reused across requests)
const httpClient = {
    baseUrl: 'https://api.example.com',
    headers: {
        'Authorization': `Bearer ${process.env.API_KEY}`,
        'Content-Type': 'application/json'
    }
};

http.createServer(async (req, res) => {
    if (req.url === '/health/liveness' || req.url === '/health/readiness') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return res.end('ok');
    }

    const response = await fetch(`${httpClient.baseUrl}/data`, {
        headers: httpClient.headers
    });

    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(await response.text());
});

server.listen(8080);