Webhooks

Webhooks allow TeamMessage to communicate with your systems via HTTP callbacks. Use them for message delivery, status notifications, or to forward messages to external services.

Overview

TeamMessage supports three types of webhooks:

  • Webhook as Delivery Channel – Forward messages from a team list to your server
  • Delivery Reports – Receive notifications when SMS are delivered or fail
  • Incoming SMS – Forward received SMS to your server (sms2mail exklusiv)

Webhook as Delivery Channel

Add a webhook URL as a team member to forward all messages sent to the team list to your server. This is useful for integrating TeamMessage with ticketing systems, chat platforms, or custom applications.

Configuration

  1. Go to your team list → Members
  2. Click 'Add Member'
  3. Select channel: Webhook
  4. Enter your webhook URL (must start with https://)

Request Format

When a message is sent to the team list, TeamMessage sends a POST request with JSON:

Example request

POST /your-webhook-endpoint HTTP/1.1
Host: your-server.example.com
Content-Type: application/json; charset=UTF-8

{
  "from": "+491711234567",
  "message": "This is the message text",
  "teamlist_id": 123,
  "teamlist_email": "alerts@tmsg.de",
  "recipient_name": "My Webhook",
  "timestamp": 1736694000
}

Parameters

Parameter Type Description
from string Sender identifier (phone number or alias)
message string The message text (UTF-8 encoded)
teamlist_id integer Internal ID of the team list
teamlist_email string Email address of the team list
recipient_name string Name of the webhook member
timestamp integer Unix timestamp (seconds since 1970-01-01)

Expected Response

Your endpoint should return an HTTP 2xx status code (200, 201, 204) to indicate success:

Success response

HTTP/1.1 200 OK
Content-Type: application/json

{"status": "received"}

Note

The response body is not evaluated. Only the HTTP status code matters. Timeout is 10 seconds.

Use Cases

  • Forward alerts to Slack, Microsoft Teams, or Discord
  • Create tickets in Jira, Zendesk, or other ticketing systems
  • Log messages to a database or monitoring system
  • Trigger automated workflows (Zapier, n8n, Make)

Delivery Reports

Delivery report webhooks notify you about the final status of sent SMS messages.

Configuration

Configure a webhook URL in your team list settings:

  1. Go to Team List Settings
  2. Enter your webhook URL in the 'Delivery Report URL' field
  3. The URL must be a valid HTTP or HTTPS endpoint

Tip

Use HTTPS for secure transmission. Your webhook endpoint should respond within 10 seconds.

Request Format

TeamMessage sends a POST request with form-encoded data:

Example request

POST /your-webhook-endpoint HTTP/1.1
Host: your-server.example.com
Content-Type: application/x-www-form-urlencoded

status=0&reason=0&to=004917012345678&msgid=123456&timestamp=2025-01-08T14:30:00Z

Parameters

Parameter Description Example
status Delivery status code (0 = delivered) 0
reason Reason code providing additional detail 0
to Recipient phone number 004917012345678
msgid Unique message identifier 123456
timestamp Time of delivery or failure (ISO 8601) 2025-01-08T14:30:00Z

See Status Codes for a complete list of status and reason codes.

Retry Behavior

If your endpoint doesn't respond with HTTP 200:

  • TeamMessage retries after 5 minutes
  • Up to 3 retry attempts
  • After all retries fail, the notification is discarded

Incoming SMS Webhooks

With sms2mail exklusiv, incoming SMS messages can be forwarded to a webhook URL instead of email.

Request Format

Incoming SMS webhook

POST /your-webhook-endpoint HTTP/1.1
Host: your-server.example.com
Content-Type: application/json

{
  "from": "+491711234567",
  "to": "+491512345678",
  "message": "The SMS text content",
  "timestamp": "2025-01-08T14:30:00Z"
}

Parameters

Parameter Description
from Sender's phone number (E.164 format)
to Your dedicated phone number
message The SMS text content
timestamp When the SMS was received (ISO 8601)

Implementation Examples

Python (Flask)

from flask import Flask, request, jsonify

app = Flask(__name__)

# Webhook as delivery channel
@app.route('/webhook/message', methods=['POST'])
def message_webhook():
    data = request.get_json()

    print(f"Message from {data['from']}: {data['message']}")
    print(f"Team list: {data['teamlist_email']}")

    # Process the message (create ticket, forward to Slack, etc.)
    # ...

    return jsonify({"status": "received"}), 200

# Delivery report webhook
@app.route('/webhook/delivery', methods=['POST'])
def delivery_webhook():
    status = request.form.get('status')
    reason = request.form.get('reason')
    to = request.form.get('to')
    msgid = request.form.get('msgid')

    if status == '0':
        print(f"Message {msgid} delivered to {to}")
    else:
        print(f"Message {msgid} failed: status={status}, reason={reason}")

    return 'OK', 200

PHP

<?php
// webhook_message.php - Webhook as delivery channel
$data = json_decode(file_get_contents('php://input'), true);

$from = $data['from'] ?? '';
$message = $data['message'] ?? '';
$account = $data['teamlist_email'] ?? '';

error_log("Message from {$from} to {$account}: {$message}");

// Process the message
// ...

http_response_code(200);
echo json_encode(['status' => 'received']);

// ---

// webhook_delivery.php - Delivery reports
$status = $_POST['status'] ?? '';
$reason = $_POST['reason'] ?? '';
$to = $_POST['to'] ?? '';
$msgid = $_POST['msgid'] ?? '';

if ($status === '0') {
    error_log("Message {$msgid} delivered to {$to}");
} else {
    error_log("Message {$msgid} failed: status={$status}, reason={$reason}");
}

http_response_code(200);
echo "OK";

Node.js (Express)

const express = require('express');
const app = express();

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

// Webhook as delivery channel
app.post('/webhook/message', (req, res) => {
    const { from, message, teamlist_email, timestamp } = req.body;

    console.log(`Message from ${from}: ${message}`);
    console.log(`Team list: ${teamlist_email}`);

    // Process the message
    // ...

    res.status(200).json({ status: 'received' });
});

// Delivery report webhook
app.post('/webhook/delivery', (req, res) => {
    const { status, reason, to, msgid } = req.body;

    if (status === '0') {
        console.log(`Message ${msgid} delivered to ${to}`);
    } else {
        console.log(`Message ${msgid} failed: status=${status}, reason=${reason}`);
    }

    res.send('OK');
});

app.listen(3000);

Testing Webhooks

Before going live, test your webhook implementation:

  1. Use a test tool like webhook.site or ngrok to inspect incoming requests
  2. Add the test URL as a webhook member in your team list
  3. Send a test message to the team list
  4. Verify the request appears on webhook.site with correct JSON payload

Tip

During development, use ngrok or a similar tool to expose your local server to the internet for testing webhooks.

Security Considerations

  • Use HTTPS to encrypt webhook data in transit
  • Add a secret token to your webhook URL for validation (z.B. https://example.com/webhook?token=secret123)
  • Process webhooks asynchronously to avoid timeout issues
  • Log all webhook requests for debugging and auditing
  • Implement idempotency – handle duplicate notifications gracefully

Note

Webhook URLs are called from TeamMessage servers. If you have firewall restrictions, contact support for our IP ranges.

Menu