Treat the category as a policy object
FreePBX's Music on Hold module groups media into named categories. The category is the reusable policy selected by another call-flow object; it is not proof that a particular caller was placed on hold or heard a particular file. Keep category name, source type, file list, random-play setting, selector and runtime class in the change record.
Sangoma documents category selection in inbound routes, outbound routes, ring groups, queues and conferences. A category selected at the call target can override the inbound-route category for that target, after which the call can fall back to the inbound-route category when it leaves. Reconstruct the call's actual path before treating the default category as authoritative.
Prefer bounded static files
The documented static workflow accepts WAV or MP3 uploads and converts MP3 during upload. Preserve the original authorized asset, checksum, source license, upload result, generated file inventory, level adjustment and target category. A completed browser upload does not establish that conversion finished, Asterisk loaded the file or a caller decoded it.
Random play changes which file starts for a caller; disabling it starts at the first item and follows the uploaded order. Validate every file in a category rather than accepting one call as coverage of a random set. Re-upload is required to change the documented per-file volume adjustment.
Keep copyright permission with the asset
Sangoma warns that ordinary radio, CD and online content is not automatically licensed for telephone hold use. Maintain the rightsholder, applicable license, attribution or paid grant, permitted use, territory, term and evidence for every imported asset. An Asterisk-distributed track's documented Creative Commons terms do not transfer to unrelated recordings.
Treat legal review and technical acceptance as separate. A file can be playable but unauthorized, or licensed but poorly encoded for the deployed voice path. Do not copy credentials, private URLs or licensed media into public tickets or repositories.
Use streaming only with explicit risk ownership
Sangoma's public guide says streaming music on hold is not recommended for production servers and describes results as source- and stream-dependent. A streaming category adds a source process, network path, decoder, format, restart and resource-usage boundary that static files do not have.
If an approved exception remains necessary, pin the application path and options, restrict its identity and network reach, define source authentication and outage behavior, monitor the process and PBX resources, and prove fail-closed or fallback behavior. A reachable stream URL is not evidence that every held call receives stable audio.
Distinguish call-flow class from channel override
Asterisk can take a class explicitly in MusicOnHold() or from the channel's musicclass; Dial() can also name a class while supplying pre-answer hold music. PJSIP endpoint configuration can suggest a default class. Preserve the generated dialplan and runtime channel evidence because a correct FreePBX form can be superseded later in the path.
The Asterisk MusicOnHold application does not answer the channel by itself. Separate answer or progress, class selection, start event, media frames, listener result, stop or bridge and resume. A class name in MusicOnHoldStart is narrower than proof of the selected track or audible content.
Keep local generation and remote hold distinct
PJSIP can generate hold media locally or pass hold and unhold signaling to another system depending on endpoint and channel policy. Confirm which side owns media for the affected dialog before replacing local files. A locally valid category cannot correct silence produced by a provider, remote PBX or endpoint that owns the held-media leg.
Record SDP direction, any re-INVITE, endpoint moh_passthrough behavior, selected class and RTP source separately. Do not generalize a fix for early media, queue waiting or an endpoint hold button across all of those states.
Verify selection, audio and return from hold
Use one authorized non-emergency call per relevant path: inbound route, ring group, queue, conference, outbound waiting treatment or endpoint hold. Confirm the expected category, runtime start event, file or stream source, level and intelligibility, hold and resume in both directions, fallback and CPU or transcoding impact.
Retain the previous category assignments, file list, order, stream configuration and rollback trigger. Use the silent or wrong music diagnostic when the runtime result diverges. No PBX or call was tested for this guide.
Keep hold intent, SIP signaling and music generation separate
The Asterisk HOLD_INTERCEPT guide distinguishes a suppressed device hold frame and event from PJSIP hold signaling, ARI hold control and the music class heard by a channel.
Confirm local ownership before changing a music category
The PJSIP passthrough guide shows when Asterisk generates music locally and when a remote endpoint, PBX or provider owns the held-media result.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Sangoma FreePBX Music on Hold user guide ↗
- Sangoma FreePBX Music on Hold module ↗
- Asterisk MusicOnHold application ↗
- Asterisk CHANNEL function ↗
- Asterisk Dial application ↗
- Asterisk MusicOnHoldStart event ↗
- Asterisk res_pjsip configuration reference ↗
- Asterisk voice-prompt and music-on-hold licensing ↗
- Asterisk HOLD_INTERCEPT function ↗
- Asterisk AMI Hold event ↗
- Asterisk AMI Unhold event ↗
- Asterisk REST data models: ChannelHold and ChannelUnhold ↗
- Asterisk ARI Channels REST API ↗
- Asterisk PJSIP_MOH_PASSTHROUGH function ↗
- Asterisk PJSIP_ENDPOINT dialplan function ↗
- Asterisk pjsip.conf sample ↗
- RFC 6337: SIP usage of the offer-answer model ↗
- RFC 3264: An offer-answer model with SDP ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.