What you see that they do not
Your view carries each tenant’s balance and your margin on their traffic. Margin is an operator figure by design — a tenant sees what they are charged, never what it cost you underneath.Billing mode
Prepaid
Calls stop when the balance runs out. A credit check runs before the call is
placed, not after it.
Postpaid
Calls continue and are billed in arrears.
A tenant using their own carrier can still place calls at zero balance.
Those calls cost you nothing, so refusing them would be charging somebody for
the privilege of using their own account.
Creating one
A new organisation needs a name and a SIP domain. The domain is how an agent’s sign-in resolves which tenant they belong to, so it has to be right before anybody registers a handset. Give each tenant its own, e.g.abc.firet.one. Every extension in it is
then addressed as 911001@abc.firet.one. It is a realm and not a host —
nothing resolves it and nothing connects to it, so it needs no DNS record and
no certificate: handsets present it as their domain and still connect to the
node by address.
The panel refuses a value no handset could present: uppercase, a port, a URI, a
bare label, an address.
Handles
With a base domain set (Settings → Email → Brand), an organisation can have a handle: one word that is its name in every address.
Type a handle in New organisation and the SIP domain fills itself in; the
form says straight away whether the handle is free. A handle is 3 to 32
lower-case letters, digits and hyphens. Names the platform may need (
www,
api, admin, mail, sip and similar) are kept back.
Organisations made before handles keep their SIP domain; give them a handle
whenever you like.
What the server needs
The panel address needs two things this installer does not make:- A wildcard DNS record:
*.firet.onepointing at the server. - A certificate that covers
*.firet.one. In Virtualmin, add*.firet.oneas a server alias of the FireTone site and issue a certificate that includes it. Let’s Encrypt issues a wildcard only through a DNS challenge.
sudo deploy/staging/verify.sh checks both under Organisation addresses.
The SIP domain needs neither: phones present it as their realm and still connect
to the node by address.
Sign-up
Organisations can sign themselves up once you turn on Organisations can sign up (Settings → Email → Brand). That needs a base domain and email that has passed a test, because every step depends on email arriving.- They fill in the form at
https://<base domain>/signup: organisation name, handle, email, password and country. The handle is checked as they type, and they see the address it gives them. - They get an email with a link that works for 24 hours. Until they open it, nothing exists except the request, although the handle is held for them.
- The link creates the organisation as waiting for approval: prepaid, zero balance, in their country, with their handle as its SIP domain, and them as its administrator. Your operator admins get an email.
- Organisations shows it under Waiting for approval:
- Approve makes it active and emails them where to sign in.
- Turn down emails them the reason you give, then removes it, which frees the handle.
Country and outside-line prefix
Country decides what a number an agent dials without a+ means:
09216217231 is +919216217231 from India and +619216217231 from Australia.
It restricts nothing. An organisation may operate in several countries and
hold numbers and carriers in any of them — nothing checks a number against
it. Where agents sit in more than one country, an extension can override it.
Outbound caller ID
The number carriers are shown when the calling extension has no real number of its own — usually the organisation’s main line. Without it (and without a default on the trunk), a call from extension1001 presents 1001, and most
carriers refuse it. International with a +, or national in the organisation’s
country; it is stored in E.164. See caller ID
for the full order.
Numbers are stored with their +
A number added to an organisation is read the same way:0412 345 678 in the
organisation’s country, or international with a + or 00, and always stored
as +61412345678. Anything that is not a real number is refused when it is
added rather than saved and never matched — ftctl doctor reports any older
number stored without its + (did-not-e164), and any number that routes to an
extension, queue, flow or process that no longer exists
(did-dangling-destination).
Recording
Record calls here records every call in the tenant. Recording is on if any level says so — organisation, team, extension, queue, trunk or process — so a level below can add recording but cannot switch off what you set here.When a call was not recorded
Open the call and look at Journey. Every call now carries onerecording
step saying what was decided and why:
After the call, a second step says whether the file actually appeared. It can
say
missing: the recording was started and the switch could not write the
file, almost always because it does not have write access to the recordings
directory. The daemon’s log carries the exact setfacl command that fixes it,
and verify.sh on that node checks the same thing before another call is lost.
A call in that state shows “taken, but the file is not on this node” instead of
a player — the call record deliberately keeps the path, because that it was
recorded at all is worth knowing.
Recording storage
Recordings and voicemail can be kept in the organisation’s own cloud storage rather than on the node. In Organisations → Storage choose where:
The key needs to create, read and delete objects in the bucket. Press Test
after saving: it writes a small file, reads it back, compares it and deletes it,
because the usual mistake is a policy that allows one of those and not the
others.
Only the operator sees this. A bucket is someone’s bill and a compliance
boundary, so an organisation’s own admin cannot point its recordings somewhere
you have not agreed to.
<prefix>/<organisation id>/recordings/<year>/<month>/<call>.wav
and …/voicemail/… for messages. A voicemail’s file stays on the node until its
notification email has been sent and it has been transcribed, since both read it.
Playing a recording. The bucket stays private. The panel and the API play
recordings through FireTone, with the same permission checks as before, and
never hand out a link to the bucket.
Retention deletes the file from the bucket when a recording or message
reaches the end of its window. If the bucket refuses, the call keeps pointing
at the file and the next sweep tries again.
Switching back to the node stops new uploads. Recordings already in the
bucket stay there and still play, because their settings are kept.
Refusal announcements
When a call cannot go out, the caller is told why. There are three reasons, and each has its own announcement:
In Organisations → edit → Refusal announcements, choose for each a recording
from the organisation’s media library (a prompt), text to speak, or a file on
the switch. Left as Nothing, the built-in sentence is spoken when the
organisation has text-to-speech, and the stock “the call cannot be completed as
dialled” plays when it does not.
A missing rate is kept apart from a low balance on purpose: nobody should top
up to fix a price that was never set. Every refusal is still logged as a
warning with its reason, and the call’s trace shows
refused: <reason>.