Skip to main content

The carbon emissions and ESG footprint model

Devotel Orbit already records every outbound message and outbound voice minute your account sends. The carbon footprint feature converts that usage into a per-channel CO2 equivalent (CO2e) estimate, so ESG and procurement teams can answer sustainability questionnaires without exporting raw traffic data to a third-party calculator. This page explains the model behind those numbers: where the emission factors live, how SMS is metered, why both API surfaces agree, and what the exported CSV stamps into its header. The task walkthrough — open the dashboard page, pick a window, download the report — lives in the Sustainability and ESG reporting guide. This concept page owns the model: what the factors are, where they come from, and why the math looks the way it does. The guide owns the task; this page owns the reasoning.

1. Why a concept page in addition to the guide

Two different readers hit this feature. An operator wants to export a report — that is the guide’s job. An ESG auditor, a procurement reviewer, or your own sustainability lead wants to know why the number is what it is before they cite it in a filing — that is this page’s job. Three design decisions in particular are not obvious from the JSON response:
  1. One canonical factor table. Every factor value the API returns comes from a single source-of-truth table, with the citation for each factor attached to it.
  2. SMS is metered per segment, with a message-count fallback. A concatenated SMS is physically transmitted as N independent 160-character segments, so the estimate follows the segment count — and degrades gracefully when segment data was never recorded.
  3. Two wire surfaces, one factor set. The modern GET /analytics/carbon endpoint and the legacy stats-side adapter deliberately keep different response shapes, but both read their factor values from the same table, so an exported figure never depends on which endpoint rendered it.
Each of those is expanded below.

2. The channel factor table

Every channel line in a report carries the factor it used (grams CO2e per unit) and a human-readable source string naming where that factor comes from. The table is intentionally small and auditable: Design properties that make this table defensible in an audit:
  • Per-factor provenance. A factor with no citation is unjustifiable; a factor whose citation travels with it in every response and every CSV row is traceable. The source string is not decorative — it is what lets an auditor confirm the coefficient instead of taking it on faith.
  • Explicit estimation posture. The figures are order-of-magnitude estimates derived from published per-unit factors, labelled as such on every surface. The disclaimer is part of the model, not a footnote: it states plainly that this is indicative ESG reporting, not a certified carbon audit.
  • A fallback factor for unknown channels. A channel added to the platform before the table is updated still counts, at the generic IP-message factor (0.02 g CO2e per message). An unrecognised channel is never silently dropped from the footprint.
  • One estimate per unit basis. Factors are expressed per segment (SMS), per message (email and OTT channels), or per minute (voice). The basis is part of the factor definition — you cannot apply a per-message factor to a per-minute unit without the report showing it.

3. SMS: segment-basis math and the graceful fallback

A concatenated (multipart) SMS is not one transmission. The handset and network split it into N independent 160-character segments (153 when continuation headers apply), each separately transmitted and separately billed. The energy cost follows the same physics, so the SMS factor is expressed per segment, and the SMS line multiplies the factor by the segment count, not the message count. This is also why the SMS line reports both numbers: units is the segment count the factor was applied to; messages is the message count for context. A 390,000-message month that carried 410,000 segments is estimated on 410,000 units. The fallback covers the honest case: some providers, and some older traffic, never record segment counts — the field is zero. Estimating zero emissions for traffic you demonstrably sent would be worse than a coarser estimate, so when the segment count is absent the message count is used instead. The consequence is a known, bounded inaccuracy: multipart sends from those providers are counted as if single-segment, which under-rather than over-estimates. That trade-off is deliberate, and it is exactly the caveat an auditor should see stated rather than discover. Voice has the analogous rule in the other direction: it is metered per connected minute, never per message, and its minutes come from call records rather than the message store — so a stray voice-tagged message row never double-counts against the voice line.

4. Why two wire surfaces had to merge

The feature historically appeared on two API surfaces:
  • GET /analytics/carbon — the current per-channel report: basis-aware lines, per-factor provenance, totals in grams and kilograms.
  • GET /stats/analytics/carbon — an older stats-side adapter with a different envelope (camelCase per-channel lines, a per_channel / total_gco2e shape, its own CSV column set) that existing dashboard widgets and integrations already consume.
Early on, those two surfaces each maintained their own factor table, and the tables disagreed — on voice, by more than an order of magnitude. The same procurement-questionnaire figure then depended on which endpoint happened to render it, which is the one property an ESG number must never have. The consolidation keeps both wire shapes — the stats adapter’s consumers were not breaking-changed — but moves every factor value into the single canonical table behind GET /analytics/carbon. The legacy adapter re-derives its numbers from that table instead of maintaining its own. Both surfaces now also stamp the same methodology tag, factors_version: 2026-06-orbit-v1, onto every report, so a figure exported from either endpoint is reproducible against one known factor set and the two surfaces always reconcile. When a coefficient is revised, the version bumps in exactly one place and every downstream report cites it.

5. Scope: why only outbound counts

The footprint answers one question: what emissions did the platform cause on your behalf? That is outbound traffic — messages your account sends and voice minutes your account originates. Inbound replies are the counterparty’s send volume, not yours; counting them would charge you for traffic your organisation did not initiate. Treat the report as the outbound slice of a Scope 3 estimate: defensible, reproducible, and explicitly not your organisation’s full Scope 3 inventory. Say so when you cite it — the label the report carries is designed to be quoted alongside the figures, not stripped off.

6. The deterministic CSV envelope

The export endpoint renders the same report as a self-describing CSV, built deterministically so the same window always produces the same file. Its envelope is part of the contract:
  • Leading # comment lines carry the report title, the exact period the figures cover, the methodology version, and the full estimation disclaimer. Spreadsheet importers ignore # lines when parsing data, so the header survives the trip into an auditor’s workbook intact — the file stands on its own when detached from the platform.
  • A fixed column setchannel, basis, units, messages_or_calls, factor_g_co2e_per_unit, co2e_grams, co2e_kg — followed by one row per channel (highest-emitting first) and a closing TOTAL row.
  • The disclaimer in the header, on purpose. Because the disclaimer travels inside the file, a report forwarded through a procurement chain still states its own estimation posture at every hand-off.
Channels with zero outbound volume in the window are omitted from both the JSON and the CSV, so the breakdown only shows surfaces you actually used.