Page tree
Skip to end of metadata
Go to start of metadata


Lua is the preferred scripting language for custom applications based on FreeSWITCH.

The Lua API documentation is provided here Lua API Reference

Since FreeSWITCH 1.4, you need to use Lua5.2 (

For those willing to keep using Lua5.1 for backwards compatibility reasons, there is a mod_lua available in legacy directory `freeswitch/src/mod/legacy/languages/mod_lua/`



 Click here to expand ToC


On Centos 6.x:



Write IVR scripts in Lua

It has a very easy to use syntax, see the Hello Lua script.

Add event hooks in Lua

You can define a Lua script to be executed each time a specific event is fired. See: Mod_lua#Event_Hooks

Serve configs

Lua can serve configurations for xml_curl, without requiring a web server, this works in a similar way to mod_xml_curl.

See: Mod_lua/Serving_Configuration 

Make API calls directly from Lua code



Stripped is 272k

Highly Embeddable

As far as embeddability goes - Python ranks a 2, Perl ranks a 4, JavaScript is a 5, and Lua is a 10!

Learning Lua

Here's a comparison on some salient points to Javascript: [1]

CLI Usage: lua and luarun

You can issue a "luarun /path/to/script.lua" and launch a thread which your lua script will run in. The "lua" command is for inline lua like from the dialplan i.e. ${lua(codehere)}. "luarun" will spawn a thread while "lua" will block until the code is complete. A "~" in front of the argument will run a single line lua command. Note that lua scripts executed with luarun cannot write to the console through stream:write API as there is no stream.

Passing Arguments

Arguments are passed as space-separated values:

Arguments are accessed with "argv" like this:

And so on...


Event Hooks

The following configuration shows how to have the tone_event.lua script executed each time the DETECTED_TONE event is fired.

Event Hook Script

This is an example event hook script. getHeader() can be called on the event to get information about the event.

For IVR use

Nothing should be needed here.

For making API calls

Note: Please take care to escape the arguments that you pass, as has been done to the regex string above.

To call another Lua script

For serving configuration

mod_lua allows you to replace request for configuration data from a lookup in the static XML to your script.

See Mod_lua/Serving_Configuration for more information.

Lua scripts at startup

Here is a minimum configuration file:

The start-up script values represent lua scripts (located inside the scripts/ directory) that are launched when FreeSWITCH is started. The scripts live in their own thread. You can use them to run simple tasks (and then let them finish) or looping forever, watching (for example) for events, generating calls or whatever you like.

Sample Dialplan


NOTE: arguments can be accessed by using argv[1] argv[2] in your script

NOTE: for looking up the location of the helloworld.lua file, it looks in prefix/scripts by default

In-line expansion


Sample IVR's

This is a basic IVR example, in which we answer the call, wait 1 second and play an wav audio file.

Pattern matching (regular expressions)

Regex API Example

Using this method, you can execute regex conditions from inside your lua scripts.

If destination is a lua variable with your destination number in it, and your regex was ^([0-9]{10})$

the result will be put in "some_chan_variable" that you can get thorough a session:getVariable

You can also do:

To match and return parts of your regex.

Native Lua Pattern Matching

Lua supports a simple but powerful pattern matching syntax. It is less powerful than PCRE but it handles the majority of pattern matching cases will ever need in a simple script.

The following is a simple script that can be run with "luarun" from fs_cli and demonstrates the capturing of two values from a data string:

Misc. Samples

Run a shell command

When using session:execute() and api:execute() to execute a shell command (ie: bash script) it will only return the error code integer.

To return the output of a shell command use io.popen(). The following example Lua function is from


Why is mod_lua not unloadable?

Some threads explaining why the decision was made

mod_lua was reloadable  but when I found that long-running scripts cannot be  easily stopped the developers changed it to un-reloadable.
There's also a blog page in Chinese explaining this:
(...truncated thread...)
The reason being if the module unloads while scripts are still running you're going to be almost guaranteed a segmentation fault - a well meaning admin running a simple command could crash the entire server dropping all calls.

Where is my debug information?

Q: When I use static XML or xml_curl, I see the commands executed in the fs_cli and in the "application log" section of the xml_cdr file. However, when I run commands via my lua script, I don't see that information anywhere?

A: When you have an actual call session, you can use session:execute("$application","$data") just like in the static XML - it will then show up in the fs_cli and the xml_cdr application log. If you don't have a call session - e.g. if you are running lua as a background application or from the CLI, then you have to use other commands which may not be as easily logged.

How can I make it use the "system lua"

Q: I have Lua installed, but mod_lua seems to ignore the Lua binary.

A: Lua is so small that the whole ball of wax is statically linked into the module!

How can I get Lua to see my own libraries using "require"

Q: Can I use the require mechanism for including libraries with the Lua in FreeSWITCH?

A: You may need to alter the LUA_PATH variable to instruct the embedded Lua inside FreeSWITCH to find your libraries. A simple startup script to do this is:

The default path is something like /usr/local/share/lua/5.1/

Another option for common code similar to the "include" directive in many languages is to use dofile

eg. dofile("/home/fred/scripts/fredLuaFunctions.lua")

Note that this will just execute the code contained in the file as if it were inline - this is not the same as creating a lua module

How can I find useful undocumented Functions?

There may be times when a function gets added, but not documented. This simple Lua script may help.

At freeswitch version FreeSWITCH Version 1.6.17-34-0fc0946~64bit (-34-0fc0946 64bit) this is the output of the script:

 Click here to expand the output of the script

Jester Lua Toolkit

Jester is a scripting lua toolkit for FreeSWITCH :Wiki Jester

See Also


  1. Freeswitch on Debian currently depends on libodbc and unixodbc.  We have found both of these versions very unstable in high call volume environments.  Upgrading to MySQL ODBC driver 5.3.4 with unixODBC 2.3.1 has really improved our stability and we have not seen any crashes since the full rebuild of the environment.

  2. From what I'm reading about LUA, arguments passed from the dialplan into the LUA script will be available as arg[1], arg[2], etc, not argv[n] as stated above.

    1. Tom, have you tested each form of argument reference in Lua using the current versions of everything since the recent upgrades? I have seen numerous Lua script examples and all use what is documented here. I can't believe that all of them are wrong and nobody has pointed it out yet.

  3. John, as it turns out, I'd been having trouble getting arguments to work at all.  Today I see that argv does in fact work.  I'd been looking at LUA documentation that seemed to contradict this, though.  Thanks.