Getting Started

Carbonly is a developer platform for tracking the resource usage and sustainability impact of your software features. It instruments your codebase at the feature level — turning execution time and memory into energy and CO₂ per call, deterministically and without black boxes.

The platform is built around three concepts:

  • ProjectsA grouping for your application (e.g. my-api, data-pipeline).
  • EnvironmentsIsolated contexts within a project — development, staging, production.
  • FeaturesIndividual code paths you want to track, identified by a key string.

Prerequisites

  • Node.js 18+ (or any runtime with fetch support)
  • A Carbonly account — sign up at carbonly.io
  • A project created in the Carbonly dashboard
  • An SDK key issued for your target environment

Installation

Install the SDK from npm:

terminal
npm install @carbonly/node
# or
pnpm add @carbonly/node
# or
yarn add @carbonly/node

Then add your SDK key to your environment:

.env
CARBONLY_API_KEY=carbonly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

SDK keys are prefixed with carbonly_live_ for production environments and carbonly_test_ for non-production. Never commit keys to source control.

Quick Start

Initialize the client once (typically in a shared module):

carbonly.ts
import { CarbonlyClient } from "@carbonly/node";

export const carbonly = new CarbonlyClient({
  apiKey: process.env.CARBONLY_API_KEY,  // carbonly_live_... or carbonly_test_...
});

Then wrap the feature you want to track with carbonly.track():

checkout.ts
import { carbonly } from "./carbonly";

export async function checkoutFlow(cart: Cart) {
  return carbonly.track("checkout-flow", async () => {
    // your feature logic here
    return await processCart(cart);
  });
}
How it works: carbonly.track() wraps your function, measures execution time and memory, then batches the telemetry event and sends it to POST /v1/ingest/batch in the background. Your function's return value is passed through unchanged.

API Reference

The Carbonly ingestion API is the only endpoint your SDK or application needs to talk to. All requests authenticate via an x-api-key header containing an SDK key issued from your project's dashboard.

Authentication

All ingestion endpoints require an SDK key passed as an HTTP header:

x-api-key: carbonly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are SHA-256 hashed at rest — the raw key is only shown once at creation time. Revoke and rotate keys from the SDK Keys page in your project.

Batch Ingest

POST/v1/ingest/batch

The primary ingestion endpoint. Send up to 500 metric events in a single request. The SDK batches events internally and flushes on an interval, so you rarely need to call this directly.

Request body

FieldTypeDescription
sdkVersionrequiredstringThe version of the SDK sending the events (e.g. "1.0.0").
appVersionstringOptional version of your application.
eventsrequiredarrayArray of metric event objects. Maximum 500 events per batch.

Event object fields

FieldTypeDescription
featureKeyrequiredstringIdentifier for the feature being tracked (e.g. "checkout-flow"). Must match a feature registered in the project.
environmentKeyrequiredstringThe target environment slug (e.g. "production", "staging"). Must match an environment in the project.
executionTimeMsrequirednumberWall-clock duration of the feature execution in milliseconds.
memoryBytesnumberMemory allocated by the feature in bytes. Used in CO₂ calculation. Optional but recommended.
cpuPercentnumberCPU utilization percentage at time of execution (0–100). Optional.
timestamprequiredstringISO 8601 timestamp of when the event occurred on the client.
metadataobjectArbitrary key/value pairs (string | number | boolean). Stored as JSONB. Max 20 keys.

Response

202 Accepted
Events queued for processing.
400 Bad Request
Payload failed Zod validation.
401 Unauthorized
Missing or invalid x-api-key.

Single Event

POST/v1/ingest/single

A convenience endpoint for sending one event at a time. Accepts the same fields as a single item in the batch events array, plus sdkVersion and appVersion at the root level.

FieldTypeDescription
sdkVersionrequiredstringSDK version sending the event.
appVersionstringOptional app version.
featureKeyrequiredstringFeature identifier.
environmentKeyrequiredstringTarget environment slug.
executionTimeMsrequirednumberExecution duration in milliseconds.
memoryBytesnumberMemory used in bytes.
cpuPercentnumberCPU utilization at time of call.
timestamprequiredstringISO 8601 client-side timestamp.
metadataobjectOptional key/value context.

Health Check

GET/v1/ingest/health

Returns a lightweight status response. Useful for verifying SDK connectivity and confirming the API key is valid before sending production events.

// 200 OK { status: "ok", project: "my-api", environment: "production" }

SDK Examples

Choose your language or tool below. Every example uses the same HTTP API — the SDK simply wraps the batching and retry logic for you.

terminal
# Health check — verify your key and project
curl -X GET https://api.carbonly.io/v1/ingest/health \
  -H "x-api-key: carbonly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Single event
curl -X POST https://api.carbonly.io/v1/ingest/single \
  -H "Content-Type: application/json" \
  -H "x-api-key: carbonly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -d '{
    "sdkVersion": "1.0.0",
    "featureKey": "checkout-flow",
    "environmentKey": "production",
    "executionTimeMs": 145,
    "memoryBytes": 268435456,
    "timestamp": "2026-04-15T10:00:00.000Z"
  }'

# Batch (up to 500 events)
curl -X POST https://api.carbonly.io/v1/ingest/batch \
  -H "Content-Type: application/json" \
  -H "x-api-key: carbonly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -d '{
    "sdkVersion": "1.0.0",
    "events": [
      {
        "featureKey": "checkout-flow",
        "environmentKey": "production",
        "executionTimeMs": 145,
        "memoryBytes": 268435456,
        "timestamp": "2026-04-15T10:00:00.000Z"
      },
      {
        "featureKey": "search-index",
        "environmentKey": "production",
        "executionTimeMs": 32,
        "memoryBytes": 67108864,
        "timestamp": "2026-04-15T10:00:01.000Z"
      }
    ]
  }'
Note: The cURL examples are useful for testing key validity and exploring the API shape. For production use, prefer the SDK or an HTTP client that handles retries and batching.

Sustainability Calculations

Every CO₂ estimate Carbonly produces is deterministic and traceable — no ML, no black boxes. This page documents exactly how raw telemetry turns into energy and carbon numbers, and which published coefficients are used as defaults.

How It Works

The pipeline runs in three steps after daily aggregation completes:

  1. 1
    Raw → Compute Units
    Each hourly/daily aggregated row is converted to a dimensionless Compute Unit value that normalises CPU time and memory into a single resource score.
  2. 2
    Compute Units → Energy (kWh)
    Compute Units are multiplied by hardware power coefficients and the datacenter PUE factor to arrive at an estimated kilowatt-hour figure.
  3. 3
    Energy → CO₂ (grams)
    The energy figure is multiplied by the grid carbon intensity for the configured region to produce a CO₂ estimate in grams.

Formulas

Step 1 — Compute Units

compute_units
compute_units = (executionTimeMs / 1000 × cpuCoresEstimate) + (memoryBytes / 1_073_741_824 × memoryGbWeight) // Defaults cpuCoresEstimate = 0.1 memoryGbWeight = 0.5

Step 2 — Energy (kWh)

total_energy_kwh
cpu_energy_kwh = computeUnits × cpuWattsPerCore / 1000 memory_energy_kwh = (memoryBytes / 1e9) × memoryWattsPerGb / 1000 total_energy_kwh = (cpu_energy_kwh + memory_energy_kwh) × pueMultiplier

Step 3 — CO₂ (grams)

co2_grams
co2_grams = total_energy_kwh × carbonIntensityGramsPerKwh
Worked Example
Input: 150ms execution, 256 MB memory, defaults for all coefficients
compute_units0.015 + 0.1250.140
cpu_energy_kwh0.140 × 10 / 10000.0014 kWh
memory_energy_kwh(268_435_456 / 1e9) × 0.375 / 10000.0000938 kWh
total_energy_kwh(0.0014 + 0.0000938) × 1.20.001792 kWh
co2_grams0.001792 × 4000.717 g CO₂

Default Coefficients

All defaults are overridable per-organization via sustainability_config in your dashboard settings. Carbon intensity defaults to the IEA world average and can be scoped by region using the carbon_regions table.

ParameterDefaultUnitSource
cpuWattsPerCore10WSPEC Power SPECpower_ssj2008
memoryWattsPerGb0.375W/GBDDR4 TDP average
pueMultiplier1.2Google / AWS average PUE
carbonIntensityGramsPerKwh400g/kWhIEA world average
cpuCoresEstimate0.1coresConservative shared-CPU estimate
memoryGbWeight0.5Proportional memory-to-compute weight
Carbonly does not use machine learning for any estimates. All numbers are derived by applying these published coefficients to the telemetry your SDK sends. This makes every figure auditable, reproducible, and easy to adjust when your infrastructure assumptions differ from the defaults.