Historical France Carbon Intensity Prices

Historical France Carbon Intensity Prices

You need historical carbon intensity for France as a clean, queryable time series and a repeatable way to fetch it programmatically. By the end of this guide, you will know exactly how to call the Energy API time series endpoint for the France Carbon Intensity symbol, interpret the response, handle symbol availability errors, and wire the data into your own system.

What you will build

This post is a focused, copy-pasteable guide to querying the Energy API for the France Carbon Intensity time series:

Illustration: Historical France Carbon Intensity Prices
  • API symbol: France Carbon Intensity (code: CARBON_INT_FR)
  • Unit: gCO2/kWh
  • HTTP method: GET
  • Endpoint: /api/v1/timeseries
  • Auth: api_key query parameter (use YOUR_API_KEY as the placeholder)

You will get a working curl example, a Python example that parses the response, and multiple concrete JSON envelopes (including a real-world failure case) so you can design robust ingestion and error handling from day one.

Symbol and data model explained

The France Carbon Intensity series quantifies grams of CO2 per kilowatt-hour (gCO2/kWh) for France’s power system. In the Energy API, it is referenced by the symbol code CARBON_INT_FR. Time series queries return:

  • rates: keyed by symbol, containing values or nested-by-date values depending on the product’s data shape
  • dates: keyed by symbol, denoting the effective date for the rate if applicable
  • currencies: keyed by symbol, indicating the denomination; for intensity, treat this field as ancillary metadata rather than a conversion unit
  • base: reference currency for price symbols; for intensity, the key concept is the unit gCO2/kWh, not currency

When building your integration, treat CARBON_INT_FR as an intensity metric. Avoid currency conversions. If you mix multiple symbols (e.g., carbon allowances or gas), ensure you do not force a currency base that contradicts catalog guidance.

Endpoint, parameters and authentication

Use GET /api/v1/timeseries with the following query parameters:

  • start: inclusive start date (YYYY-MM-DD)
  • end: inclusive end date (YYYY-MM-DD)
  • symbols: one or more comma-separated symbol codes (use CARBON_INT_FR for this guide)
  • api_key: your API key (string). Use YOUR_API_KEY in examples; replace with your actual key in production.

Authentication is via the api_key query parameter only. Do not include headers that are not documented. If you combine pricing symbols like TTF_GAS or EUA_CO2 with other series, do not pass a base currency that would contradict catalog rules. For France Carbon Intensity, you do not need to pass base.

For detailed parameter definitions, see the Documentation.

Quickstart: curl request you can run

Below is the official sample curl for the time series endpoint. Keep the URL and parameters exactly as shown. Replace YOUR_API_KEY with your key when you test against your account. Note that this demonstrates the endpoint and parameter shape and includes a different symbol in the JSON body; use the error envelope later in this post as the authoritative response snippet for CARBON_INT_FR availability.

curl -G "https://energy-api.com/api/v1/timeseries" --data-urlencode "start=2026-01-01" --data-urlencode "end=2026-03-31" --data-urlencode "symbols=CARBON_INT_FR" --data-urlencode "api_key=YOUR_API_KEY"

Understand the real-world response status for CARBON_INT_FR

The live call for CARBON_INT_FR did not succeed at the time of writing. Design your client to read the success field and branch accordingly. Here is the real error envelope to expect when the symbol is temporarily unavailable:

{"success":false,"error":"Symbol CARBON_INT_FR is not currently available. See \/api\/v1\/symbols for the current catalog."}

What to do with this:

  • Check success. If false, inspect error and halt ingestion for this symbol.
  • If you request multiple symbols, handle partial successes by validating each key under rates, dates, and currencies.
  • Use the symbols catalog endpoint noted in the message to confirm current availability before scheduling large backfills.

Field-by-field anatomy using the official sample JSON

The official sample below illustrates the envelope you’ll parse when success is true. The sample uses a different symbol and is not a carbon intensity series, but the envelope fields and types are what your code should expect and handle generically.

{
"success": true,
"date": "2026-10-24",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 137.1925
},
"dates": {
"OMIE_ES_DA": "2026-10-24"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}

Fields you will actively use:

  • success: boolean gate for downstream processing
  • rates: primary payload; for CARBON_INT_FR you will read the intensity value(s) associated with the symbol
  • dates: symbol-effective date (useful when a single snapshot date is provided)
  • currencies: denomination metadata. For intensity, focus on the unit gCO2/kWh rather than currency
  • date and base: context that may accompany snapshots; do not treat base as a transformer for intensity values

Multiple JSON examples to harden your parser

Example A — the real-time unavailability envelope you must handle for CARBON_INT_FR:

{"success":false,"error":"Symbol CARBON_INT_FR is not currently available. See \/api\/v1\/symbols for the current catalog."}

Design tip: If you request CARBON_INT_FR and other symbols together, treat this as a per-call failure and short-circuit the entire batch if your job requires atomicity. Otherwise, continue processing the other symbols while logging this error for retries.

Example B — the official success envelope format, demonstrating the structure to expect when success is true:

{
"success": true,
"date": "2026-10-24",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 137.1925
},
"dates": {
"OMIE_ES_DA": "2026-10-24"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}

Use this to validate field existence, types, and your JSON traversal logic.

Example C — the same real error envelope, shown again so you can copy it directly into unit tests that validate failure-path observability and retries:

{"success":false,"error":"Symbol CARBON_INT_FR is not currently available. See \/api\/v1\/symbols for the current catalog."}

Example D — the official success envelope again for your “happy path” test fixture. Keep it exactly the same to avoid brittle tests:

{
"success": true,
"date": "2026-10-24",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 137.1925
},
"dates": {
"OMIE_ES_DA": "2026-10-24"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}

End-to-end Python example (robust to symbol availability)

This example calls the same /api/v1/timeseries endpoint, checks success, and extracts values for CARBON_INT_FR if present. It also logs the error message from the real envelope when the symbol is unavailable.

import os
import sys
import urllib.parse
import json
import time
from typing import Any, Dict, Optional
import ssl
import http.client

API_HOST = "energy-api.com"
API_PATH = "/api/v1/timeseries"

def build_query(params: Dict[str, str]) -> str:
# Only include documented parameters
parts = []
for k, v in params.items():
parts.append(f"{k}={urllib.parse.quote_plus(v)}")
return "&".join(parts)

def get_timeseries(start: str, end: str, symbols: str, api_key: str) -> Dict[str, Any]:
qs = build_query({
"start": start,
"end": end,
"symbols": symbols,
"api_key": api_key
})
context = ssl.create_default_context()
conn = http.client.HTTPSConnection(API_HOST, context=context, timeout=30)
try:
conn.request("GET", f"{API_PATH}?{qs}")
resp = conn.getresponse()
payload = resp.read().decode("utf-8")
if resp.status != 200:
# Non-200 HTTP status: surface as error-like envelope for uniform handling
return {"success": False, "error": f"HTTP {resp.status}: {payload}"}
data = json.loads(payload)
return data
finally:
conn.close()

def parse_carbon_intensity(data: Dict[str, Any]) -> Optional[float]:
if not data.get("success", False):
return None
rates = data.get("rates", {})
# Access symbol directly; structure may be a scalar or a nested timeseries depending on catalog
val = rates.get("CARBON_INT_FR")
if val is None:
return None
# If val is a number, return as-is; if it is a dict keyed by date, you may select the latest key
if isinstance(val, (int, float)):
return float(val)
# If dict-of-dates, choose a deterministic date (e.g., min or max) per your app’s rule.
# Avoid guessing; here we simply decline to coerce.
return None

def main():
api_key = os.environ.get("ENERGY_API_KEY", "YOUR_API_KEY")
start = "2026-01-01"
end = "2026-03-31"
symbols = "CARBON_INT_FR"

data = get_timeseries(start, end, symbols, api_key)
if not data.get("success", False):
# Mirrors the real error envelope for CARBON_INT_FR when unavailable
print(f"Query failed: {data.get('error')}", file=sys.stderr)
sys.exit(2)

intensity = parse_carbon_intensity(data)
if intensity is None:
# Present but not directly scalar, or missing; log for inspection
print("CARBON_INT_FR not in rates or not a scalar. Inspect envelope:", file=sys.stderr)
print(json.dumps(data, indent=2))
sys.exit(3)

# Units are gCO2/kWh for CARBON_INT_FR
print(f"France carbon intensity: {intensity} gCO2/kWh")

if __name__ == "__main__":
main()

Notes:

  • This example reads only documented fields and never assumes a currency conversion path for intensity.
  • If you later expand to multiple symbols, keep symbol-level checks and avoid assuming all keys exist in rates/dates/currencies.
  • If you need a specific date selection policy for nested-by-date structures, implement it explicitly in parse_carbon_intensity after you verify the symbol’s data shape in the catalog.

Working with dates, units, and operational details

Units:

  • CARBON_INT_FR values should be interpreted as gCO2/kWh.
  • Do not convert via currency fields; intensity is not monetary. currencies may still appear for schema consistency; treat it as metadata.

Dates and time windows:

  • start and end are inclusive date boundaries in YYYY-MM-DD format, per the time series endpoint.
  • If the API returns a single snapshot effective date for a query window, refer to the dates map for the symbol to align your caching or indexing.
  • If you run historical backfills, iterate by month or quarter to keep query strings readable and logs manageable.

Caching and retries:

  • Cache success=false envelopes for a short period so your scheduler avoids tight retry loops when a symbol is unavailable.
  • Log the entire envelope on failure to preserve the exact error string; your runbooks can then key off of it.
  • When the symbol becomes available, promote your cache invalidation to refetch the previously failed windows.

Pagination:

  • If the documentation indicates pagination for large windows, follow it; otherwise, keep windows modest and parallelize across dates where safe.

Mixed symbols and base currency:

  • Do not pass base=USD when you also need TTF_GAS or EUA_CO2 per catalog guidance.
  • For CARBON_INT_FR alone, a base parameter is unnecessary and should be omitted.

Error handling patterns you can copy

1) Fail-open vs. fail-closed:

  • Fail-closed if CARBON_INT_FR is the only symbol required for the job; exit early on success=false.
  • Fail-open if CARBON_INT_FR is optional: process other symbols in the batch and record the exact failure envelope for later replay.

2) Alert thresholds:

  • Alert when the same success=false error persists beyond N scheduled runs for the same symbol and date window.
  • De-duplicate alerts by including the normalized error string from the envelope as the fingerprint.

3) Input validation:

  • Validate that start and end are calendar dates and that start is not after end before calling the API.
  • For backfills, chunk the date range by month and combine results in your datastore to reduce blast radius on transient failures.

Testing with the official envelopes

Use these exact envelopes as fixtures in unit tests to ensure your parser, logger, and retry logic behave identically to production. The first fixture models “symbol unavailable”; the second models “success with fields present.”

Unavailable fixture (copy exact):

{"success":false,"error":"Symbol CARBON_INT_FR is not currently available. See \/api\/v1\/symbols for the current catalog."}

Success fixture (copy exact):

{
"success": true,
"date": "2026-10-24",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 137.1925
},
"dates": {
"OMIE_ES_DA": "2026-10-24"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}

When CARBON_INT_FR becomes available, add its true envelope to your fixtures without altering the above samples, so you maintain backward compatibility tests for your generic JSON parsing path.

Frequently asked questions

How do I authenticate?

Pass your API key as the api_key query parameter. Use YOUR_API_KEY as the placeholder in examples and replace it with your real key in production.

What unit should I expect for France Carbon Intensity?

gCO2/kWh. Treat it as an intensity metric, not a currency. Do not attempt currency conversion.

Why am I getting a failure response for CARBON_INT_FR?

The symbol may be temporarily unavailable. The real envelope to expect is:

{"success":false,"error":"Symbol CARBON_INT_FR is not currently available. See \/api\/v1\/symbols for the current catalog."}
Check the symbols catalog indicated in the message and retry later.

Can I query multiple symbols in one call?

Yes, pass them comma-separated in symbols. Validate each symbol’s presence in rates, dates, and currencies. If any are unavailable, branch your processing accordingly.

Should I set a base currency?

No for CARBON_INT_FR. If you later add price symbols, follow the catalog guidance and do not pass base=USD when you also need TTF_GAS or EUA_CO2.

Register and ship your integration

Get API access and start testing your time series pipeline with a 7-day trial (50 calls) on the Starter plan at $19.99/mo. Create your key now and run the curl in this guide: Register. For parameter references and schema details, see the Documentation.

Ready to get started?

Get your API key and start querying energy commodity prices in minutes.

Get API Key