# GPC Support Auditor (`phoenix2810/gpc-support-auditor`) Actor

Audit a public domain's Global Privacy Control support resource at /.well-known/gpc.json against the W3C GPC specification. Validates JSON structure, the required gpc boolean member, and the optional lastUpdate field.

- **URL**: https://apify.com/phoenix2810/gpc-support-auditor.md
- **Developed by:** [Sanskar Jaiswal](https://apify.com/phoenix2810) (community)
- **Categories:** Developer tools, SEO 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

## GPC Support Auditor

Audits a public domain's Global Privacy Control (GPC) support resource at `/.well-known/gpc.json` against the [W3C Global Privacy Control specification](https://w3c.github.io/gpc/). GPC is a browser-sent signal (the `Sec-GPC` header, backed by California, Colorado, Connecticut, and other US state privacy laws) that communicates an opt-out preference. The support resource lets an origin declare, in machine-readable form, whether it respects that signal.

### Use cases

- Privacy and legal teams verifying their own GPC support declaration before a compliance audit.
- Compliance teams checking vendor and portfolio-company GPC disclosure as part of CCPA/CPRA or state privacy-law due diligence.
- Agencies and consultants auditing GPC support resource rollout across a client portfolio.
- Ad-tech and data-broker compliance teams sampling GPC declarations across sites.
- CI/CD pipelines validating `/.well-known/gpc.json` 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`. |
| `timeoutSeconds` | integer | no | 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. |
| `gpcJsonUrl` | string | The `/.well-known/gpc.json` URL that was requested. |
| `finalUrl` | string | The final URL after following any redirects. |
| `crossOriginRedirect` | boolean | Whether the final URL is on a different host than the requested domain (the spec explicitly allows this). |
| `https` | boolean | Whether the resource was served over HTTPS. |
| `status` | integer|null | Final HTTP status code. |
| `contentType` | string|null | `Content-Type` response header value. |
| `jsonValid` | boolean | Whether the body parses as valid JSON. |
| `parseError` | string|null | JSON parse error message, if any. |
| `gpcValue` | boolean|null | Raw value of the `gpc` member, if present. |
| `gpcValid` | boolean | Whether `gpc` is a valid boolean per spec. |
| `lastUpdate` | string|null | Raw value of the `lastUpdate` member, if present. |
| `lastUpdateValid` | boolean | Whether `lastUpdate` is a valid RFC3339 full-date or date-time. |
| `unknownMembers` | array | JSON object keys not defined by the spec (informational only; the spec says these must be ignored). |
| `supportStatus` | string | Overall determination per spec: `supports`, `does-not-support`, or `unknown`. |
| `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",
  "timeoutSeconds": 10
}
```

### Example output

```json
{
  "inputDomain": "https://example.com",
  "gpcJsonUrl": "https://example.com/.well-known/gpc.json",
  "finalUrl": "https://example.com/.well-known/gpc.json",
  "crossOriginRedirect": false,
  "https": true,
  "status": 200,
  "contentType": "application/json",
  "jsonValid": true,
  "gpcValue": true,
  "gpcValid": true,
  "lastUpdate": "2025-04-15",
  "lastUpdateValid": true,
  "unknownMembers": [],
  "supportStatus": "supports",
  "score": 100,
  "grade": "A+",
  "issues": [],
  "recommendations": ["GPC support resource looks spec-conformant. Re-run this audit after changing privacy practices to catch regressions."]
}
```

### What the spec requires

Per the W3C GPC specification's "GPC Support Resource" section:

- The resource lives at `/.well-known/gpc.json` relative to the origin, per RFC 8615.
- The response must use the `application/json` media type and the body must be a JSON object; otherwise support is `unknown`.
- A `gpc` member is required and must be the literal boolean `true` or `false`; any other value makes support `unknown`.
- A `lastUpdate` member is optional and, if present, must be an RFC3339 full-date (`YYYY-MM-DD`) or date-time; an invalid format makes the update time `unknown`.
- Other JSON members have no defined meaning and must be ignored by consumers (surfaced here only as `unknownMembers` for visibility).
- The spec explicitly allows the resource to be served via redirect, possibly to another origin; this actor follows redirects and reports when the final host differs from the requested domain.

### 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, including bracketed IPv6 literals) 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 before the next request is made.
- Response bodies are capped at 64 KB.
- Only `/.well-known/gpc.json` on the audited origin (and its declared redirect targets) is ever fetched; no other site links 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 Global Privacy Control?** A browser-sent opt-out signal (`Sec-GPC` header) that lets users communicate a do-not-sell/do-not-share preference recognized under CCPA/CPRA and several other US state privacy laws.

**Why does a GPC support resource matter if the browser already sends the signal?** The support resource is a separate, origin-published declaration of whether the site's pages respect GPC requests at all. It helps researchers, regulators, and compliance teams verify stated support without having to test every page.

**Does `supportStatus: "unknown"` mean the domain ignores GPC?** No. It means the support resource could not be read or validated as described by the spec. The domain's actual page-level behavior in response to the `Sec-GPC` header is not evaluated by this actor.

**Does this actor send the `Sec-GPC` header or test opt-out behavior?** No. It only fetches and validates the static `/.well-known/gpc.json` declaration resource. It does not simulate a GPC-enabled browser or test whether data-sharing actually stops.

**Why did it report a cross-origin redirect?** The GPC specification explicitly permits a GPC support resource to be served via a sequence of redirects, possibly ending at a different origin (for example, a shared compliance subdomain). This is reported for transparency, not flagged as an error.

# Actor input Schema

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

Public domain or URL to audit (e.g. example.com or https://example.com). The actor fetches /.well-known/gpc.json on this origin. HTTP and HTTPS only. Private IP ranges and URL credentials are blocked.

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

Timeout for the HTTP request.

## Actor input object example

```json
{
  "startUrl": "https://example.com",
  "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/gpc-support-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/gpc-support-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/gpc-support-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,phoenix2810/gpc-support-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/e4bdFzZbHh2WcKyt0/builds/wyYpjOJcMd8VVvvvB/openapi.json
