Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/signalwire/freeswitch/llms.txt

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

FreeSWITCH has a rich internal event system. Every significant action — a call being created, answered, hung up, a DTMF digit being pressed, a channel variable changing — generates an event. Event handler modules subscribe to these events and act on them: writing call detail records to disk or a database, publishing messages to a message broker, forwarding events over a TCP socket to external applications, or integrating with monitoring infrastructure. Loading the right event handlers is essential for billing, observability, and external integrations.

Available Event Handler Modules

ModulePurpose
mod_event_socketTCP-based Event Socket Layer (ESL) — the primary external control interface
mod_cdr_csvWrite call detail records as delimited text (CSV) to flat files
mod_cdr_sqliteWrite CDRs to a local SQLite database
mod_cdr_pg_csvWrite CDRs directly to a PostgreSQL database
mod_json_cdrWrite CDRs as JSON objects to a file or HTTP endpoint
mod_format_cdrTemplate-based CDR writer supporting custom output formats
mod_odbc_cdrWrite CDRs to any ODBC datasource (MSSQL, MySQL, etc.)
mod_amqpPublish FreeSWITCH events and CDRs to an AMQP broker (RabbitMQ)
mod_event_multicastBroadcast events as UDP multicast packets to multiple listeners
mod_erlang_eventBridge FreeSWITCH events into an Erlang node’s message bus
mod_snmpExpose FreeSWITCH operational metrics via SNMP
mod_smppSend and receive SMS messages via the SMPP protocol
mod_fail2banEmit log events in the fail2ban format to assist brute-force blocking
mod_event_testDeveloper utility that logs raw events for debugging

mod_event_socket

mod_event_socket is the most important event handler module. It exposes FreeSWITCH’s Event Socket Layer (ESL) — a plain-text TCP protocol on port 8021 that allows external programs to subscribe to events, execute API commands, and control individual calls in real time. Nearly all external FreeSWITCH integrations (call control applications, monitoring dashboards, dialers) communicate via the Event Socket. For full protocol and client library documentation, see ESL Overview.

Configuration

ESL is configured in conf/autoload_configs/event_socket.conf.xml:
<configuration name="event_socket.conf" description="Socket Client">
  <settings>
    <param name="nat-map" value="false"/>
    <param name="listen-ip" value="::"/>
    <param name="listen-port" value="8021"/>
    <param name="password" value="ClueCon"/>
    <!-- Restrict access by ACL -->
    <!--<param name="apply-inbound-acl" value="loopback.auto"/>-->
  </settings>
</configuration>
The default password ClueCon is well-known. Always change it in production and restrict the listening IP to trusted addresses or use an ACL. The Event Socket grants full administrative control over FreeSWITCH to any authenticated client.

Inbound Mode

In inbound mode, an external application connects to FreeSWITCH on port 8021, authenticates with the password, and then issues commands or subscribes to events:
# Connect with telnet (for testing only)
telnet 127.0.0.1 8021

# The server sends:
# Content-Type: auth/request

# Authenticate:
auth ClueCon

# Subscribe to all events:
events plain ALL

# Execute an API command:
api status

# Kill a specific channel:
api uuid_kill <uuid>

Outbound Mode

In outbound mode, FreeSWITCH connects out to an external application when a call reaches a dialplan extension that uses the socket application. The external app then drives the call:
<!-- Dial plan entry that hands off call control to an external app -->
<extension name="external_app">
  <condition field="destination_number" expression="^7000$">
    <action application="socket" data="127.0.0.1:8084 async full"/>
  </condition>
</extension>

CDR Modules

FreeSWITCH supports multiple CDR backends. Choose based on your storage and reporting requirements:

mod_cdr_csv

Best for: Simple deployments, Asterisk migrations, flat-file billing feeds. Writes one line per call to a CSV file using a configurable template. Supports log rotation and multiple named templates.

mod_cdr_sqlite

Best for: Single-server deployments needing SQL queries without an external DB. Stores CDRs in a local SQLite database (Master.db). No external dependencies.

mod_cdr_pg_csv

Best for: Production environments with a shared PostgreSQL server. Writes CDR fields as columns into a configurable table. Supports connection pooling.

mod_json_cdr

Best for: Modern integrations, log aggregation pipelines (ELK, Splunk). Writes a complete JSON object per call, either to a file or POSTed to an HTTP endpoint.

mod_cdr_csv

mod_cdr_csv writes CDRs using named templates defined in conf/autoload_configs/cdr_csv.conf.xml. The example template is the default:
<configuration name="cdr_csv.conf" description="CDR CSV Format">
  <settings>
    <param name="default-template" value="example"/>
    <param name="rotate-on-hup" value="true"/>
    <!-- Log A-leg only, B-leg only, or both -->
    <param name="legs" value="a"/>
  </settings>
  <templates>
    <template name="example">
      "${caller_id_name}","${caller_id_number}","${destination_number}",
      "${context}","${start_stamp}","${answer_stamp}","${end_stamp}",
      "${duration}","${billsec}","${hangup_cause}","${uuid}",
      "${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}"
    </template>

    <template name="sql">
      INSERT INTO cdr VALUES (
        "${caller_id_name}","${caller_id_number}","${destination_number}",
        "${context}","${start_stamp}","${answer_stamp}","${end_stamp}",
        "${duration}","${billsec}","${hangup_cause}","${uuid}",
        "${bleg_uuid}","${accountcode}"
      );
    </template>

    <template name="asterisk">
      "${accountcode}","${caller_id_number}","${destination_number}",
      "${context}","${caller_id}","${channel_name}","${bridge_channel}",
      "${last_app}","${last_arg}","${start_stamp}","${answer_stamp}",
      "${end_stamp}","${duration}","${billsec}","${hangup_cause}",
      "${amaflags}","${uuid}","${userfield}"
    </template>
  </templates>
</configuration>
CDR files are written to $${log_dir}/cdr-csv/ by default (e.g., /var/log/freeswitch/cdr-csv/), with one file per template name and a Master.csv that consolidates all records.

mod_amqp

mod_amqp publishes FreeSWITCH events and CDRs as messages to an AMQP-compatible message broker such as RabbitMQ. This is the preferred integration pattern for distributed systems where multiple services need to react to call events asynchronously — billing engines, CRM systems, real-time dashboards, and analytics pipelines.

How It Works

mod_amqp maintains persistent AMQP connections defined in named profiles. Each profile can publish three types of data:
  • Event producers — Subscribe to FreeSWITCH events and publish each one as an AMQP message to a topic exchange.
  • Command consumers — Consume AMQP messages and execute them as FreeSWITCH API commands (enables remote call control via AMQP).
  • Log producers — Ship FreeSWITCH log output to an AMQP exchange.

Configuration

<!-- conf/autoload_configs/amqp.conf.xml (excerpt) -->
<configuration name="amqp.conf" description="mod_amqp">
  <producers>
    <profile name="default">
      <connections>
        <connection name="primary">
          <param name="hostname" value="localhost"/>
          <param name="virtualhost" value="/"/>
          <param name="username" value="guest"/>
          <param name="password" value="guest"/>
          <param name="port" value="5672"/>
          <param name="heartbeat" value="0"/>
        </connection>
      </connections>
      <params>
        <param name="exchange-name" value="TAP.Events"/>
        <param name="exchange-type" value="topic"/>
        <param name="reconnect_interval_ms" value="1000"/>
        <param name="send_queue_size" value="5000"/>

        <!-- Routing key built from these event header fields -->
        <param name="format_fields"
          value="#FreeSWITCH,FreeSWITCH-Hostname,Event-Name,Event-Subclass,Unique-ID"/>

        <!-- Publish only these events -->
        <param name="event_filter"
          value="SWITCH_EVENT_CHANNEL_CREATE,SWITCH_EVENT_CHANNEL_DESTROY,
                 SWITCH_EVENT_HEARTBEAT,SWITCH_EVENT_DTMF"/>
      </params>
    </profile>
  </producers>
</configuration>

Routing Key Format

The routing key for each published message is built dynamically from the format_fields parameter. Fields prefixed with # are treated as literal strings; all others are looked up in the event headers. For the configuration above, a CHANNEL_CREATE event from a server named fs01 would produce the routing key:
FreeSWITCH.fs01.CHANNEL_CREATE..3f2a1b4c-...

Use Cases

  • Billing — Subscribe to CHANNEL_DESTROY to capture call duration for real-time rating.
  • CRM integration — Subscribe to CHANNEL_ANSWER to create a CRM ticket the moment a call is answered.
  • Real-time dashboards — Subscribe to all call events to drive a live wallboard showing active calls per queue.
  • Distributed call control — Use the command consumer to route FreeSWITCH API commands from a central orchestrator to multiple media servers.

mod_event_multicast

mod_event_multicast broadcasts FreeSWITCH events as UDP multicast packets. Multiple servers on the same LAN can subscribe to the multicast group and receive a copy of every event without requiring individual point-to-point connections. This is primarily used for real-time event mirroring across a cluster of FreeSWITCH nodes.

mod_erlang_event

mod_erlang_event integrates FreeSWITCH with an Erlang/OTP node. It exposes the FreeSWITCH event bus as native Erlang messages, making it natural to write call control applications in Erlang using OTP behaviours such as gen_server and gen_fsm.

mod_snmp

mod_snmp exposes FreeSWITCH operational metrics through an SNMP agent. It provides MIB objects for active call count, registered endpoints, and system health. This enables FreeSWITCH to integrate with standard network monitoring tools such as Nagios, Zabbix, and PRTG.

mod_smpp

mod_smpp implements the SMPP v3.4 protocol for sending and receiving SMS messages via an SMPP-capable SMS gateway or carrier. Inbound SMS messages generate FreeSWITCH events that can be routed to dialplan extensions or Lua/Python scripts. Outbound messages can be sent from the dialplan using the send_message API.

mod_fail2ban

mod_fail2ban monitors FreeSWITCH authentication events and emits log lines in a format that the fail2ban daemon can parse. When fail2ban detects repeated SIP authentication failures from the same IP address, it automatically creates an iptables rule to block that address. This provides lightweight brute-force protection for public-facing SIP profiles without requiring firewall integration in FreeSWITCH itself.

Build docs developers (and LLMs) love