Account codes (or dial-in PINs) are the cleanest way to attribute phone calls to people when extensions aren't tied one-to-one to staff — shared handsets, hot-desking, or field staff dialling out through a central trunk. The concept is simple; keeping the mapping accurate as you grow past a few hundred codes is where most setups fall apart.
This guide covers the model and workflow that scales — the same approach Q5000 uses for its PIN management.
Keep the mapping out of the dialplan
It's tempting to encode "PIN 1234 = Sales" directly in your PBX configuration. Don't. Store
the relationship — PIN → user → department — in a table (or a proper tool) you can edit
without reloading the PBX. The PBX's only job is to stamp the accountcode onto each call
detail record; the meaning of that code belongs in your reporting layer, where non-technical
staff can maintain it.
Model three levels, not two
Map PIN → person → department, not PIN → department directly. Modelling the person in the middle pays off constantly:
- When someone changes department, you re-point one person record instead of editing every code they hold.
- You can report per person and per department from exactly the same data.
- One person can hold several codes (desk PIN, mobile PIN) that all roll up correctly.
Plan for churn and bulk edits
At 1,000+ codes you will not hand-edit these. You need CSV import and export so onboarding or HR can hand you a spreadsheet and you round-trip it back in. Two rules make bulk work safe:
- Make imports idempotent — re-importing the same file must update existing records, not create duplicates.
- Round-trip the full structure — export should carry the department hierarchy and code assignments so an export can be re-imported without loss.
Surface unmapped codes — don't drop them
There will always be calls carrying an accountcode you haven't mapped yet. If your reporting
silently discards them, you lose visibility of real spend. Instead, surface unmapped codes as
an "unassigned" bucket in every report. That bucket is often where the interesting usage
hides — a new starter nobody registered, or unusual after-hours activity worth a second look.
Treat PINs as low-grade credentials
A dial-in PIN is effectively a credential: anyone who knows it can bill calls to that person. So handle them with a little care:
- Don't splash raw PINs across every screen and report. Mask them once they've served
their lookup purpose (e.g.
PIN ••34). - Don't log them in clear text.
This matters more in regulated environments and for POPIA/GDPR-style expectations around personal and access data.
Spreadsheet vs tool
For a small, stable site a spreadsheet keyed on account code works. Past a few hundred codes with regular staff churn, you want proper CRUD, idempotent CSV round-trip, an unassigned-code view, and PIN masking. Q5000 provides exactly this for FreePBX, Issabel, Elastix and VitalPBX, including a three-level PIN → user → department model and consolidated per-department reports. See how Q5000 handles PIN and account-code mapping →
Frequently asked questions
What's the difference between a PIN and an account code?
In practice they play the same role for call accounting: a value attached to a call that
identifies who made it. A PIN is typically entered by the caller before dialling; an account
code may be set per extension. Both land in the CDR's accountcode field.
How do I attribute calls when several people share one phone? Use per-caller PINs rather than the extension. Each caller enters their PIN, so the call is attributed to the person, not the shared handset.
Can account-code mapping scale to thousands of codes? Yes, provided you keep the mapping in an editable data layer (not the dialplan) and support CSV import/export for bulk maintenance. Q5000 is designed for 1,000+ codes.
What happens to calls with an account code I haven't mapped? Report them as an "unassigned" bucket rather than dropping them — that preserves total spend visibility and highlights codes that need attention.