Skip to content

Managing Routing Logs

This page covers retrieving and managing the forensic routing log. Read How Routing Logs Work first for what a record contains — the commands below assume you know that a record is one router walk and that the trace is its full story.

Conventions as usual: $VSS, $TOKEN, $NSID; vsscli commands live under vsscli route-logs … (alias rl). Everything here is namespace-scoped — unlike CDRs there are no partition-wide variants (use --include-children from a parent namespace to cover a subtree). Range and pagination work exactly as for CDRs: --from/--to (RFC3339 or unix seconds), --since (24h, 7d), default last 24 hours; opaque cursor, --limit, --all.

Action Held by
route_log:read partition-admin, namespace-admin, operator, editor, viewer, system-auditor, noc-viewer, cdr-compliance
route_log:purge partition-admin, cdr-compliance only

noc-viewer is the role built for this data: routing forensics plus read-only running config — everything a call-routing investigation needs, nothing else. Note that billing deliberately has no routing-log access; the forensic log carries dialed-number history beyond what invoicing needs.

The list returns envelope summaries (no trace), newest first, with optional AND-filters on the envelope:

Terminal window
# Everything in the last day
curl -s "$VSS/v1/ns/$NSID/route-logs" -H "Authorization: Bearer $TOKEN"
# Only failed walks (no destination found) from the edge
curl -s "$VSS/v1/ns/$NSID/route-logs?matched=false&source=edge" \
-H "Authorization: Bearer $TOKEN"
# Everything that resolved to a treatment this week
curl -s "$VSS/v1/ns/$NSID/route-logs?from=2026-07-06T00:00:00Z&target_type=treatment" \
-H "Authorization: Bearer $TOKEN"

Filters: source (edge|ingest|reroute), matched (true|false), target_type (a target kind — line, trunk, treatment, …). They apply to the scanned envelope, so they narrow the page contents rather than speeding the scan. An unrecognized source or target_type value is rejected with a 400 listing the accepted values — a typo can’t masquerade as “no records”.

“How has this number routed over time?” has its own index, keyed by the as-dialed number. The match is exact — it is a lookup key, not a substring, and it matches starting_number (before any rewrites):

Terminal window
curl -s "$VSS/v1/ns/$NSID/route-logs?dialed=19195551234&from=2026-07-01T00:00:00Z" \
-H "Authorization: Bearer $TOKEN"

This is the fastest way to answer “when did routing for this DID change?” — scan its records across the window and watch the target (or the rewrite chain) shift between records.

The detail endpoint takes a call ULID (every walk of that call — edge, ingest, reroutes, in order) or a leg UUID (the walks touching that leg), and returns complete records including the trace:

Terminal window
curl -s "$VSS/v1/ns/$NSID/route-logs/01K02X5RJ8Q9Z3F7M6T1V4W8YA" \
-H "Authorization: Bearer $TOKEN"
# Narrow to one record / one source within the call
curl -s "$VSS/v1/ns/$NSID/route-logs/01K02X5RJ8Q9Z3F7M6T1V4W8YA?source=reroute" \
-H "Authorization: Bearer $TOKEN"

The everyday workflow pairs this with CDRs: find the suspect call (vsscli cdrs legs --filter …), copy its call_ulid, and route-logs get it to see exactly why it routed where it did.

Routing records expire on their own after 90 days; the purge exists for earlier erasure — a compliance request, or a number-history scrub. It follows the same rules as the CDR purge: it requires route_log:purge (partition-admin or cdr-compliance), an explicit to cutoff (a purge with no to is a 400 — it never defaults to “now”), and a confirmation body; the 412 echoes the exact date window it would erase, and the vsscli prompt shows the same window before asking.

Terminal window
curl -s -X DELETE "$VSS/v1/ns/$NSID/route-logs?from=2026-01-01T00:00:00Z&to=2026-06-01T00:00:00Z" \
-H "Authorization: Bearer $TOKEN" \
-d "{\"confirm_id\":\"$NSID\",\"confirm_timestamp\":$(date +%s)}"
# → {"success":true,"records_deleted":48213}
Response / symptom Meaning Do
404 route log not found No record with that id in this namespace Check the namespace; edge records exist only for calls that reached the router (feature-code dials produce none)
--dialed finds nothing for a number you can see in records The index is an exact match on the as-dialed number Query the number exactly as the caller dialed it (starting_number), not the rewritten form
A call has no edge record The call entered via the controller fallback, or the walk never ran Look for an ingest record; a missing trace means no translation walk happened
400 “must be one of” on a filter Unrecognized source / target_type value Pick from the accepted values listed in the error
400 missing range bound Purge sent without an explicit to cutoff Pass --to / ?to= — purge never defaults its upper bound
Records older than ~90 days are gone Automatic expiry Expected — export downstream if you need longer history
412 confirmation required Purge sent without (or with a stale) confirmation body Check the echoed window, re-send with confirm_id = the nsid and a fresh unix timestamp