FreePBX Extension Routing Module

FreePBX Extension Routing Made Easy…

Amongst the many requests that FreePBX continuously receives, one of the most common has been the ability to allow only certain routes to be used by specific extensions. A common but very complicated and incomplete solution often tried is the unsupported Custom Context module. There have been other modules and solutions used to address this need but as a general rule, they have been burdened with hard to understand and often incomplete solutions such as “security” loop holes where restricted phones could still provide call forwarding to routes they should not have access to.

Because the frequency of requests Schmooze Com has seen both in the forums and while providing paid support services to FreePBX customers, we’ve decided to leverage some of our commercial module technology we use to solve this problem. We have added a free module that provides simple and easy to understand configuration. We are excited to provide this not only on the 2.11 up-and-coming release but on the current 2.10 release as well!

The module is called the Extension Routing module and its focus has been very specific: allow any extension to be restricted to a subset of routes, including any calls launched by that extension whether from Call Forwarding, Follow-Me or VmX Locator.

This can be configured one of two ways. Once the module is installed, each extension (or user) will have a section that includes a list of Outbound Routes configured on the system. By default they are all enabled. From here you can restrict or include any route for each extension as seen in the screenshot.

Alternatively, under each route you will be provided with two boxes that list all the “Allowed Extensions” and “Blocked Extensions” for that route. You can simply drag and drop extensions between the boxes to make adjustments to the route!

It really is “that” easy and if that is not easy enough, then have a look at the Extension Routing PDF UserGuide that we prepared to step you through it. All other aspects of standard Outbound Routing and Trunks will work as configured and calls that are sent out from the system that do not belong to an extension will not be affected having access to all routes as normal, such as an external configured in a Ring Group or Queue.

As mentioned, the module is free but since it includes a lot of code from our commercial modules, you will have to make sure your PBX is registered in the Schmooze/FreePBX Portal where other commercial modules and FreePBX paid support business is conducted. If you need step by step instructions on how to register, check out our How to Register a Deployment. This process simply provides your deployment with a unique id which is needed to obtain the free license required to run this module. There is no limit to the number of deployments you can obtain licenses for!

Once registered just go and “purchase” a $0 license for any of your registered deployments, the module itself can be downloaded to any system through the online Module Admin by enabling the Commercial Repository in the GUI.

One small note, you’ll need a proper Zend environment to be able to run this module as is the case with many of the other commercial modules. If you are running the FreePBX Distro then you are covered and we’ve also worked with the PBXiaF team in the past to enable these modules for them as well, so as long as you have their version 2.0.6 or greater, you are also covered. Otherwise, sorry but you’re on your own as you’ll need the Zend environment in addition to the System Admin Module in FreePBX which includes some specific FreePBX Distro RPMs that must also be installed. It’s a bit complicated and why we do all the work for you on our nice, clean FreePBX Distro!

For now, enjoy and give us feedback if the module is meeting the needs that we see constantly being requested!

Tony Lewis on behalf of the FreeBPX and Schmooze Team!

That’s a great development Tony - I wonder if it could be enhanced a little more and include facility to add a discrete CID for each route? From my point of view that would really be the icing on the cake!

You can already set the Caller ID on a per route basis in FreePBX. Not sure if I am missing the point here.

I would like to be able to send different CID’s on different routes. For example I have extensions that have a US number, a UK number and a local number, each one requiring a different CID to be sent on the appropriate outgoing route as I have one US route that is common to all extensions but each extension needs to send a discrete CID, likewise with the UK and local routes.

At the moment if only two routes are required I can make the local route an emergency route and set the emergency CID on the extension and I can set the outbound CID on the extension to the CID for the other route.

The trouble starts when you have a third route involved, the only way to do that is to set up a discrete route for each individual extension with an override CID set and the extension CID set in the outgoing routing patterns.

Quite possible, but tedious to set up Especially when you have many extensions and numerous outgoing routing patterns. I have many routing patterns because I do least cost routing sending transit international calls to the cheapest route which could be any one of the outgoing routes.

It would be great to only have to set the CID at the extension level for each route, thus avoiding a lot of tedious setup when a new customer is added.

Hope that makes sense.

Look at the Caller ID Management module.

I am not sure, as I read it the module sets the CID to be sent but needs a manually entered feature code to change the CID sent.

If I am right it seems to me it would be incumbent upon the user to select the correct CID before making a call which is not likely to happen correctly every time.

I wonder if I am missing something and there a way to have the route determined by the dial pattern send the feature code before the route passes the call to the outbound trunk?


the need you mention is understood, to be able to have different caller-id’s per extension based on route used.

It’s a valid need and one that has been discussed before but it’s quite separate from what this module is intended to tackle and from the common requirement that led to implementing this module.

There’s likely a feature request for your ‘per-extensions-per-route’ CallerID need but if not feel free to open one to keep it on the radar scope. Being part of this module would simply add additional complexity to a feature that was designed to be simple to understand and for an additional need that most users requiring this feature don’t need.

Point taken, it just seemed this might be as good a place as any to add a CID field alongside the route. I do understand that is the easy bit, of course the complex part is the part you don’t see that makes it work so it will have to wait for another day.

There is an open ticket #4424 so hopefully that will keep it on the radar!

Just did an install on a PIAF server, all seems to work well.

If possible I would like to see the settings listed in the Extension Settings screen.

Thanks for making this a free module.


have been wanting an easy way to do this for a while. Custom Contexts can be a bit buggy at times.
I have just registered my pbx on the portal, “bought” the module and now waiting from it to show in my licenses on the system admin window.
All i get is the below at present.

Product Name: OSS FreePBXDistro
Licensed Products:?
Extensions 0
Global License Expiration 03-Jan-2030
Zend status: Available

and nothing extra shows in either extensions or outbound routes.
I have already installed the module from module admin -> Commercial.

Is this just a time thing ???
i notice in the portal it is waiting for me to “pay” for the modules by entering my CC details. do i need to do this??
Thanks in advance.


You should be all set. All orders have to be approved by us once placed and the portal tells you this when you submit your order on the redirect page.

I thought it might be something like that from when i was in the portal. Just wasn’t sure on the awaiting payment thing if that would hold things up as i have not registered a CC.
I have updated in the System Admin -> Licenses section and yes it is there now.
Is showing up and configurable in both Extensions and Outbound Routes.

A big congratulations to the team there for listening to the community and bringing in this feature at no cost.


I created a new route and by default all the extensions were blocked on it.
I could allow an extension by either ticking in the extension settings or dragging in the outbound routes but i thought all were supposed to be allowed by default.

I am not seeing that when I use or test it. Is anyone else.

Is this module compatible with FreePBX

Weare using Elastix 2.3/FreePBX

No this module only works with 2.10 and only with FreePBX Distro and PBXiaF 2.0.6 or newer as stated above in the Blog

This is a great idea and definitely useful as is, but is there any way this could be made to work at the trunk level rather than the outbound route level? That way, if you had several extensions that each had their own dedicated trunk, you could have a single outbound route that would handle all their outgoing calls, and then out of the selected trunks for the route you could allow or disallow specific extensions from using particular trunks. It would make things easier than having to have a separate outbound route AND a dedicated trunk for each extension.

For example, let’s say you had three users that each had an individual account with a particular provider. This might happen because they have usage-based billing, or want their outgoing Caller ID to display their own personal number. The outbound route would likely have the exact same configuration for all three users, except that only the selected trunk would need to be different. Now imagine it’s 100 users rather than three, and you can see where the ability to whitelist or blacklist extensions on a per-trunk basis might come in handy.


We understand what you are asking and that there are use cases of which that would be easier for some users.

We made the choice this way to maximize the flexibility as well as keep it simple. Most of the use cases we have seen are more oriented around route restrictions such as limiting international and/or long distance calling, or lobby and other restricted calling phones.

The way we implemented it does allow a user to achieve a trunk level capability though in a more cumbersome way as you pointed out. Although there are “legitimate” use cases such as the caller id per user that you mentioned in cases where carriers do not allow such, the majority of such use cases are typically an attempt to do a form of multi-tenant configuration. Although users can and will find all sorts of ways to use FreePBX, it is still very much focused on a single entity PBX and as such the choices we make are oriented around that. Given that, this is why we made the choice to do it the way we have vs. trunk level or both. One could of course develop a similar module that addressed the trunk level scenario in addition to or in place of the route level as we did, but at this time it’s not in the roadmap at least for this module which is designed to keep simple and directed at the common requests that we have mostly seen.

First, thank You very much for your work!
(and sorry for my poor English…)
I made 2 trunks and 2 routes, one route use first trunk, another route - second trunk. Both routes use identically Dial Patterns. I denied for the “101” extention to use first route in list, and allowed to use second route.
But outgoing calls are routed over the fist route.
I tried the FreePBX distro’s “Stable-1.817.210.62” and old analog of “Stable EOL-1.817.210.58” (downloaded before the new distro roadmap has issued). Each of them has the same problem. Should I use “Stable-1.1009.210.62” ?
Thank You!

I would suggest you post a help request in the forums (vs. discussing the issue in the blog).

My guess is that you have another route prior to these using the suspect trunk, but posting more details in a new form thread will probably get to the bottom of it and more details can be requested there to help you find the issue.