# Carbon.txt Auditor (`phoenix2810/carbon-txt-auditor`) Actor

Discover and audit a public domain's carbon.txt sustainability disclosure file (Green Web Foundation spec v0.5). Checks discovery, TOML validity, disclosures, upstream services, score, and grade.

- **URL**: https://apify.com/phoenix2810/carbon-txt-auditor.md
- **Developed by:** [Sanskar Jaiswal](https://apify.com/phoenix2810) (community)
- **Categories:** SEO tools, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Carbon.txt Auditor

Discover and audit a public domain's `carbon.txt` sustainability disclosure file against the [Green Web Foundation carbon.txt v0.5 syntax](https://carbontxt.org/syntax). Carbon.txt is the emerging standard for publishing machine-readable sustainability data disclosures (carbon footprint, energy mix, CSRD reports, AI model cards) at a predictable location on a domain.

### Use cases

- Sustainability and ESG teams verifying their own carbon.txt deployment before a public announcement.
- Compliance and legal teams auditing CSRD-related disclosure publication readiness.
- Agencies and consultants running carbon.txt audits across a client portfolio.
- Procurement and investor-research teams checking whether a vendor or portfolio company publishes verifiable sustainability disclosures.
- CI/CD pipelines validating a carbon.txt file after edits, before deployment.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `startUrl` | string | yes | Domain or URL to audit, e.g. `example.com` or `https://example.com`. |
| `checkDisclosureUrls` | boolean | no | If `true`, performs a reachability check (HEAD, falling back to a capped GET) against each disclosure URL found in the file. Default `false`. |
| `timeoutSeconds` | integer | no | Per-request timeout, 3-30 seconds. Default `10`. |

### Output

One JSON object per run, pushed to the default dataset.

| Field | Type | Description |
|---|---|---|
| `inputDomain` | string | The domain/URL provided as input. |
| `discoveryMethod` | string | How the file was located: `dns-txt`, `root`, `well-known`, `header`, or `none`. |
| `carbonTxtUrl` | string|null | URL the carbon.txt file was fetched from, if found. |
| `https` | boolean|null | Whether it was served over HTTPS. |
| `status` | integer|null | Final HTTP status code. |
| `fileFound` | boolean | Whether any discovery method succeeded. |
| `tomlValid` | boolean | Whether the body parses as valid TOML. |
| `parseError` | string|null | TOML parse error message, if any. |
| `version` | string|null | Declared `version` field. |
| `lastUpdated` | string|null | Declared `last_updated` field. |
| `hasOrgSection` | boolean | Whether a required `[org]` table is present. |
| `disclosureCount` | integer | Number of `org.disclosures` entries. |
| `disclosures` | array | Parsed disclosure entries: `docType`, `url`, `validUntil`, `domain`, `title`, `issues`. |
| `hasUpstreamSection` | boolean | Whether an optional `[upstream]` table is present. |
| `upstreamServiceCount` | integer | Number of `upstream.services` entries. |
| `upstreamServices` | array | Parsed service entries: `domain`, `serviceType`, `issues`. |
| `disclosureUrlChecks` | array|null | Per-URL reachability results, if `checkDisclosureUrls` was enabled. |
| `checks` | array | Per-check breakdown: `name`, `status`, `note`, `weight`, `recommendation`. |
| `issues` | array | Deduplicated list of all issues found. |
| `score` | integer | Readiness score, 0-100. |
| `grade` | string | Letter grade, `A+` to `F`. |
| `checkedAt` | string | ISO timestamp of the audit. |
| `recommendations` | array | Actionable fixes. |
| `error` | string|null | Top-level fetch error, if any. |

### Example input

```json
{
  "startUrl": "https://example.com",
  "checkDisclosureUrls": true,
  "timeoutSeconds": 10
}
```

### Example output (abridged)

```json
{
  "inputDomain": "https://example.com",
  "discoveryMethod": "root",
  "carbonTxtUrl": "https://example.com/carbon.txt",
  "https": true,
  "status": 200,
  "fileFound": true,
  "tomlValid": true,
  "version": "0.5",
  "hasOrgSection": true,
  "disclosureCount": 1,
  "disclosures": [
    { "index": 0, "docType": "sustainability-page", "url": "https://example.com/sustainability", "validUntil": null, "domain": "example.com", "title": null, "issues": [] }
  ],
  "hasUpstreamSection": false,
  "upstreamServiceCount": 0,
  "upstreamServices": [],
  "score": 90,
  "grade": "A",
  "issues": [],
  "recommendations": ["carbon.txt looks spec-conformant. Re-run this audit after updating sustainability disclosures to catch regressions."]
}
```

### Discovery method

Per the [carbon.txt FAQ](https://carbontxt.org/faq), discoverability is checked in this order:

1. DNS TXT record on the domain in the form `carbon-txt-location=URL`.
2. `https://<domain>/carbon.txt` (domain root).
3. `https://<domain>/.well-known/carbon.txt`.
4. A `CarbonTxt-Location: URL` HTTP response header on the domain root.

The actor stops at the first location that returns a 200 response and attempts to parse it as TOML.

### Security

- Public HTTP/HTTPS only. URL credentials are rejected.
- Localhost and private/link-local IPv4 and IPv6 literal ranges (RFC 1918, RFC 3927, and IPv6 unique-local/link-local equivalents) are blocked.
- Hostnames are DNS-resolved and resolved addresses are re-checked against the same private-range rules before any request is made (SSRF defense in depth).
- Redirects are manually followed and each hop is revalidated with the same SSRF checks.
- Response bodies are capped at 256 KB.
- Only the exact disclosure URLs found inside the carbon.txt file are fetched when `checkDisclosureUrls` is enabled; no other URLs referenced by the file are followed.

### Pricing

| Event | Price (USD) |
|---|---|
| Actor start | $0.005 |
| Domain audited | $0.01 |

Apify takes a 20% platform commission; the operator keeps 80%.

### FAQ

**What is carbon.txt?** An open specification from the Green Web Foundation for publishing machine-readable sustainability disclosure links (carbon footprint reports, energy mix data, CSRD reports, AI model cards) at a predictable location on a web domain.

**Does this actor validate the disclosure document contents?** No. It validates the carbon.txt file's structure and, optionally, that each linked disclosure URL is reachable. It does not parse PDF annual reports or verify the sustainability claims themselves.

**Does it support older carbon.txt syntax versions (pre-0.3)?** The actor validates against the current v0.5 TOML structure (`[org].disclosures`, `[upstream].services`). Older array-of-tables syntax from early drafts is not retro-validated.

**Why didn't it find my carbon.txt file?** Check that it is reachable at the domain root, `/.well-known/`, via a `carbon-txt-location=` DNS TXT record, or via a `CarbonTxt-Location` HTTP header, and that it responds with HTTP 200 over HTTPS.

# Actor input Schema

## `startUrl` (type: `string`):

Public domain or URL to audit (e.g. example.com or https://example.com). The actor checks a DNS TXT discovery record, https://<domain>/carbon.txt, https://<domain>/.well-known/carbon.txt, and a CarbonTxt-Location response header, in that order. HTTP and HTTPS only. Private IP ranges and URL credentials are blocked.

## `checkDisclosureUrls` (type: `boolean`):

If enabled, the actor performs a HEAD (falling back to a capped GET) request against each org.disclosures\[].url found in the carbon.txt file to confirm it resolves publicly. Disabled by default to keep runs fast and side-effect free.

## `timeoutSeconds` (type: `integer`):

Timeout for each HTTP request.

## Actor input object example

```json
{
  "startUrl": "https://example.com",
  "checkDisclosureUrls": false,
  "timeoutSeconds": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrl": "https://example.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("phoenix2810/carbon-txt-auditor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrl": "https://example.com" }

# Run the Actor and wait for it to finish
run = client.actor("phoenix2810/carbon-txt-auditor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrl": "https://example.com"
}' |
apify call phoenix2810/carbon-txt-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,phoenix2810/carbon-txt-auditor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/xpG5gDExUlDvSTJzE/builds/PgfaxuqLQvlnjkUsq/openapi.json
