top of page

NENA i3-Aligned CHE Evidence Graph

  • Writer: Jon Whirledge
    Jon Whirledge
  • Oct 16
  • 3 min read

Every 911 call tells a story — from the first ring to the final report. The CHE Evidence Graph captures that story in real time, recording each call-handling event as a verifiable entry on the 911 Trust Ledger. By anchoring cryptographic proofs of call logs, audio recordings, and operator actions to a shared, permissioned blockchain, PSAPs can demonstrate integrity, compliance, and trust without exposing sensitive data.


The result is a transparent, tamper-evident record of every call — aligning with NENA i3 and EIDO standards while preserving privacy and operational control.


Why it matters


Call Handling Equipment (CHE) sits at the heart of every emergency response. It captures the moment a 911 call is received, answered, transferred, and closed. But until now, the digital trail behind those events lived in separate systems — vulnerable to deletion, error, or dispute.

The CHE Evidence Graph creates an immutable chain of custody for every call event. Each time a call changes state — from initiated to answered, on hold, transferred, or released — the CHE writes a signed record to the 911 Trust Ledger. The underlying data never leaves the PSAP; only a cryptographic fingerprint (hash) and essential metadata are published on-chain.


How It Works


  • Event-based Ledgering – Each call event becomes a blockchain transaction containing timestamp, call state, agent ID, and hash of off-chain artifacts (audio, logs, transcripts).

  • Privacy by Design – No personal data or audio is ever stored on-chain. Proofs of existence and integrity replace raw content.

  • Interoperable Schema – The event model extends the NENA i3 and EIDO standards, allowing CHE vendors and PSAPs to integrate without custom mapping.

  • Audit Ready – Every call can be reconstructed as a verified timeline — from call initiation to closure and retention action — without relying on a single vendor’s database.


Example Call Lifecycle


CallInitiated → CallAnswered → CallUpdated* → CallReleased

↘ RecordingCaptured → RetentionAction



CHE Evidence Event — Field Catalog


A) Identity & Linking (core)

  • event_id (UUID)

  • event_type (CallInitiated | CallAnswered | CallUpdated | CallReleased | RecordingCaptured | Transfer | Conference | Hold | Resume | Abandon | Error)

  • prev_event_id (UUID)

  • call_id (CHE logical CallID; stable across transfers/holds)

  • sip_call_id (raw SIP Call-ID header)

  • conversation_id (for multi-leg continuity, if CHE supports)

  • incident_id (optional; populated once linked to CAD)


B) Timestamps & Sequence

  • ts (event creation time, UTC ISO-8601 with ms)

  • che_rx_ts (CHE first-seen time)

  • che_tx_ts (CHE emit time, if different)

  • seq (monotonic per call_id)


C) Parties & Roles (PII-minimized)

  • agent_id (CHE operator ID or position)

  • agent_station_id (console/position)

  • caller_id_hash (hash of ANI/From; never raw)

  • callback_number_hash (hash)

  • service_urn (e.g., urn:service:sos.police)

  • language (detected/selected; BCP-47)

  • accessibility_mode (TTY | RTT | TCC | VRS | None)

  • origin_type (wireless | wireline | VoIP | NGCS | i3-text)


D) Media & QoS

  • media_types (audio | text | video array)

  • codec (e.g., PCM16, G711u)

  • jitter_ms_avg, packet_loss_pct_avg, rtt_ms_avg (if available)

  • recording_policy (on | off | selective)


E) Location (i3/PIDF-LO friendly, minimized)

  • location_source (HELD | PIDF-LO | LIS | Manual | None)

  • location_method (civic | geo | hybrid)

  • location_hash (hash of PIDF-LO or civic/geo blob)

  • dispatchable_location_hash (hash if derived)

  • life_cycle (received | validated | updated)

  • confidence (0–100; optional)


F) Routing Context (read-only in CHE, but useful)

  • esrp_id (if known)

  • route_reason (default | policy | overflow | transfer-in)

  • psap_id (target PSAP identifier)


G) Call State & Controls

  • call_state (Ringing | InProgress | OnHold | Transferred | Conferenced | Released | Abandoned | Error)

  • hold_reason (if hold)

  • transfer_type (blind | consult | supervised)

  • bridge_id (for conferences)

  • duration_ms (for terminal states)


H) Artifacts (off-chain references)

Each event can point to zero or more artifacts:

artifacts[]: {
  type: "che-log | audio | rtt-transcript | screen-recording | policy-snapshot",
  hash: "sha256:…",
  uri: "che://… | recorder://…",
  retention_class: "90d_audio | 2y_logs | casefile",
  size: <bytes>,
  segment: { index: 1, start_ts: “…”, end_ts: “…” } // for audio/text chunks
}

I) Security & Provenance

  • issuer (system identity, e.g., CHE-PSAP01)

  • issuer_cert_chain_id (reference to PKI chain)

  • signature (detached or JOSE over canonical payload)

  • schema_version (e.g., che.v1.2)

  • software_version (CHE version/build)


J) Policy, Privacy, and Audit

  • privacy_profile_id (which fields were suppressed/hardened)

  • retention_profile_id (applied at creation time)

  • redaction_of_event_id (if this event supersedes/redacts prior)

  • notes_hash (hash of any free-text notes captured in CHE)

  • policy_refs (array of policy IDs cited for this event)


Event Types & Their Expected Fields


CallInitiated

Must: A, B, C(partial), D(partial), E(partial), F(partial), GArtifacts: che-logNotes: include origin_type, media_types, service_urn if present in INVITE.


CallAnswered

Must: A, B, C(agent), G(state=InProgress)Nice: D(QoS baseline), E(life_cycle=received), H(optional audio segment start)Artifacts: che-log


CallUpdated (repeatable)

Use for location updates, language, accessibility, notes:Must: A, B, GPlus one or more of: C(language/accessibility), D(QoS deltas), E(updated location), H(additional audio/rtt-transcript)Artifacts: che-log, optional rtt-transcript


RecordingCaptured (can be emitted by recorder but linked here)

Must: A, B, H(artifact type=audio with segment info)Nice: D(codec)Notes: if recorder is a separate system, issuer = recorder, but keep call_id.


Hold / Resume

Must: A, B, G(with reason for hold)Artifacts: che-log


Transfer

Must: A, B, G(state=Transferred), F(route_reason=transfer-out), target_psap_idNice: transfer_type, consult_agent_id (if supervised)


Conference

Must: A, B, G(state=Conferenced), bridge_idArtifacts: che-log


Abandon

Must: A, B, G(state=Abandoned)Artifacts: che-log


CallReleased

Must: A, B, G(state=Released), duration_msArtifacts: che-log


Error

Must: A, B, error_code, error_detail_hashArtifacts: diagnostics log


Comments


bottom of page