VoIP.info Guide

FreePBX Custom Destinations: publish custom dialplan without losing ownership

Register a reviewed context, extension and priority as a managed destination, choose transfer or subroutine behavior deliberately, and keep source, generated state and call results separate.

Reviewed 2026-10-14Sangoma Custom Destinations, Misc Applications and Misc Destinations guidance; FreePBX Custom Applications 17.0.1 and Misc Applications 17.0.3 release/17.0 metadata and current dialplan sources; and current Asterisk Goto, Gosub, Return and dialplan documentation reviewed October 11, 2026; older screen guides establish concepts rather than an exact FreePBX 17 field map, and no installed module, code, application, destination, generated or loaded dialplan, caller path or call was inspected or testedAdvancedDocumentation based · not lab tested

Use the registry to expose owned dialplan, not to replace it

FreePBX Custom Destinations registers an existing custom dialplan target and makes it available to destination selectors such as inbound routes, IVRs and queues. The registry does not create the target code, prove that its context is loaded or make that code safe. Treat the GUI entry, source-controlled custom code, generated wrapper, loaded dialplan and call outcome as separate assets.

Give every custom destination an owner, purpose, callers, input contract and rollback. Keep its implementation in a supported custom-code location under the site’s change policy; do not put the durable implementation in FreePBX-generated files. Review privileges, external commands, data handling and reachable outbound routes before publishing it to more selectors.

Reconcile the documented screen with the installed FreePBX 17 branch

Sangoma’s detailed Custom Destinations guide identifies PBX GUI version 13. The current release/17.0 metadata reviewed here lists Custom Applications version 17.0.1, FreePBX 17 support and menu entries for Custom Extensions and Custom Destinations. Use the older guide for its documented target and return concepts, then verify the installed signed package, exact labels and supported actions on the target host.

Repository state does not establish the locally installed version, signature, database row, generated configuration or loaded runtime. Record those boundaries before changing anything. If the module is absent, disabled, unsigned or outside the supported platform baseline, resolve that through Module Admin rather than copying a screen sequence from another release.

Define the exact context, extension and priority

Sangoma documents a Custom Destination target as [context],[extension],[priority]. Record all three fields exactly, plus the file or module that owns the target, how that source becomes included, the variables it expects and every destination it may reach. A friendly description is not a runtime address, and a context name visible in a source file is not proof that the loaded dialplan can select it.

Use Asterisk’s loaded-dialplan inspection through an authorized operational workflow to prove the exact context, extension and priority exist. Asterisk searches extensions within context rules and includes; an unexpected pattern, include or duplicate can alter the match. Keep user-derived strings bounded and avoid logging credentials, PINs, caller data or other secrets while proving the target.

Choose transfer or subroutine behavior deliberately

Current FreePBX release/17.0 source handles the Return option as a control-flow decision. With Return disabled, the generated destination transfers directly to the configured target with Goto. With Return enabled, FreePBX publishes a wrapper destination that invokes the target with Gosub, expects the custom code to execute Return, and then sends the channel to the configured return destination.

These are not interchangeable labels. A direct transfer has no Custom Destinations return stack to resume. A returning target must end each intended branch with a valid Return; falling through, recursively selecting the wrapper or jumping to the wrong context can terminate or loop the call. Asterisk documents that Gosub saves a return location and Return removes that stack frame, while an invalid Goto location may ultimately terminate the channel.

Keep selectable destinations and dialable entry points distinct

A Custom Destination is a target that another FreePBX module can select. Sangoma separately defines Misc Applications as unique feature codes that internal phones dial to reach an existing PBX destination. Do not add a dialable feature code when the requirement is only to expose a destination to an IVR or route, and do not publish a privileged destination as a broadly dialable application without an access review.

Also keep Custom Extensions conceptually separate: registering or reserving an extension does not supply the underlying custom code. Before activation, search the effective numbering plan and feature-code inventory for collisions, and identify which inbound, internal and transferred calls can reach the custom path.

Validate the generated path, failure branches and rollback

Submit the exact target and Return choice, Apply Config through the supported FreePBX workflow, then compare saved intent, generated destination, loaded dialplan and one bounded runtime trace. Test the authorized source path, intended success branch, missing or invalid input, timeout or application error, and the configured post-return destination where applicable. Confirm an unrelated managed destination remains unchanged.

If the first failed boundary is the target, wrapper, loaded code or downstream action, repair only that owner. Roll back the selector and registry entry before removing still-referenced code, and retain a reference search for dependent routes. No PBX, installed module, custom target, generated or loaded dialplan, external command, destination, security control or call was inspected or tested for this guide.

Do not use a Custom Destination as a user access code

A Custom Destination registers reviewed custom dialplan as a selectable target. When authorized internal users need a code that points to a managed destination, use the Misc Applications boundary guide and keep source ownership, access-code allocation and final destination behavior separate.

Choose the wrapper that matches the owned target

Use the Misc Destinations guide for an already dialable number or feature selected by another module. Keep Custom Destinations for explicitly owned context, extension and priority targets.

Verify the destination after a dynamic result match

If a Dynamic Route entry points to a Custom Destination, first prove the exact result matched, then validate the custom target and return behavior. The Dynamic Routes diagnostic keeps those two handoffs separate.

Keep Set CallerID and custom destination ownership distinct

If a Set CallerID rule hands off to a Custom Destination, verify the channel identity before entry and then inspect the custom target. The Set CallerID guide prevents a later custom rewrite from being blamed on the module.

Keep the public custom destination stable while replacing Macro internals

The FreePBX 17 macro-to-Gosub guide preserves the module-owned destination entry while moving site-owned execution to an explicit Gosub contract in a supported custom include.

Sources & applicability

Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.

Examples require adaptation to your topology. No live PBX or hardware testing is claimed.