QVCCS innovation · Audit and governance
Where does every number go? Auditing Genesys Cloud DIDs, flows and caller IDs
Phone numbers in Genesys Cloud CX live in more places than most teams realise: call routes, DID records and pools, site number plans, trunks, user profiles and outbound campaigns. Our DID Conflict Checker reads them all, maps every inbound number to the Architect flow it lands on, and surfaces the stale, orphaned and dual-routed numbers without a spreadsheet in sight.
Did you know that, in the Genesys Cloud Platform API, call routes are served as IVR configurations at /api/v2/architect/ivrs, with their phone numbers in a dnis list – and that reading them needs the Routing > Call Route > View permission?
Did you know a single Genesys Cloud call route can hold up to 4,500 phone numbers, but Genesys notes that the more numbers a route holds, the slower the Edge is to process them?
Did you know a DID record’s ownerType in the API can be USER, PHONE, IVR_CONFIG or GROUP – so a number in your DID ranges may belong to a person or a handset rather than to any call flow at all?
01
The 08:55 phone call nobody can explain
It is 08:55 on a Monday and the team leader on the sales floor has a puzzle. A customer says they dialled the new promotions number and reached a recorded greeting for a service line that was retired last year. Another caller swears their own mobile rang moments after they hung up, showing their own number. Meanwhile one agent keeps receiving calls that should have gone to a queue. Three symptoms, one root cause: nobody can say, with confidence, where every number in the org actually goes.
In Genesys Cloud CX, a phone number is not one record in one place. It can sit in a DID range, be assigned to a person, a phone or a call flow, appear in a call route alongside its open, closed and holiday flows, live in a site number plan or a trunk’s inbound routing, be typed into a user’s profile as a work or mobile number, and be used as the caller ID on an outbound campaign. Each of those places is correct on its own terms. The trouble starts when they disagree – and spotting that means reading them all at once.
02
Where numbers live in Genesys Cloud CX
Genesys gives administrators good tools for each object. The Call Routing page under Admin > Routing lists each call route with its open call flow, closed call flow, holiday call flow, schedule group, emergency settings, division and inbound phone numbers. When a caller dials one of those numbers, they are routed into the associated inbound call flow. The DID Numbers page under Admin > Telephony splits into DID Ranges, where purchased numbers are made available, and DID Assignments, where each number can be assigned to a person, a phone or a call flow, with Assignee and Type columns and an Assigned or Unassigned view. Orgs on Genesys Cloud Voice administer numbers through Number Management instead.
Outbound is configured somewhere else again. Every dialler campaign carries a caller ID phone number and name – the callerAddress and callerName fields in the API – which is what the person you are calling sees. User profiles carry their own contact numbers in addresses and primary contact information. None of this is a gap in the platform; it is the natural shape of a system where routing, telephony, people and campaigns are administered by different teams with different permissions.
The insight behind our app was simple: the questions that hurt are cross-object questions. Does any agent’s profile number collide with an inbound DID? Is any number registered to two different flows? Is any inbound DID also being presented as an outbound caller ID? Answering those from the admin pages means exporting, copying and VLOOKUP-ing across several screens. So we built a single view that joins them – the figure below shows the Genesys data model it reads and how every source converges on one number registry.
Read this diagram as text
A three-column diagram, read left to right: eight read-only Genesys Cloud sources join into one normalised number registry, which feeds five outputs.
- Left column, "Genesys Cloud Platform API", headed "Eight read-only sources", lists: "Inbound call flows"; "Call routes (IVR configs) · dnis[]"; "A · DID records · ownerType"; and "B · DID pools (start, end)".
- It continues with "C · Site number plans", "D · Trunk inbound routing", "Active users’ profile numbers" and "Campaign caller IDs · callerAddress".
- Lines from all eight sources join on a vertical bus and enter the middle column, "The join", headed "One registry".
- A note there reads "Five routing sources: call routes plus A–D. Users and campaigns are cross-checked, not routed."
- The bus arrow enters a "Normalise" box ("Digits, leading +" and "Equal or last 10"), and an arrow leads down to a "Registry" box ("Number → flows[]", "Source of each", "ownerType census"), with the note "GET requests only".
- From the registry, arrows fan out to five outputs in the right column, "One view", headed "Inventory and findings".
- The outputs are "Flow ↔ DID map" ("Per flow, E.164-sorted, source pill") and three findings: "Agent conflicts" ("Profile field at fault · last 10 digits"), "Duplicate routings" ("One number, two distinct flows") and "Ghost ring" ("Inbound DID = campaign callerAddress").
- The fifth output is "Exports" ("CSV · Excel · PDF, built in the browser"), and a final box reads "One click replaces the spreadsheet".
03
One click, five routing sources, one registry
In the app – which appears in-app as the QVCCS DID Validator, and which our team calls DIDmapper – a single Run Audit click walks the org in a fixed pipeline. It loads every inbound call flow from /api/v2/flows?type=INBOUNDCALL&deleted=false, then every IVR configuration from /api/v2/architect/ivrs. Each IVR resolves to a flow from the first of its open-hours, default, closed-hours or holiday flow references, and every number in its dnis list is registered against that flow. This is the canonical DID-to-flow bridge, and it is why the call route is the first thing we read.
Four further sources follow. Source A is the individual DID records from /api/v2/telephony/providers/edges/dids, resolved in three passes: through the IVR map when ownerType is IVR_CONFIG, directly when the owner is an inbound-flow id, and by type hints otherwise. Unmatched numbers are kept as Unassigned so they still take part in the agent check, and an ownerType census explains at a glance why nothing mapped – if every DID is owned by USER, there are simply no flow assignments to find. Source B registers DID pool start and end boundaries. Source C fetches every site’s number plans. Source D reads inbound routing embedded on trunks.
Real orgs are messy, so a records-agnostic resolver tries every field shape we have met – owner, routing target, flow, inbound route, call route, destination – covering Genesys Cloud Voice, BYOC and older configurations. Numbers are normalised to digits with a leading plus, and the whole run streams into a live scan log stage by stage, with per-page pagination progress on large orgs, so nobody stares at a spinner wondering whether anything is happening.
04
Three conflicts that no single admin screen shows
The agent conflict check harvests numbers from the addresses, primary contact information and phones of every active user via /api/v2/users, then compares each against every registered number, mapped or unassigned. Two numbers conflict when they are equal or when their last ten digits match, so +1 702-555-0142 and 17025550142 collide as intended, while short extensions only ever match exactly. Each flagged agent gets a card naming the exact profile field at fault – addresses › WORK, for example – with the clashing DID and its flow, plus a flat summary table ready to paste into a ticket.
Duplicate routings are numbers registered to two or more distinct flows. Only one assignment can win, so the others are dead configuration that someone will one day trust. The subtle part is provenance overlap: when a call route and a DID record both point the same number at the same flow, that is expected, and the app deliberately does not count it. A duplicate always means two different flows, listed with the source of each registration so the fix is obvious.
The third check is the one that makes customers ring back angry. We call it the ghost ring: a number that is both an inbound DID and an outbound campaign callerAddress. The audit reads /api/v2/outbound/campaigns, compares every caller ID with the full inbound set, and flags each collision with the campaign name, the inbound flow and an Active or Off pill. Campaigns that take their caller ID from the contact list have no callerAddress, and our user guide says plainly that those cannot be checked this way.
Read this diagram as text
A diagram of three side-by-side panels, one per cross-check, each using illustrative phone numbers.
- Check 1, "Agent conflict", headed "Profile meets DID": a user profile work number "+1 702-555-0142" and an inbound DID on the sales flow "17025550142" are linked by a double-headed arrow labelled "Last 10 digits".
- The result is a "Conflict card per agent" listing "Agent · field · number · DID · flow", with the note "Extensions under 10 digits match only exactly".
- Check 2, "Duplicate routing", headed "One number, two flows": the number "+44 20 7946 0004" branches to two flows, "Service flow via call route" and "Legacy flow via site plan".
- Two outcomes are shown: "Same flow, two sources", ticked as "Provenance overlap, not counted"; and "Two distinct flows", crossed as "Duplicate routing, flagged".
- Check 3, "Ghost ring", headed "Inbound DID as caller ID": an inbound DID on the sales flow "+44 20 7946 0001" and a campaign callerAddress "+44 20 7946 0001" are linked by a double-headed arrow labelled "Same number".
- The result is "Flagged with campaign", listing "Inbound flow · campaign · Active or Off", with the note "Caller IDs taken from the contact list cannot be checked this way".
- The banner beneath reads: "Each finding names the object to fix: the user’s profile field, the flow registration or the campaign. Numbers illustrative."
05
From inventory to a decommission list
Findings are only half the value; the inventory is the other half. The results workspace lists every inbound flow with its numbers as chips, sorted by E.164 with a country flag, national digit grouping and a source pill such as DID, DID Pool, Site or Trunk. Flow names deep-link straight into Architect. A reverse name filter hides every staging flow in one keystroke, a digits-only search finds a number across all flows, and the sort can put oldest-published or no-DID flows first.
Two chips turn the inventory into a clean-up plan. A staleness chip appears when a flow’s last publish is 180 days or more ago, and the “only flows with no DID” toggle shows orphans. Combine them and you have a decommission-candidate list that a design authority can actually review. An optional second pass inventories the eleven non-voice flow types – chat, email, message, secure call, bot, workflow, in-queue, outbound and survey – for a complete Architect catalogue.
Everything exports in the browser: four CSV files, a five-sheet Excel workbook including the ownerType census, or a branded landscape PDF with an executive summary that suits audit hand-over. Exports honour the on-screen flow filter and stamp it into the file name, while conflicts, duplicates and caller-ID findings always export in full, because they are a separate concern from whatever you were browsing.
06
Read-only by construction, built the QVCCS way
An audit tool that can change routing is a liability, so this one cannot. Apart from the OAuth client-credentials token call, every request it makes is a GET. It needs a read-only role covering telephony, Architect, routing and the user directory, with outbound read as an optional extra for the caller-ID check. The client secret is sent once at sign-in and never returned to the browser, a fresh token is fetched for every run, and results are never stored server-side – they live in the browser tab until the next audit. Because results contain agent names and numbers, the guide reminds users to treat exports accordingly.
We built it the way we deliver any change. Our IT Systems, Telecoms & SIP Engineer defined the number sources from real Genesys Cloud Voice and BYOC estates; a Senior Developer built the resolver and pipeline; and a Systems Integration Tester ran negative and failure-path tests against missing scopes, empty sources and odd field shapes, with Practice Lead peer review before release. It earns its keep in the Transition stage of our method – rehearsing a number porting plan or a cut-over – and again in Run & evolve health checks, backed by the whole practice.
How it compares
Native number administration and the QVCCS DID Conflict Checker
Genesys Cloud CX administers numbers per object, with the right permissions for each team. Our app reads across those objects.
| Aspect | Native Genesys Cloud CX | QVCCS DID Conflict Checker |
|---|---|---|
| Number to flow | Call Routing lists each route’s open, closed and holiday flows and its inbound numbers; DID Assignments shows each number’s assignee and type. | One view per inbound flow merging call routes, DID records, DID pools, site number plans and trunk routes, each number tagged with its source. |
| Agent profile numbers | Held on the user’s profile; no cross-check against inbound numbers is described in the Call Routing or DID Numbers documentation. | Every active user’s addresses, contact info and phones compared with every registered number on equality or the last ten digits. |
| Numbers reaching two flows | The API states an IVR’s numbers must be unique and not in use by another resource. | Registers numbers from all five sources and flags any that reach two distinct flows, ignoring same-flow provenance overlap. |
| Outbound caller IDs | Set per campaign as the caller ID number and name. | Flags every inbound DID that is also a campaign callerAddress, with the campaign’s Active or Off state. |
| Stale and orphaned flows | Flow records expose publish and modify dates through the flows API. | Staleness chip at 180 days and a no-DID toggle combine into a decommission-candidate list. |
| Access needed | Call Routing administration uses Call Route add, edit, view and delete permissions. | Read-only role; GET requests only, plus the OAuth token call. |
| Evidence | Each admin page shows its own object. | CSV, five-sheet Excel and a branded PDF built in the browser. |
Native behaviour is as described in the Genesys Cloud Resource Center and Platform API documentation at the time of writing.
The takeaways
- Every inbound number mapped to the Architect flow it reaches, from five routing sources, in one click.
- Agent profile clashes, dual-routed numbers and ghost-ring caller IDs surfaced without exports or spreadsheets.
- Stale and orphaned flows combined into a reviewable decommission list.
- Strictly read-only: GET requests only, no server-side storage of results.
- Audit-ready CSV, Excel and PDF evidence for cut-overs, porting and health checks.
DID Conflict Checker is part of the QVCCS App Suite, included with every Managed Professional Services tier and built by the same certified team that designs, builds and supports Genesys Cloud CX solutions.
Sources
- Call routing overview – Genesys Cloud Resource Centerhelp.genesys.cloud
- Add a call route – Genesys Cloud Resource Centerhelp.genesys.cloud
- Manage DID and toll-free number assignmentshelp.genesys.cloud
- Manage DID and toll-free number rangeshelp.genesys.cloud
- Architect APIs – Genesys Cloud Developer Centerdeveloper.genesys.cloud
- Telephony APIs – Genesys Cloud Developer Centerdeveloper.genesys.cloud
- Outbound APIs – Genesys Cloud Developer Centerdeveloper.genesys.cloud