CBAM GN-Code Checker — EU Carbon Border Adjustment Mechanism avatar

CBAM GN-Code Checker — EU Carbon Border Adjustment Mechanism

Pricing

from $3.00 / 1,000 classificatie-resultaats

Go to Apify Store
CBAM GN-Code Checker — EU Carbon Border Adjustment Mechanism

CBAM GN-Code Checker — EU Carbon Border Adjustment Mechanism

Classify or check whether a GN/CN customs code or product falls under CBAM (EU carbon border tax): cement, steel, aluminium, fertiliser, electricity, hydrogen. Bulk-classifies an import list with the 50-tonne threshold in one run, no manual annex lookups. From $0.003/item, PPE.

Pricing

from $3.00 / 1,000 classificatie-resultaats

Rating

0.0

(0)

Developer

Dennis

Dennis

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Share

Check in seconds whether a product falls under CBAM (Carbon Border Adjustment Mechanism, the EU's carbon border tax) by GN/CN customs code or free-text product description — and whether the 2025 50-tonne/year de-minimis threshold applies.

When should an AI agent use this?

  • "Does GN code 7601 10 00 (aluminium bars) fall under CBAM?"
  • "Check whether 'Portland cement' triggers a CBAM obligation."
  • "We import 30 tonnes of steel tubes per year — does the CBAM de-minimis threshold apply?"
  • "Which of these 20 imported product codes are subject to CBAM, and under which category (cement, steel, aluminium, fertiliser, electricity, hydrogen)?"
  • "Is urea (GN 3102 10) covered by CBAM?"
  • "Given a direct GN code, what CBAM category applies and is there a known exception?"

Why this matters

CBAM became financially tangible for the first time in 2026, with a further Omnibus simplification (Regulation (EU) 2025/2083) in effect since October 2025 that introduced a new cumulative 50-tonne/year de-minimis threshold — replacing the old per-shipment €150 rule. Checking whether a specific customs code is in scope, and whether your import volume clears the new threshold, is a recurring compliance task for every importer of steel, aluminium, cement or fertiliser.

What this Actor does

  • Maps a GN/CN customs code (or a free-text product description as fallback) to 1 of 6 CBAM categories: cement, iron & steel, aluminium, fertilisers, electricity, hydrogen
  • Matches hierarchically: a full 8-digit code matches if its 4-digit heading is listed, exactly like the real CBAM scope rules work
  • Applies the 50-tonne/year cumulative de-minimis threshold (2025 Omnibus simplification) when a quantity is supplied — correctly excluded for electricity and hydrogen, which have no such exemption
  • Flags a known explicit exclusion (GN 3105 60 00 — phosphorus/potassium-only fertiliser, no nitrogen)
  • Handles the one code whose outcome depends on the product rather than the code: GN 2507 00 80 (kaolinic clay) sits in Annex I with an ex caveat since the 2025 Omnibus ("except non-calcined kaolinic clays") — calcined kaolin is in scope, non-calcined is not. Set kleiGecalcineerd for a definitive answer, or get an explicitly conditional one
  • Flags match confidence (hoog/middel/laag) per result — some codes have nuances (partial heading coverage, recent scope changes) that this Actor shows honestly instead of pretending certainty
  • Supports bulk classification of an entire import list in one run
  • 100% static rule engine — no scraping, no external API calls at runtime

What this Actor does NOT do

It does not check whether a trading partner is a registered/authorised CBAM declarant. The official EU CBAM Registry (Authorisation Management Module) is a closed system, accessible only via EU Login to registered importers/customs representatives and national authorities — there is no public API or searchable list (verified 2026-07-12). If you need that check, it has to go through your own CBAM Registry access.

Input

FieldTypeDescription
gnCodestringCustoms GN/CN code, e.g. "76011000" or "7601 10 00" (quote it — Apify's input schema requires a string). Matches on the code or any longer code starting with it (heading-level match)
productomschrijvingstringFree-text product description, used as fallback when gnCode is empty or doesn't match
jaarlijkseHoeveelheidTonnumberYour cumulative annual CBAM import quantity in tonnes, for the 50-tonne de-minimis check. No effect on electricity/hydrogen (no exemption)
kleiGecalcineerdbooleanOnly for kaolinic clay (GN 2507 00 80). Since Regulation (EU) 2025/2083 that code is in Annex I with an ex caveat: calcined kaolin is in scope, non-calcined is not. Set it for a definitive status; leave empty for an explicitly conditional one
productenarrayBulk mode: a list of objects with the same fields above (plus an optional label per item)
toonEmissieIndicatiebooleanOptional, separately charged: adds an indicative CO2-intensity range (tCO2e/tonne) per CBAM category when the result is onder_cbam. See "Emission indication" below. Default false

Output

{
"input": { "gnCode": "76011000" },
"genormaliseerdeCode": "76011000",
"matches": [
{
"code": "7601",
"codeTitel": "Aluminium product, heading 7601",
"categorie": "aluminium",
"matchZekerheid": "hoog",
"toelichting": "Hoofdstuk 76-post 7601 (aluminiumproduct) valt onder CBAM. ...",
"zoektermen": "aluminium"
}
],
"status": "onder_cbam",
"toelichting": "Match gevonden met CBAM-categorie(ën): aluminium.",
"disclaimer": "Dit is een indicatieve classificatie ... GEEN juridisch bindend advies.",
"emissieIndicatie": null,
"rapportage": {
"volgendeDeadline": "Jaarlijkse CBAM-aangifte over het voorafgaande kalenderjaar, uiterlijk 30 september ...",
"boeteHint": "Bij het niet of te laat indienen van de CBAM-aangifte, of bij het niet inleveren van voldoende CBAM-certificaten ..."
}
}
  • status: onder_cbam, onder_drempel (matched, but below the 50-tonne threshold), buiten_scope, or onbekend (no usable gnCode/productomschrijving, or an invalid GN-code format — see "GN-code format validation" below)
  • matches: can contain more than one rule for a code (e.g. a heading-level rule plus a more specific sub-code rule), and can even span more than one CBAM category if a code or free-text description genuinely matches more than one (rare, but not excluded)
  • rapportage: a static calendar field — the next CBAM reporting deadline and a generic penalty hint. Only filled when there's an actual CBAM import (onder_cbam or onder_drempel), null otherwise. This is informational, not a per-case legal calculation — see the shared disclaimer field. The deadline is 30 September (first for the 2026 import year: 30 September 2027) and the same date applies to certificate surrender, per Art. 6(1) and 22(1) of Regulation (EU) 2023/956 as amended by Regulation (EU) 2025/2083. From 2027 you must also hold at least 50% of the accrued embedded emissions as certificates at every quarter-end (Art. 22(2)) — you cannot defer all purchases to the annual deadline.

GN-code format validation

gnCode is normalised by stripping everything except digits, so "7601 10 00" and "76011000" are equivalent. It has to be sent as a JSON string: Apify's input-schema validator rejects a string-or-number field, so there is no way to declare the code as accepting both. The Actor's own validation layer does accept a number, so a direct call that bypasses the platform schema still works.

Only a result of 2, 4, 6 or 8 digits (chapter/heading/sub-heading/full breakdown) is treated as a plausible GN/CN code. Anything else — a typo, or digits embedded in unrelated text (e.g. an 11-digit paste error) — returns status onbekend with an explicit "ongeldig GN-code-formaat" explanation instead of being silently prefix-matched against the rule set. This does not fall back to productomschrijving, so a malformed code can't mask itself behind a coincidental free-text match.

Kaolinic clay: the one code where the product decides the answer

GN 2507 00 80 sits in Annex I with an ex caveat. Regulation (EU) 2025/2083, Art. 1(28) replaced the entry with "ex 2507 00 80 – Other kaolinic clays except non-calcined kaolinic clays" — so calcined kaolinic clay is in CBAM scope and non-calcined is not. This is the one code in the rule set whose outcome depends on a property of the product rather than on the code, which is why this Actor asks instead of guessing:

kleiGecalcineerdResult
trueonder_cbam, cement category, normal explanation — the ex caveat does not apply
falsebuiten_scope, no match — the ex exclusion applies
not setonder_cbam with an explanation that leads with the condition, and no emission indication (a cement intensity would be misleading for non-calcined clay, which is out of scope)

Note that a free-text description containing the bare word "klei" (Dutch for clay) does not match any CBAM category — only the specific kaolin terms do. Generic clay products are not in scope.

Emission indication (optional, separately charged)

Set toonEmissieIndicatie: true to add a rough tCO2e/tonne intensity range per matched CBAM category, only when status is onder_cbam. emissieIndicatie is an array — one entry per matched category. In the overwhelming majority of cases a product matches exactly one category, so the array has 1 entry; if a code or free-text description genuinely matches more than one category (rare, but not excluded), every matched category gets its own entry instead of only the first one being shown:

{
"emissieIndicatie": [
{
"categorie": "cement",
"indicatieveTonCo2ePerTonMin": 0.6,
"indicatieveTonCo2ePerTonMax": 0.9,
"toelichting": "Cement/clinkerproductie: circa 0,6-0,9 ton CO2e per ton product, ...",
"disclaimer": "Dit is een GROVE, illustratieve orde-van-grootte ... GEEN officiële EU CBAM-default-waarde ..."
}
]
}

This is a broad, illustrative order-of-magnitude compiled from generally published industry averages — not the official EU CBAM default value (which requires a product/installation-specific calculation under the CBAM implementing regulation). It's meant to give importers a first-order feel for how much certificate costs might weigh, not a number to file with. Always read the disclaimer field on each entry. The separately charged emissie-indicatie-resultaat event is billed once per result regardless of how many entries the array has — the price is unchanged from before this array shape.

Bulk runs (more than 1 product) also get one free summary record at the end, on top of the per-product results — not charged, no extra event:

{
"type": "cumulatieve_samenvatting",
"aantalProducten": 3,
"totaalTonPerCategorie": { "cement": 55, "elektriciteit": 0, "waterstof": 0, "kunstmest": 0, "ijzer_staal": 0, "aluminium": 10 },
"categorieenBovenDrempel": ["cement"],
"drempelTon": 50
}

This makes the 50-tonne de-minimis threshold's cumulative nature (per importer per year, not per shipment — see the FAQ) directly actionable: two products that are each individually onder_drempel can still push a category's cumulative total over the threshold, which this summary flags. elektriciteit and waterstof are never included in categorieenBovenDrempel — the threshold doesn't apply to them at all.

Use cases

  • Importers of steel, aluminium, cement or fertiliser: check new product codes against CBAM before the first shipment
  • Customs/compliance consultants: bulk-classify a client's full import list in one run
  • Procurement teams: flag which new supplier product lines will trigger CBAM reporting
  • AI agents: structured JSON output, ideal as an MCP tool for import-compliance workflows

Pricing

This Actor uses Apify's Pay-Per-Event (PPE) pricing model.

  • Actor Start: $0.00005 (Apify default)
  • classificatie-resultaat: $0.003 per classified product
  • emissie-indicatie-resultaat: $0.006 extra, only with toonEmissieIndicatie enabled and only when the result is onder_cbam

Combined EU compliance scan (manual orchestration suggestion)

These 3 Actors target the same buyer (importers, customs/compliance consultants) and share the same static rule-engine approach, but each classifies against a different legal scope. There is no combined workflow Actor — running them together today means calling each one separately and merging the results yourself (e.g. in an n8n/Make flow, a script, or an AI agent that calls all 3 as tools):

  1. CBAM GN-Code Checker (this Actor) — is this product/GN-code subject to the carbon border tax?
  2. UPV Classificatiechecker — does this same product trigger extended producer responsibility (UPV) obligations?
  3. NIS2 SBI Sector Mapper — does the importing company's SBI sector fall under NIS2 cybersecurity-law scope?

Feeding the same product/company identifiers into all 3 gives a broader "which EU compliance regimes apply to us" picture than any single Actor covers. This is a documentation pointer only, not a built integration — a genuine combined-workflow Actor (shared input schema, single run, merged output) would be a separate product with its own pricing.

Keywords

cbam, carbon border adjustment mechanism, eu carbon tax, gn code, cn code, customs classification, steel, aluminium, cement, fertiliser, compliance, import

  • The GN/CN-code-to-category mapping is compiled from Regulation (EU) 2023/956 Annex I as amended by Regulation (EU) 2025/2083, cross-checked against 2 independent secondary compliance sources (2026-07-12) because the literal EUR-Lex annex text could not be extracted as parseable text during development. Verify against the official EUR-Lex text before relying on this for a filing decision.
  • This is an indicative classification, not legal advice, and it is not a CBAM declarant-registry check (see "What this Actor does NOT do" above).
  • The optional emissieIndicatie is a rough illustrative range, not the official EU CBAM default value and not usable for an actual CBAM filing — see its own disclaimer field.
  • No personal data is processed — only product/customs-code classification data.

FAQ

Q: My GN code didn't match anything — does that mean I'm not covered? A: Probably, but the rule set isn't exhaustive and is based on secondary sources rather than the literal official annex. Verify against the official EUR-Lex text of Regulation (EU) 2023/956 if in doubt.

Q: Does this check if my trading partner is an authorised CBAM declarant? A: No — the official CBAM Registry has no public API or searchable list. This Actor only classifies goods, not counterparties.

Q: What's the 50-tonne threshold? A: Since the October 2025 CBAM Omnibus simplification, importers with less than 50 cumulative tonnes of CBAM goods per year are exempt — replacing the old per-shipment €150 de-minimis rule. It does not apply to electricity or hydrogen.

Q: Why do some results show matchZekerheid: "middel" instead of "hoog"? A: A handful of CBAM headings (e.g. ferro-alloys under 7202, or certain fertiliser sub-codes under 3102/ 3105) are only partially covered at the 8-digit level, or the available secondary sources disagreed on the exact sub-code boundary. This Actor shows that honestly rather than guessing.

Q: GN 2507 00 80 (kaolinic clay) — in or out of scope? A: It depends on the product. Since Regulation (EU) 2025/2083 the Annex I entry reads "ex 2507 00 80 — except non-calcined kaolinic clays", so calcined kaolinic clay is in scope and non-calcined is not. Set kleiGecalcineerd to get a definitive answer; leave it empty and you get an explicitly conditional one.

Changelog

0.4.0

  • Added kleiGecalcineerd input (per run and per bulk product) and made the GN 2507 00 80 (kaolinic clay) answer reflect the real legal position. Regulation (EU) 2025/2083 Art. 1(28) replaced the Annex I entry with "ex 2507 00 80 — except non-calcined kaolinic clays", so calcined kaolin is in scope and non-calcined is not. Before this version the rule's own explanation said the product was excluded while the status still reported onder_cbam and was charged — a contradiction the customer could not resolve. Now kleiGecalcineerd: false → buiten_scope, true → onder_cbam, unset → onder_cbam with the condition as the first sentence. No emission indication is returned for the conditional case, because a cement intensity would be misleading for out-of-scope non-calcined clay.
  • Narrowed the kaolin free-text search terms: the bare term klei (Dutch for clay) is removed, so generic clay product descriptions no longer match the cement category. Only the specific kaolin terms remain.
  • gnCode is now also tolerated as a JSON number by the Actor's own validation layer, instead of failing with a type error. The published input schema keeps a plain string because Apify's schema validator rejects string-or-number fields outright (verified on the platform), so platform callers must still send a quoted code. No pricing change.
  • Related Actors links are now absolute Store URLs instead of repo-relative paths.
  • No pricing change. 13 new tests, 54/54 green.

0.3.3 - Bugfix (rapportageveld)

  • Corrected the rapportage deadline from 31 May to 30 September. The 31 May date came from the original Regulation (EU) 2023/956 and was replaced by the CBAM Omnibus simplification (Regulation (EU) 2025/2083): Art. 6(1) and 22(1) now read "By 30 September of each year, and for the first time in 2027 for the year 2026" — for both the annual declaration and the certificate surrender. Verified against the consolidated text CELEX:02023R0956-20251020 (2026-09-27).
  • Corrected the penalty hint: the indicative "€10-50 per tonne" figure belonged to the 2023-2025 transitional regime and does not carry over to the definitive regime. Art. 26(1) sets the penalty equal to the EU ETS excess-emissions penalty of Art. 16(3) of Directive 2003/87/EC (€100 per tonne CO2e, EICP-indexed), per certificate not surrendered; importing without authorised CBAM declarant status, or exceeding the 50-tonne threshold without that status, is 3-5× that amount (Art. 26(2)).
  • Added the Art. 22(2) quarterly holding requirement (from 2027: at least 50% of accrued embedded emissions held as certificates at every quarter-end) to the deadline text, since deferring all certificate purchases to the annual deadline no longer works.
  • No pricing change. Regression tests added for the deadline and penalty figures.

0.3.2

  • Added a static rapportage field (next CBAM reporting deadline + a generic penalty hint) to each result, filled only when there's an actual CBAM import (onder_cbam/onder_drempel). No pricing change — enrichment of the same result object.
  • emissieIndicatie is now an array (one entry per matched CBAM category) instead of only ever showing the first matched category when a code matched more than one. No pricing change — same already-charged emissie-indicatie-resultaat event, billed once per result regardless of array length.
  • Added GN-code format validation: only 2/4/6/8-digit normalised codes are treated as plausible GN/CN codes; anything else now returns onbekend with an explicit explanation instead of being silently prefix-matched. No pricing change — bugfix on an existing, already-priced event.
  • Expanded the "Related Actors" section with a manual combined-workflow suggestion for UPV Classificatiechecker and NIS2 SBI Sector Mapper. Documentation only, no built integration.

0.3.1 - Bugfix

  • classificatie-resultaat is no longer charged when the result status is onbekend (empty/meaningless request) — the customer received nothing to classify, so they aren't billed for it.

0.3.0

  • Added optional toonEmissieIndicatie input: when the result is onder_cbam, adds an indicative tCO2e/tonne intensity range per CBAM category (illustrative industry-average order of magnitude, not the official EU default value). New charged event emissie-indicatie-resultaat ($0.006), confirmed by the user (2026-07-14).

0.2.0

  • Added a free cumulatieve_samenvatting record at the end of bulk runs (2+ products), totalling jaarlijkseHoeveelheidTon per CBAM category so a cumulative de-minimis breach can be spotted even when every individual product is below the 50-tonne threshold. No pricing change.

0.1.0 - Initial release

  • GN/CN-code and free-text classification against 6 CBAM categories (cement, iron & steel, aluminium, fertilisers, electricity, hydrogen).
  • Hierarchical code matching (heading-level rules match any longer code starting with them).
  • 50-tonne/year cumulative de-minimis threshold (2025 Omnibus simplification), correctly excluded for electricity/hydrogen.
  • Explicit known-exclusion handling (GN 3105 60 00).
  • Bulk classification via the producten input field.
  • Built on the shared shared-rule-engine package (also used by NIS2 SBI Sector Mapper and UPV Classificatiechecker), extended with a new vindMatchesOpCodePrefix function for hierarchical customs-code matching.