Business phone numbers and phone menus for the United States and Canada. FRES(510) 288-6288[email protected]Sign in

Home › Open-source VoIP › Kazoo (2600Hz)

Open-source VoIP

2600Hz Kazoo in depth: the platform, the API, and an auto attendant built on it.

Kazoo is the most ambitious open-source telephony platform there is: multi-tenant, built around an API, and designed for carriers and resellers rather than one office. It is also a project whose public releases, install guides and documentation have fallen years behind the code. This guide covers both, from 2600Hz’s documentation and the source itself.

Last checked 26 October 2026 · 56 cited sources · 22 min read

A multi-tenant telephony platform

What Kazoo is

Kazoo is 2600Hz’s telephony platform. The repository describes it as “The core of an open-source, distributed, highly scalable platform designed to provide robust telecom services”, and it has been on GitHub since December 2011.1 The README puts the intent more plainly: Kazoo is “an API-based platform that lets you use your existing phones, programming languages and IT skills to build voice, video and SMS services”, and its goal is to let you “create your own phone service in the cloud”.3

Three properties set it apart from a PBX such as Asterisk:

  • It is multi-tenant from the data model up. The account documentation says “Accounts represent tenants or customers on the system. Each account represents an individual dataset or sandbox that only one tenant can access.”16 Accounts nest in a tree, so a carrier can host resellers who host businesses.
  • Everything is configured through a REST API called Crossbar. The web interfaces (Monster UI, and now comm.land) are clients of that API, not a separate control path.1346
  • Call logic is data, not code. A “callflow” is a JSON tree of actions such as menu, ring group, voicemail and time-of-day routing, stored per account and run by the callflow application.17

Kazoo is not a single program either. It is a set of Erlang/OTP applications that coordinate Kamailio, FreeSWITCH, CouchDB and RabbitMQ.311 That design is why it scales across data centres, and also why it is hard to run. Both points come up again below.

The short version: Kazoo is a platform for building a phone service, not a phone system for one business. If you want an auto attendant for your own office, almost every other option on this site is simpler. If you want to sell hosted phone service to hundreds of businesses under your own brand, Kazoo is one of very few open-source codebases designed for exactly that.

The architecture, component by component

The README lists Kazoo’s foundations as “GNU/Linux, Erlang, FreeSWITCH, Apache CouchDB, and RabbitMQ”.3 The installation guide adds Kamailio, with 2600Hz’s own Kamailio configuration, as a requirement for voice, video and SIP.11 Here is what each one does, from each project’s own documentation:

LayerComponentRole in Kazoo
SIP edgeKamailio (version 5.2+, with the kazoo module)Listens for SIP from phones and carriers (port 5060 in the install guide) and passes calls to FreeSWITCH servers through its dispatcher; until FreeSWITCH servers are added, the dispatcher check reports “No Destination Sets”.1136 Kamailio’s kazoo module is “a general purpose AMQP connector” that exposes publish and consume to Kamailio’s routing logic,35 so the SIP proxy can ask the Erlang side questions in real time. The registrar application answers those questions: it “Handles caller authentication requests, by sender’s IP address or SIP username/password”.34
MediaFreeSWITCH (1.10+, with mod_kazoo)Answers calls, plays prompts, collects keypresses, records and bridges. The installation guide requires the mod_kazoo plug-in and 2600Hz’s FreeSWITCH configuration.11 2600Hz’s FreeSWITCH config loads mod_kazoo.40
Call controlecallmgr (Erlang)“Ecallmgr connects to and manages the FreeSWITCH servers and the interactions between higher-level applications and the FreeSWITCH layer.” Applications “don’t need to know which FreeSWITCH server the call they’re processing is located on”.33
Message busRabbitMQ (AMQP)Kazoo’s applications talk to each other over AMQP (the README invites developers to “create a Kazoo application in your favorite language” against the AMQP APIs), and Kamailio joins the bus through its kazoo module.335 The cluster guide points each Kazoo node at the RabbitMQ server in each zone (amqp_uri in /etc/kazoo/core/config.ini).37 Kazoo 5 needs the rabbitmq_consistent_hash_exchange plug-in for fax.11
StorageCouchDB 2 (BigCouch on older clusters)All configuration (accounts, callflows, menus, numbers) is JSON documents. The installation guide says CouchDB 2 is required and that “Old abandoned BigCouch can be used too but this is not recommended for new clusters”.11 Each account has its own account database; the callflow code opens menus and rules from the calling account’s database.1623
ApplicationsKazoo apps (Erlang/OTP)The monorepo’s applications/ directory holds, among others, crossbar (REST API), callflow (call logic), ecallmgr, registrar, stepswitch (carrier routing), teletype (email notifications), webhooks, pivot, conference, fax, acdc (call centre) and trunkstore.1
InterfaceMonster UI, comm.landMonster UI is a JavaScript framework with apps such as Smart PBX and Advanced Callflows.42 2600Hz’s docs now label it “MonsterUI - Legacy” and describe comm.land as “the all-in-one frontend platform built atop Kazoo”.46

Scroll the table sideways to see every column.

The cluster guide’s worked example shows what “distributed” means. It assumes two zones, each with three CouchDB servers, one FreeSWITCH, one RabbitMQ, one Kazoo application server and one Kamailio: seven servers per zone. Each zone’s Kazoo nodes are pointed only at their local FreeSWITCH servers.37 CouchDB is told which zone each node belongs to, and the guide warns “make sure you have enough copies in each zone to support a quorum if you lose a zone”.37 One more requirement catches people out. The guide warns that “if you don’t have public DNS for your hostnames, Kazoo will have issues connecting to RabbitMQ”.37

Carrier connectivity is handled by stepswitch, “the carrier management application, most often used for offnet routing”. A carrier is a “resource” document. It can sit in the global offnet database for every tenant, or inside one account as a “local” resource, which 2600Hz calls “BYOC (Bring Your Own Carrier)”.32

Telemetry is on by default

The 4.3 release notes say “KAZOO collects anonymous telemetry data by default”, limited to “aggregate values, aggregate statistics, and software version information”, and that “You can opt-out at any time by consulting the configuration document in the system_config database.”7 If you run Kazoo for clients with data-residency commitments, make that change deliberately and record it.

Accounts, the tree and resellers

“Accounts are the container for most things in 2600Hz. They typically represent an office, business, family, etc.” They form a tree “where parent accounts can access their sub accounts but not their ancestor accounts.”16 An account’s ancestry is kept in a pvt_tree array ordered “from most-ancestral to parent”, and an empty tree marks “the master (or Highlander) account; there should only be one!”16

That gives a natural hosting hierarchy: the master account (the platform operator), reseller accounts below it, and customer accounts below each reseller. The API exposes the tree directly. PUT /v2/accounts/{ACCOUNT_ID} creates a child under the given account, and /children, /descendants, /siblings, /parents and /tree walk it.16

Reseller status is an explicit flag on an account, controlled from the top. Promoting (PUT /v2/accounts/{ACCOUNT_ID}/reseller) and demoting (DELETE) both require a “superduper admin auth token”.16 Authentication responses carry is_reseller and reseller_id, so every client knows which reseller a user sits under.14 Two details matter for anyone planning a reseller business:

  • Moving customers between resellers is off by default. “2600Hz does NOT support moving accounts between reseller accounts”, although a system setting (allow_move) can allow moves by anyone above the account.16
  • Sibling visibility is on by default. “By default a user account under an admin/reseller account can view all the other accounts under that reseller”; set allow_sibling_listing to false to stop it.16 Most resellers will want that off before the second customer arrives.

Each account also gets its own SIP realm (the docs’ example is account1.2600hz.com), time zone, caller ID defaults, call restrictions, music on hold and emergency address. Because callflows are looked up per account, two tenants can both use extension 100 without colliding.1620

The Crossbar REST API

“2600Hz’s REST API server is called Crossbar”. It listens on port 8000 by default, and request paths follow /{VERSION}/accounts/{ACCOUNT_ID}/resources/{RESOURCE_ID}. For {VERSION}, “Currently, the only supported value is v2.”13 Version 1 was deprecated in 4.3, and the 5.0 notes say “All Crossbar API version 1 modules are removed.”7

The conventions are consistent across resources, which is the API’s best feature:13

  • Verbs. On a collection, GET lists and PUT creates (Crossbar uses PUT to create, not POST). On an item, GET fetches, POST replaces the whole document, PATCH merges a partial one and DELETE removes it. Clients limited to GET and POST can tunnel the verb with "verb":"PUT" in the envelope or ?verb=PUT.
  • Envelopes. Request bodies go inside {"data": {...}}. Responses come back with data, metadata, status (success, error or fatal) and a request_id for tracing on the server.
  • Pagination. “All listing APIs will be paginated by default”, using opaque start_key and next_start_key values.
  • Timestamps are Gregorian seconds, not Unix time. Kazoo counts seconds from year 0, so add 62,167,219,200 (719,528 days × 86,400) to a Unix timestamp. The 4.2 notes record the switch: kz_time:now_s/0 “returns Gregorian seconds instead of Unix Epoch seconds”.7

There are two ways to get a token. The first is user credentials. PUT /v2/user_auth takes an MD5 or SHA-1 hash of {username}:{password} plus an account name, realm or phone number, and returns an auth_token.14 The second suits scripts and integrations better. PUT /v2/api_auth takes the account’s API key, which is “intended for use by applications talking to Crossbar” so that you do not store a username and password in the application.15 Every later request sends X-Auth-Token. If a key leaks, PUT /v2/accounts/{ACCOUNT_ID}/api_key rotates it.16

# Scripted access: exchange the account API key for a token
curl -s -X PUT https://kazoo.example.net:8000/v2/api_auth \
  -H 'Content-Type: application/json' \
  -d '{"data":{"api_key":"{API_KEY}"}}'

# Every later call carries the token
curl -s https://kazoo.example.net:8000/v2/accounts/{ACCOUNT_ID}/callflows \
  -H 'X-Auth-Token: {AUTH_TOKEN}'

Our view: hashing username:password with MD5 is a weak credential scheme by modern standards, and the docs’ examples all use plain http:// on port 8000.1314 The API reference has a page on setting up SSL for Crossbar.13 Put Crossbar behind TLS, prefer API keys for automation, and never expose port 8000 to the internet unencrypted.

Callflows and the modules that matter

“Callflows are the instructions 2600Hz uses to process a call.” A callflow document has a list of numbers (exact matches) and patterns (regular expressions with optional capture groups), and a flow. The flow is a tree whose nodes each have a module, a data object and children.17 A call that reaches an account is matched against those numbers and patterns, and the matching flow runs.

Children are keyed by outcome. A menu’s children are keyed by digit, a time-of-day node’s children by rule ID, and the key _ is the default branch taken when nothing else applies. Most modules also accept skip_module, which jumps straight to the _ branch.1822 The current docs list over forty callflow actions.18 An auto attendant needs only five:

ModuleWhat it doesKey data fields
menu“Menus, also known as IVRs allow you to create branches in the callflow based on the caller’s input.” The menu itself (prompt, retries, timeouts) is a separate document managed through /menus.18id of the menu document
temporal_route“Branch the callflow based on the current date and time when compared to the temporal rule(s) associated with the action.”22rules, rule_set, timezone
ring_group“allows calling multiple endpoints with given strategy and timeout”. Strategies are simultaneous (default), single and weighted_random.26endpoints (device, user or group), timeout (default 20 s), strategy
userRings the user’s devices; strategy is simultaneous (default) or single.56id, timeout (default 20 s)
voicemail“Puts the caller into the Voicemail system.” action is compose (leave a message, the default) or check.27id of the voicemail box, max_message_length (default 500 s)

Scroll the table sideways to see every column.

If static JSON is not enough, the pivot module hands the call to your web server. Your server replies with either Callflow JSON or “Pivot TwiML”, and can switch between the two from one request to the next.49 The docs include a page called “Switching from Twilio™”.49 A team that has built on Twilio’s TwiML (see our Twilio phone-menu guide) can move much of that logic across. Verbs and attributes need checking one by one, because Pivot TwiML is 2600Hz’s implementation, not Twilio’s.

Building an auto attendant through the API

Here is the whole thing for a small business: a greeting, a menu with sales (1), support (2) and a message (0), business hours in the business’s own time zone, holidays, and voicemail when closed. Every field below appears in the current 2600Hz schema documentation. Replace the {PLACEHOLDERS} with IDs returned by earlier calls. The phone number is a fictional 555 number.

1. The greeting. Create a media document, then upload the audio to it. Text-to-speech also works, through "media_source":"tts" with a tts.text and tts.voice (the voice list includes female/fr-CA and male/fr-CA). It needs a text-to-speech engine configured on the cluster.29

PUT /v2/accounts/{ACCOUNT_ID}/media
{"data": {"name": "Main greeting", "media_source": "upload", "streamable": true}}

# then upload the audio file to that media document
POST /v2/accounts/{ACCOUNT_ID}/media/{MEDIA_ID}/
Content-Type: audio/mp3
(binary body)

2. Voicemail boxes. A box needs only a name and a mailbox number; the docs’ example also sets a time zone and PIN.28

PUT /v2/accounts/{ACCOUNT_ID}/vmboxes
{"data": {"name": "General messages", "mailbox": "3000",
          "timezone": "America/Toronto", "require_pin": true, "pin": "{PIN}"}}

3. The menu document. This is where Kazoo keeps the behaviour of a menu: “the actual menu callflow has just two options because Menus are managed separately, created and updated by API.”18 The fields that matter are below. retries defaults to 3, and timeout is in milliseconds. The source falls back to 10,000 ms if it is not set.1920

PUT /v2/accounts/{ACCOUNT_ID}/menus
{"data": {
  "name": "Main menu",
  "retries": 3,
  "timeout": 8000,
  "interdigit_timeout": 2000,
  "max_extension_length": 4,
  "hunt": false,
  "media": {"greeting": "{MEDIA_ID}"}
}}
Set hunt explicitly

The menu schema documents hunt, “Determines if the callers can dial internal extensions directly”, with a default of true.19 Crossbar fills schema defaults when it validates a document: the schema library’s default options include use_defaults.21 So a menu created through the API lets callers dial digits that are looked up against all of the account’s callflows (up to max_extension_length, default 4).20 That may be what you want in an office where callers know extensions. If it is not, set "hunt": false, or limit it with a hunt_allow regular expression such as ^2\d{2}$. Treat record_pin with the same care. With allow_record_from_offnet enabled, an outside caller who knows the PIN can re-record your greeting.19

4. The time rules. A temporal rule has a cycle (date, daily, weekly, monthly or yearly). Optional fields are wdays, days, month and ordinal (first to fifth, every or last), and a daily window, time_window_start and time_window_stop, given as “Seconds from the start of a day”.24 Opening hours are 9:00 to 17:00, which is 32400 to 61200 seconds:

PUT /v2/accounts/{ACCOUNT_ID}/temporal_rules
{"data": {"name": "Open weekdays", "cycle": "weekly", "interval": 1,
          "wdays": ["monday","tuesday","wednesday","thursday","friday"],
          "time_window_start": 32400, "time_window_stop": 61200}}

PUT /v2/accounts/{ACCOUNT_ID}/temporal_rules
{"data": {"name": "Canadian Thanksgiving", "cycle": "yearly", "interval": 1,
          "month": 10, "ordinal": "second", "wdays": ["monday"],
          "time_window_start": 0, "time_window_stop": 86400}}

PUT /v2/accounts/{ACCOUNT_ID}/temporal_rules
{"data": {"name": "US Thanksgiving", "cycle": "yearly", "interval": 1,
          "month": 11, "ordinal": "fourth", "wdays": ["thursday"],
          "time_window_start": 0, "time_window_stop": 86400}}

PUT /v2/accounts/{ACCOUNT_ID}/temporal_rules
{"data": {"name": "Christmas Day", "cycle": "yearly", "interval": 1,
          "month": 12, "days": [25],
          "time_window_start": 0, "time_window_stop": 86400}}

Group the holidays into a rule set so that one ID covers them all. That is the purpose the docs give: “one could define each holiday as a temporal rule, then create a temporal rule set with all of the holiday temporal rule IDs added.”25 Holidays that move with Easter, such as Good Friday, cannot be written as a recurrence. Use "cycle":"date", which “only considers start_date and matches it against the current day”, and add one rule per year.24 A yearly rule that does not apply one year can carry an exclude list of dates instead of being split in two.24

PUT /v2/accounts/{ACCOUNT_ID}/temporal_rules_sets
{"data": {"name": "Holidays",
          "temporal_rules": ["{THANKSGIVING_RULE_ID}", "{CHRISTMAS_RULE_ID}"]}}

5. The callflow. This ties it together. The outer temporal_route checks the holiday set (a match takes the rule_set branch, anything else takes _), as the docs describe.22 The inner one checks opening hours, and its branch is keyed by the rule’s ID. In the source, the ID of the first rule whose window contains the current time becomes the child key the call follows.23

PUT /v2/accounts/{ACCOUNT_ID}/callflows
{"data": {
  "name": "Main line",
  "numbers": ["+16135550142"],
  "flow": {
    "module": "temporal_route",
    "data": {"rule_set": "{HOLIDAY_SET_ID}", "timezone": "America/Toronto"},
    "children": {
      "rule_set": {"module": "voicemail", "data": {"id": "{CLOSED_VMBOX_ID}"}, "children": {}},
      "_": {
        "module": "temporal_route",
        "data": {"rules": ["{OPEN_RULE_ID}"], "timezone": "America/Toronto"},
        "children": {
          "{OPEN_RULE_ID}": {
            "module": "menu",
            "data": {"id": "{MENU_ID}"},
            "children": {
              "1": {"module": "ring_group",
                    "data": {"strategy": "simultaneous", "timeout": 25,
                             "endpoints": [{"endpoint_type": "user", "id": "{SALES_USER_1}"},
                                           {"endpoint_type": "user", "id": "{SALES_USER_2}"}]},
                    "children": {"_": {"module": "voicemail", "data": {"id": "{SALES_VMBOX_ID}"}, "children": {}}}},
              "2": {"module": "user", "data": {"id": "{SUPPORT_USER}", "timeout": 25},
                    "children": {"_": {"module": "voicemail", "data": {"id": "{SUPPORT_VMBOX_ID}"}, "children": {}}}},
              "0": {"module": "voicemail", "data": {"id": "{GENERAL_VMBOX_ID}"}, "children": {}},
              "_": {"module": "voicemail", "data": {"id": "{GENERAL_VMBOX_ID}"}, "children": {}}
            }
          },
          "_": {"module": "voicemail", "data": {"id": "{CLOSED_VMBOX_ID}"}, "children": {}}
        }
      }
    }
  }
}}

Why nest two temporal_route nodes instead of listing every rule in one? The source builds a node’s rule list in a fixed order: the IDs in data.rules, then the child keys, then the members of data.rule_set. It returns the first rule that matches.23 With everything in one node, the holiday set is checked after “Open weekdays”, so a holiday that falls on a Monday matches as open. Nesting makes the order explicit, and it does not depend on JSON key order, which no JSON parser promises to preserve.

The menu’s _ child is not just decoration. When retries run out, the source plays the exit prompt, tries a max_retries branch if one exists, and otherwise continues down _; if there is no _ branch, the caller hears “goodbye”.20 If no timeout child exists, “the menu is retried (until retries are exceeded)”.18 A menu without _ hangs up on the people who most need a human: the ones who did not understand it. Our call flow templates cover the menu design itself.

6. Test the hours before you go live. Fetch a rule with ?timestamp= (Gregorian seconds, in the account’s time zone) and the response carries metadata.rule_matches.24 Check a weekday at 08:59 and 09:00, a Saturday, and each holiday. Nobody tests holidays until the first one, when every caller hears the open-hours menu and nobody picks up.

GET /v2/accounts/{ACCOUNT_ID}/temporal_rules/{OPEN_RULE_ID}?timestamp={GREGORIAN_SECONDS}
# response metadata: {"rule_matches": true | false, ...}

One schema oddity you may trip over: the wdays enumeration accepts both wednesday and the misspelling wensday.24 It is a backward-compatibility artefact, not a typo in your client. Write wednesday.

Number management

Numbers are their own resource under /v2/accounts/{ACCOUNT_ID}/phone_numbers. Two rules in the docs prevent most mistakes. First, “{PHONE_NUMBER} has to be URL-encoded”, so +14155555555 becomes %2B14155555555. Second, normalisation is literal: “4123456789 is turned into +14123456789”, but “41234567 is turned into +41234567, so be careful!”30 Only an account whose document has pvt_wnm_allow_additions set to true, or a request made with master-account authentication, can add or modify numbers.30

The lifecycle is search, then activate. GET /v2/phone_numbers?prefix=613&quantity=5 searches carrier inventory, and PUT .../phone_numbers/{NUMBER}/activate buys a number, which “must have appeared as part of the results of a numbers search”.30 Numbers have states (available, reserved, in_service, port_in, port_out, aging, released, deleted, discovery). A number can carry CNAM settings, a structured e911 address and the porting details the losing carrier has on file.30 Which carriers you can search depends on the number-manager modules your cluster runs. The master branch ships modules for Bandwidth, Flowroute, Inteliquent, Telnyx, Thinq, VoIP Innovations, Voxbone, Simwood and others, plus local, managed and other for numbers you bring yourself.31 Some features also depend on “Phonebook”, which the docs describe as “an external service that ‘abstract’ carrier number inventory” that “the sysadmin need to provide and configure”.30

Assigning a number to an account does not route it. A call reaches the auto attendant only when the number appears in a callflow’s numbers, as in step 5.17 Porting has its own port_requests API.12 The rules behind it (what a carrier may require and how long it may take) are covered in our porting guide.

Notes for Canadian deployments

  • French prompts exist. The kazoo-sounds repository has a Canadian French set (kazoo-core/fr/ca) alongside the French one.50 The install guide shows importing it as fr-ca.36 The account’s language setting and the language callflow action decide which set callers hear,1618 and a bilingual menu is simply a menu whose digit branches lead to language-specific sub-flows.
  • Time zones are IANA names (America/Toronto, America/Vancouver, America/Halifax), set per account, per voicemail box or on the temporal_route node.162822
  • Emergency addresses are stored per number in the e911 object, with a two-letter region that fits provinces as well as states.30 Whether they reach a 911 database depends on your carrier. Canada’s 911 obligations differ from the US ones; see emergency calling.

The state of the open-source project

This is where most write-ups of Kazoo are out of date, including some of 2600Hz’s own.

Licence. The LICENSE file in the kazoo repository is the “Mozilla Public License Version 2.0”, and GitHub identifies it as MPL-2.0.12 The README still says Kazoo is “Released under the OSI-approved MPL 1.1 open source software license”.3 The LICENSE file is the operative text. The 5.x application repositories are also MPL-2.0.9 Monster UI’s LICENSE file is the Mozilla Public License version 1.1.47 Our reading of the MPL 2.0: it is file-level copyleft, so you can combine Kazoo with proprietary code, but changes to MPL-licensed files must be shared when you distribute them. Read the licence text yourself before relying on that summary.2

Releases. The latest release on the kazoo repository is 4.3.142, published 19 January 2022, and the previous one, 4.3.141, came out in October 2021.4 The most recent commit on master is a documentation fix dated 12 March 2024.5 The 4.3 branch was last changed on 15 May 2024 (a fax fix).6 The repository has 990 stars, 466 forks and about 185 contributors counted by GitHub. Issues are turned off on GitHub, and 2600Hz tracks bugs in its own ticket system.13

Kazoo 5. The announcements file is blunt: “KAZOO master (5.x) is closed at the moment”, and development “is currently closed to public commits as we prepare the infrastructure necessary for the app exchange”. That exchange would be “a release channel from which folks can purchase those apps for use on any KAZOO cluster.”7 The code did not disappear, though. A public kazoo5 repository (described as “Kazoo 5.x - For your eyes only”) assembles separate per-application repositories, and its latest commit is from August 2026.8 Those repositories are active. kazoo-crossbar has 2026 commits tagged 5.4.x, such as “KCRO-277: tighten up cb_simple_authz checks”.10 kazoo-callflow was last changed in April 2026.9 We found no tagged 5.x releases in them.910 2600Hz’s own guide to this multi-repo layout is still a stub that reads “Write something useful here”.53

Community apps. The 5.0 notes moved “Community-supported and deprecated apps” to a separate kazoo-community organisation.7 That organisation’s most recently updated repository was last changed in September 2024.52

Commercial offerings. 2600Hz sells the platform as white-label UCaaS, CPaaS and contact centre for service providers. Its website pitches migrations from BroadWorks and Metaswitch.43 There are two deployment models. Hosted Platform runs on “2600Hz’s Triple Geo-Redundant Cloud” and is aimed at service providers who want to launch “with minimal upfront costs”.44 Global Infrastructure puts the clustered architecture “inside your own data center”: clients “partner directly with the 2600Hz engineering team on their custom cluster design” and get a Cluster Manager tool.45 Both pages advertise “99.999% reliability”; that is 2600Hz’s claim, not something we measured.4445 We found no published price list; 2600hz.com/pricing/ returns the site’s not-found page.43 comm.land, the new front end, is documented on docs.2600hz.com.46 We found no public repository for it among the organisation’s public repositories, and the Monster UI accounts app repository is archived.48

Put plainly: the code is open and still moving, but the open-source product, meaning a public release you can install from packages and follow upgrade notes for, stopped at 4.3 in early 2022. New work ships through 2600Hz’s commercial channels.

Installation options, and how stale the guides are

There are four ways to get a running Kazoo, and each comes with caveats:

  1. The all-in-one RPM install on CentOS 7. 2600hz.org’s install instructions point here.42 The guide installs 2600Hz’s wrapped packages (kazoo-rabbitmq, kazoo-kamailio, kazoo-freeswitch, kazoo-bigcouch, kazoo-applications), creates the master account with sup crossbar_maintenance create_account and imports the prompts.36 It is explicitly “for testing purposes”, and it says itself that changes “can cause this guide to bitrot”.36 The public package index for this route stops at kazoo-applications-4.3 for CentOS 7.38
  2. Build from source. The installation guide covers Erlang, CouchDB, RabbitMQ, FreeSWITCH with mod_kazoo and Kamailio with the kazoo module, then make, make build-release and the sup command-line tool.11
  3. Docker. 2600Hz’s docker repository is a development environment. It is based on Debian Jessie, “provides all Kazoo components alongside with source code”, and was last updated in 2019. It points to third-party images for production use.51
  4. Buy it. Hosted Platform, or Global Infrastructure with 2600Hz engineers designing the cluster.4445

The package index does show newer work. 2600Hz publishes Rocky Linux 8 and 9 channels. The Rocky 9 stable channel carries 2600Hz-built FreeSWITCH, Kamailio 5.7, freeswitch-kazoo and kamailio-kazoo, but we found no Kazoo application packages in it.39 The FreeSWITCH configuration repository’s CI now builds only for Rocky Linux 9; a change in August 2026 removed CentOS 7 and EL8.40

Here is how the public instructions compare with the current state, document by document:

TopicWhat the public guide saysWhat is current
Operating systemCentOS 7 Minimal ISO.36CentOS Linux 7 reached end of life on 30 June 2024, with no updates after that date.41
“Stable” version“Currently, 4.3 is considered ‘stable’”.36The docs home page calls its API reference “2600Hz 5.X stable” and the 4.3 material “legacy content”.12
Database“BigCouch is still ‘recommended’”; the sample output shows CouchDB 1.1.1 and BigCouch 0.4.2.36The installation guide requires CouchDB 2 and calls BigCouch “Old abandoned”.11
FreeSWITCHSample output shows FreeSWITCH 1.6.20.36FreeSWITCH 1.10+ is required.11
RabbitMQInstalls “an older (perfectly fine) version 3.3.5”.36No current version is stated; the Rocky 9 channel mirrors RabbitMQ and its Erlang.39
Erlang/OTP4.3 “requires Erlang version 19 specifically 19.3.x”; the monorepo guide says 5.x targets 22.3.11The kazoo5 repository pins Erlang 26.2.5,8 while its own copy of the installation guide says 23.0.3.55
Doc linksThe README links to docs.2600hz.com/dev/, a freenode IRC channel and Travis CI badges.3The documentation moved to a new structure on docs.2600hz.com; the 4.3 HTTP API reference is kept as “Legacy”.12

Scroll the table sideways to see every column.

The new docs site is accurate about the API: where we compared schemas, endpoints and examples with the source, they matched. It is weakest on operations, which is exactly where a first-time operator needs it most.

When Kazoo is the right choice, and when it is not

What follows is our view. It rests on the documentation and repository evidence above and on the shape of the architecture, not on running a production cluster for this article.

Kazoo is a strong fit when

  • You are building a phone service, not buying a phone system. The account tree, reseller flag, per-tenant databases and per-account realms are the hard parts of hosted PBX, and they are already designed in.16 Very few open-source projects take multi-tenancy this seriously.
  • Your product is the API. Crossbar is uniform: one envelope, consistent verbs, JSON schemas for every document.13 Provisioning, white-label portals and integrations sit on top of it cleanly.
  • You have, or will pay for, the operations skills. That means someone comfortable with Erlang releases, CouchDB quorum and replication, RabbitMQ, Kamailio and FreeSWITCH all at once, or a commercial contract with 2600Hz.3745
  • You want an exit door. Running 2600Hz’s commercial platform on MPL-licensed code you can read, audit and in principle self-host is a better position than a fully closed UCaaS platform.2

Look elsewhere when

  • You need one auto attendant for one business. Seven servers per zone in the reference cluster, and four separate infrastructure projects (Kamailio, FreeSWITCH, CouchDB, RabbitMQ) under Kazoo’s own Erlang applications, is a lot of machinery for a three-option menu.3711 A single Asterisk server, a programmable API such as Twilio, or a hosted service is the proportionate choice. (Auto Attendant is one such hosted service.)
  • You want a current, packaged, community-supported open release. The last public release is from January 2022 and the documented install targets an end-of-life operating system.43641 Running 4.3 in production in 2026 means owning its security yourself.
  • You need a large community. For a project this size, about 990 stars and roughly 185 contributors since 2011 is a small community. Issues are off on GitHub, and the community-apps organisation went quiet in 2024.152 When something breaks at 2 a.m. you will be reading Erlang source, as we did for this guide.
  • You want multi-tenancy without the Erlang layer. FusionPBX describes itself as “A full-featured domain based multi-tenant PBX and voice switch for FreeSwitch”.54 It is a smaller system with different trade-offs, worth comparing before you commit to Kazoo.

The fair summary: the design is excellent, the API is among the best in open-source telephony, and the code is still being worked on. But the open project now trails the commercial one. If you are not prepared either to run it like a carrier or to pay 2600Hz to, it is not the right tool.

Further reading

Longer research pieces on this topic, each with its own source list and a downloadable PDF.

Sources

Every regulatory and pricing claim on this page links to the primary source it came from. Figures were checked on the date shown at the top of the page; rules and prices change, so verify before relying on one.

  1. GitHub, 2600hz/kazoo repository: description, creation date (12 Dec 2011), licence detection (MPL-2.0), stars, forks, contributors, issues disabled, applications/ directory. Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo
  2. 2600hz/kazoo, LICENSE file (Mozilla Public License Version 2.0). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/LICENSE
  3. 2600hz/kazoo, README.md (what Kazoo is, “MPL 1.1” statement, foundations, ticket system, doc and IRC links). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/README.md
  4. 2600hz/kazoo, Releases (latest 4.3.142, 19 Jan 2022; 4.3.141, 27 Oct 2021). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/releases
  5. 2600hz/kazoo, commit history of master (latest commit 12 Mar 2024). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/commits/master
  6. 2600hz/kazoo, commit history of the 4.3 branch (latest commit 15 May 2024). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/commits/4.3
  7. 2600hz/kazoo, doc/announcements.md (5.x closed to public commits, app exchange, v1 API removal, kazoo-community, 4.3 telemetry, 4.2 Gregorian seconds). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/doc/announcements.md
  8. GitHub, 2600hz/kazoo5 repository (description, latest commit Aug 2026, .tool-versions pinning Erlang 26.2.5). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo5
  9. GitHub, 2600hz/kazoo-callflow commit history (MPL-2.0; 5.4.x commits; no tags). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo-callflow/commits/master
  10. GitHub, 2600hz/kazoo-crossbar commit history (2026 commits tagged 5.4.x; no tags). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo-crossbar/commits/master
  11. 2600hz/kazoo, doc/installation.md (dependencies, Erlang versions, CouchDB 2, FreeSWITCH 1.10+ with mod_kazoo, Kamailio 5.2+ with kazoo module, build targets). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/doc/installation.md
  12. 2600Hz Docs, home page and navigation (5.X stable API reference, 4.3 legacy content, callflow actions, port requests). Retrieved 26 Oct 2026
    https://docs.2600hz.com/
  13. 2600Hz Docs, REST API Reference: API Basics (Crossbar, port 8000, v2, envelopes, verbs, pagination). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/overview/api-basics
  14. 2600Hz Docs, User Authentication (PUT /v2/user_auth, MD5/SHA-1 credentials hash). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/authentication/user-authentication
  15. 2600Hz Docs, Account API Authentication (PUT /v2/api_auth). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/authentication/account-api-authentication
  16. 2600Hz Docs, Accounts (tree, pvt_tree, schema, child accounts, API key, siblings, reseller promotion, move). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/account-actions-and-permissions/accounts
  17. 2600Hz Docs, Callflows API (numbers, patterns, flow, module/data/children). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/call-control/callflows/callflows
  18. 2600Hz Docs, Callflow action: Menu (IVR), children keys, timeout behaviour. Retrieved 26 Oct 2026
    https://docs.2600hz.com/call-control/callflow/callflow-actions/ivr
  19. 2600Hz Docs, Menus API (schema: hunt, retries, timeout, media, record_pin). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/call-control/menus/menus
  20. 2600hz/kazoo, applications/callflow/src/module/cf_menu.erl (defaults, hunt lookup, max_retries and wildcard handling). master, retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/callflow/src/module/cf_menu.erl
  21. 2600hz/kazoo, core/kazoo_schemas/src/kz_json_schema.erl (default validator options include use_defaults). master, retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/core/kazoo_schemas/src/kz_json_schema.erl
  22. 2600Hz Docs, Callflow action: Temporal Route (schema, rule sets, catch-all). Retrieved 26 Oct 2026
    https://docs.2600hz.com/call-control/callflow/callflow-actions/temporal-route
  23. 2600hz/kazoo, applications/callflow/src/module/cf_temporal_route.erl (rule loading order, first match becomes the branch key). master, retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/callflow/src/module/cf_temporal_route.erl
  24. 2600Hz Docs, Temporal Rules API (schema, exclude, date cycle, timestamp evaluation). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/call-control/advanced-features/temporal-rules
  25. 2600Hz Docs, Temporal Rules Sets API. Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/call-control/advanced-features/temporal-rules-sets
  26. 2600hz/kazoo, applications/callflow/doc/ring_group.md (schema and strategies). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/callflow/doc/ring_group.md
  27. 2600hz/kazoo, applications/callflow/doc/voicemail.md (voicemail callflow action schema). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/callflow/doc/voicemail.md
  28. 2600hz/kazoo, applications/crossbar/doc/voicemail.md (vmboxes API, required fields). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/crossbar/doc/voicemail.md
  29. 2600hz/kazoo, applications/crossbar/doc/media.md (media documents, binary upload, TTS voices). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/crossbar/doc/media.md
  30. 2600Hz Docs, Phone Numbers API (encoding, normalisation, states, search, activate, e911, porting, Phonebook). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/rest/usage/phone-numbers-api
  31. 2600hz/kazoo, core/kazoo_numbers/src/carriers (number-manager carrier modules). master, retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/tree/master/core/kazoo_numbers/src/carriers
  32. 2600hz/kazoo, applications/stepswitch/doc/README.md (carrier resources, BYOC). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/stepswitch/doc/README.md
  33. 2600hz/kazoo, applications/ecallmgr/doc/README.md. Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/ecallmgr/doc/README.md
  34. 2600hz/kazoo, applications/registrar/doc/README.md. Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/registrar/doc/README.md
  35. Kamailio, KAZOO module README (general purpose AMQP connector). master, retrieved 26 Oct 2026
    https://github.com/kamailio/kamailio/blob/master/src/modules/kazoo/README
  36. 2600Hz Docs, Installation Guide for CentOS 7 (all-in-one install, package names, sample outputs, “4.3 is considered stable”, BigCouch note). Retrieved 26 Oct 2026
    https://docs.2600hz.com/sysadmin/ref/getting-started/installation/via-cent-os-7/
  37. 2600Hz Docs, Cluster operation guide (two-zone, seven-server-per-zone example; DNS and quorum warnings; amqp_uri). Retrieved 26 Oct 2026
    https://docs.2600hz.com/sysadmin/ref/cluster-operation/guide
  38. 2600Hz package index, CentOS 7 stable kazoo-applications 4.3 directory. Retrieved 26 Oct 2026
    https://packages.2600hz.com/centos/7/stable/kazoo-applications/4.3/
  39. 2600Hz package index, Rocky Linux 9 stable channel (FreeSWITCH, Kamailio 5.7, freeswitch-kazoo, kamailio-kazoo, RabbitMQ mirrors). Retrieved 26 Oct 2026
    https://packages.2600hz.com/rockylinux/9/stable/
  40. GitHub, 2600hz/kazoo-configs-freeswitch (loads mod_kazoo; CI builds Rocky Linux 9; Aug 2026 commit removing CentOS 7 and EL8). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo-configs-freeswitch
  41. CentOS Project blog, “End dates are coming for CentOS Stream 8 and CentOS Linux 7” (CentOS Linux 7 EOL 30 June 2024). April 2023, retrieved 26 Oct 2026
    https://blog.centos.org/2023/04/end-dates-are-coming-for-centos-stream-8-and-centos-linux-7/
  42. 2600hz.org, community site (projects, Monster UI apps, Get Started links). Retrieved 26 Oct 2026 via a scraping service (the site blocks plain HTTP clients)
    https://2600hz.org/
  43. 2600Hz, home page (UCaaS, CPaaS, contact centre; deployment models; migration pitch). /pricing/ returned a not-found page. Retrieved 26 Oct 2026
    https://www.2600hz.com/
  44. 2600Hz, Hosted Platform. Retrieved 26 Oct 2026
    https://www.2600hz.com/hosted-platform/
  45. 2600Hz, Global Infrastructure. Retrieved 26 Oct 2026
    https://www.2600hz.com/global-infrastructure/
  46. 2600Hz Docs, Frontend Frameworks: comm.land and MonsterUI (Legacy). Retrieved 26 Oct 2026
    https://docs.2600hz.com/frontends/commland
  47. GitHub, 2600hz/monster-ui (LICENSE: Mozilla Public License 1.1). Retrieved 26 Oct 2026
    https://github.com/2600hz/monster-ui
  48. GitHub, 2600hz organisation repository list (153 public repositories; monster-ui-accounts archived; no comm.land repository found). Retrieved 26 Oct 2026
    https://github.com/2600hz
  49. 2600Hz Docs, Pivot: Programmable flows (Callflow JSON and Pivot TwiML; “Switching from Twilio™”). Retrieved 26 Oct 2026
    https://docs.2600hz.com/developers/pivot/pivot-programmable-flows
  50. GitHub, 2600hz/kazoo-sounds, kazoo-core/fr (French and Canadian French prompt sets). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo-sounds/tree/master/kazoo-core/fr
  51. GitHub, 2600hz/docker README (development environment, Debian Jessie; last push 2019). Retrieved 26 Oct 2026
    https://github.com/2600hz/docker
  52. GitHub, kazoo-community organisation (community apps; most recent push Sep 2024). Retrieved 26 Oct 2026
    https://github.com/kazoo-community
  53. 2600hz/kazoo5, doc/getting_used_to_multi_repo.md (stub sections). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo5/blob/master/doc/getting_used_to_multi_repo.md
  54. GitHub, fusionpbx/fusionpbx repository description. Retrieved 26 Oct 2026
    https://github.com/fusionpbx/fusionpbx
  55. 2600hz/kazoo5, doc/installation.md (states Kazoo 5.x targets Erlang 23.0.3). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo5/blob/master/doc/installation.md
  56. 2600hz/kazoo, applications/callflow/doc/user.md (user callflow action schema). Retrieved 26 Oct 2026
    https://github.com/2600hz/kazoo/blob/master/applications/callflow/doc/user.md