Teams Phone Licensing Calculator
Every license line, nothing hidden. Pick how calls reach the phone network, enter users and shared phones, and see the monthly total. Microsoft charges and carrier charges are kept apart so you can compare like with like.
Choosing how calls connect
Microsoft Calling Plan
Microsoft is your phone company. Numbers and minutes come with the license, bundled with Teams Phone. Simplest to run; usually the best fit under about 100 users.
Operator Connect
A Microsoft-certified carrier provides numbers and minutes, connected inside the Teams admin center. You buy Teams Phone Standard from us and calling from the carrier, often cheaper at volume or with better international rates.
Direct Routing
Your own session border controller connects Teams to any carrier or an existing phone system. The most flexible option, and the most to maintain.
Auto attendants and call queues
Each one needs a resource account with the free Teams Phone Resource Account license, plus a phone number if callers dial it directly.
window.C2N = (function () { function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); } function fire(el) { el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } function enhance(form) { [].forEach.call(form.querySelectorAll('select[data-seg]'), function (sel) { var seg = document.createElement('div'); seg.className = 'c2n-seg'; seg.setAttribute('role', 'radiogroup'); seg.style.gridTemplateColumns = 'repeat(' + Math.min(sel.options.length, +sel.dataset.seg || sel.options.length) + ',1fr)'; [].forEach.call(sel.options, function (o) { var b = document.createElement('button'); b.type = 'button'; b.textContent = o.textContent; b.dataset.v = o.value; b.setAttribute('role', 'radio'); b.addEventListener('click', function () { sel.value = o.value; sync(form); fire(sel); }); seg.appendChild(b); }); sel.hidden = true; sel.parentNode.insertBefore(seg, sel.nextSibling); }); [].forEach.call(form.querySelectorAll('input[data-range]'), function (num) { var r = num.dataset.range.split(','), rg = document.createElement('input'); rg.type = 'range'; rg.min = r[0]; rg.max = r[1]; rg.step = r[2] || 1; rg.className = 'c2n-range'; rg.setAttribute('aria-label', num.name); rg.addEventListener('input', function (e) { e.stopPropagation(); num.value = rg.value; fire(num); }); num.parentNode.appendChild(rg); }); } function sync(form) { [].forEach.call(form.querySelectorAll('select[data-seg]'), function (sel) { [].forEach.call(sel.nextSibling.children, function (b) { var on = b.dataset.v === sel.value; b.classList.toggle('on', on); b.setAttribute('aria-checked', on); }); }); [].forEach.call(form.querySelectorAll('input[data-range]'), function (num) { num.parentNode.querySelector('.c2n-range').value = num.value; }); } function render(el, r) { var h = '<div class="c2n-cx-bar"><span>Results · ' + esc(r.title) + (r.unit === undefined ? ' · USD' : r.unit) + '</span><span class="c2n-cx-live">Live</span></div>'; if (r.lead) h += '<p class="c2n-cx-lead">' + r.lead + '</p>'; if (r.kpis) h += '<div class="c2n-cx-kpis">' + r.kpis.map(function (k, i) { return '<div class="c2n-cx-kpi' + (i ? '' : ' on') + '"><small>' + esc(k[0]) + '</small><b>' + k[1] + '</b><span>' + (k[2] || '') + '</span></div>'; }).join('') + '</div>'; if (r.rows) { var cell = function (tag) { return function (c, i) { return '<' + tag + (i ? ' class="n"' : '') + '>' + c + '</' + tag + '>'; }; }; h += '<div class="c2n-cx-scroll"><table class="c2n-cx-table">' + (r.head ? '<tr>' + r.head.map(cell('th')).join('') + '</tr>' : '') + r.rows.map(function (row) { return '<tr>' + row.map(cell('td')).join('') + '</tr>'; }).join('') + (r.total ? '<tr class="t">' + r.total.map(cell('td')).join('') + '</tr>' : '') + '</table></div>'; } h += '<div class="c2n-cx-foot"><p>' + (r.note || '') + '</p>' + (r.cta ? '<a class="c2n-cx-btn" href="' + esc(r.cta[1]) + '">' + esc(r.cta[0]) + '</a>' : '') + '</div>'; el.innerHTML = h; } function money(n, d) { return (n < 0 ? '-$' : '$') + Math.abs(n).toLocaleString('en-US', { minimumFractionDigits: d || 0, maximumFractionDigits: d || 0 }); } function values(form) { var v = {}; [].forEach.call(form.elements, function (el) { if (el.name) v[el.name] = el.type === 'number' ? Math.max(0, +el.value || 0) : el.value; }); return v; } function restore(form) { var q = new URLSearchParams(location.search); [].forEach.call(form.elements, function (el) { if (el.name) { if (q.has(el.name)) el.value = q.get(el.name); } }); } function save(form) { var o = {}; [].forEach.call(form.elements, function (el) { if (el.name) o[el.name] = el.value; }); history.replaceState(null, '', '?' + new URLSearchParams(o)); } function mount(form, calc) { enhance(form); restore(form); var run = function () { sync(form); calc(values(form)); save(form); }; form.addEventListener('input', run); form.addEventListener('submit', function (e) { e.preventDefault(); }); run(); } return { mount: mount, render: render, money: money, esc: esc, sync: sync, enhance: enhance }; })(); (function () { var P = {"Teams Phone with Calling Plan (country zone 1 - US)":{"c":[204,17.85,20.4]},"Teams Phone with Calling Plan (country zone 1 - US) (Non-Profit Pricing)":{"n":[152.4,13.34,15.24]},"Teams Phone with domestic and international calling":{"c":[408,35.7,40.8]},"Teams Phone with pay-as-you-go calling (country zone 1 - US)":{"c":[156,13.65,15.6]},"Microsoft Teams Phone Standard":{"c":[120,10.5,12]},"Microsoft Teams Phone Standard (Non-Profit Pricing)":{"n":[48,4.2,4.8]},"Microsoft Teams Domestic Calling Plan":{"c":[144,12.6,14.4]},"Microsoft Teams Domestic and International Calling Plan":{"c":[288,25.2,28.8]},"Microsoft Teams Shared Space":{"c":[96,8.4,9.6]},"Microsoft Teams Shared Space (Non-Profit Pricing)":{"n":[38.4,3.36,3.84]},"Microsoft Teams Premium":{"c":[120,10.5,12,["P3Y","Annual",120],["P3Y","Triennial",360]]},"Microsoft Teams Premium (Non-Profit Pricing)":{"n":[48,4.2,4.8,["P3Y","Annual",48],["P3Y","Triennial",144]]}}; var $ = C2N.money; function mo(name, seg) { var np = P[name + ' (Non-Profit Pricing)'], r = seg === 'n' ? (np ? np.n : null) || P[name].c : P[name].c; return r ? r[0] / 12 : 0; } C2N.mount(document.getElementById('tp'), function (x) { var e5 = Math.min(x.e5, x.users), plain = x.users - e5, rows = [], ms = 0, carrier = 0; function add(label, n, each) { if (!n) return; rows.push([n + ' x ' + label, $(each, 2), $(n * each, 2)]); ms += n * each; } if (x.pstn === 'cp') { add('Teams Phone with Calling Plan (US)', plain, mo('Teams Phone with Calling Plan (country zone 1 - US)', x.seg)); add('Domestic Calling Plan (E5 users)', e5, mo('Microsoft Teams Domestic Calling Plan', 'c')); } else if (x.pstn === 'cpi') { add('Teams Phone, domestic + international', plain, mo('Teams Phone with domestic and international calling', 'c')); add('Domestic + Intl Calling Plan (E5 users)', e5, mo('Microsoft Teams Domestic and International Calling Plan', 'c')); } else if (x.pstn === 'payg') { add('Teams Phone with pay-as-you-go (US)', plain, mo('Teams Phone with pay-as-you-go calling (country zone 1 - US)', 'c')); } else { add('Teams Phone Standard', plain, mo('Microsoft Teams Phone Standard', x.seg)); carrier = x.users * x.carrier; } add('Teams Shared Space', x.shared, mo('Microsoft Teams Shared Space', x.seg)); if (x.aa) rows.push([x.aa + ' x Resource account', '$0.00', '$0.00']); add('Teams Premium', x.prem, mo('Microsoft Teams Premium', x.seg)); if (carrier) rows.push(['Carrier service (your estimate)', $(x.carrier, 2), $(carrier, 2)]); var all = ms + carrier; C2N.render(document.getElementById('tp-out'), { title: 'Teams Phone', lead: 'About <strong>' + $(x.users ? all / x.users : 0, 2) + ' per user per month</strong> all in' + (carrier ? ', of which ' + $(carrier, 2) + ' goes to your carrier.' : ', all billed by Microsoft.') + (x.pstn === 'payg' ? ' Pay-as-you-go minutes are billed on top from Communications Credits.' : ''), kpis: [['Monthly total', $(all, 2), 'Microsoft ' + $(ms, 2) + (carrier ? ' + carrier ' + $(carrier, 2) : '')], ['Per year', $(all * 12), 'annual commitment']], head: ['License', 'Each / mo', 'Monthly'], rows: rows.length ? rows : [['Nothing selected', '', '']], total: ['Total per month', '', $(all, 2)], note: 'Microsoft US list price, annual commitment, monthly equivalent. Taxes, regulatory fees and number porting not included.', cta: ['Start Teams Phone setup', '/tools/forms/?f=teams-phone'] }); }); })();