REST API · MCP server · OpenAPI 3.1 · free pre-consent check

Cookie consent your coding agent can set up by itself

Connect Claude, Cursor or ChatGPT to PrivacyPill and say “add a GDPR banner to my site”. The agent creates the site, styles the banner, pastes the embed and runs a compliance scan — on your account, with your permission. Checking what a site loads before consent is free and needs no account at all.

Free: what loads before consent

One tool needs no account, no API key and no sign-in: give it a public URL and it reports which trackers and cookies load before the visitor answers the cookie banner, which ones correctly wait, which other sites the page contacts (Google Fonts, CDNs…) and what to change. It's the same check over REST and over MCP (pre_consent_scan), limited to 10 checks per hour per visitor.

REST · GET
curl "https://privacy-pill-consent-studio.lovable.app/api/public/v1/pre-consent-scan?url=https://example.com"
REST · POST
curl -X POST https://privacy-pill-consent-studio.lovable.app/api/public/v1/pre-consent-scan \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/pricing" }'
MCP · tools/call on https://privacy-pill-consent-studio.lovable.app/mcp (no sign-in)
{
  "name": "pre_consent_scan",
  "arguments": { "url": "https://example.com" }
}
Response (shortened)
{
  "final_url": "https://shop.example/",
  "verdict": "fail",
  "summary": "2 trackers and 3 cookies that need consent load on shop.example before the visitor chooses: Google Analytics 4 and Meta Pixel. No consent banner was found in the page's HTML.",
  "counts": { "trackers_before_consent": 2, "cookies_before_consent": 3, "waiting_for_consent": 0, "unclear": 0, "unidentified_cookies": 0, "third_party_hosts": 2 },
  "consent_banner": { "detected": false, "tools": [], "auto_blocking": [] },
  "consent_mode": { "default_denied_found": false, "set_before_google_tags": false, "v2": false },
  "trackers": [
    {
      "id": "meta-pixel",
      "name": "Meta Pixel",
      "category": "marketing",
      "needs_consent": true,
      "status": "loads_before_consent",
      "reason": "Runs on page load: nothing in front of it holds it back until consent.",
      "cookies": ["_fbp"]
    }
  ],
  "cookies": [
    { "name": "_fbp", "category": "marketing", "observed": false, "set_by": "Meta Pixel", "needs_consent": true }
  ],
  "third_party": [
    { "host": "connect.facebook.net", "kinds": ["script"], "service": "Meta Pixel", "needs_attention": true },
    { "host": "www.googletagmanager.com", "kinds": ["script"], "service": "Google Analytics 4", "needs_attention": true }
  ],
  "fixes": [
    "Add a consent banner that blocks trackers until visitors choose. …",
    "Load Meta Pixel only after consent: change its tag to <script type=\"text/plain\" data-pp-category=\"marketing\"> …"
  ]
}

verdict is fail when something that needs consent loads (or a cookie is set) before the visitor chooses, warning when some trackers or cookies can't be confirmed, and pass otherwise. Each tracker has a status:

loads_before_consentRuns on page load with nothing holding it back — a problem under GDPR / ePrivacy.
restricted_by_consent_modeA Google tag that loads after a Consent Mode default of 'denied': no cookies until consent.
blocked_until_consentInert in the HTML (for example type="text/plain") until a consent tool turns it on.
may_be_gated_by_cmpA consent tool that can block or restrict it loads first — confirm in a browser.
via_tag_managerFired from Google Tag Manager, so it depends on the container's consent settings.
unclearMentioned in the page but not as a tag we could see load (often added later by JavaScript).
no_consent_neededStrictly necessary or cookieless.

How it works: we fetch the page once as a first-time visitor and read its HTML, response headers and Google Tag Manager containers. No JavaScript runs, so trackers that other scripts add later may not show up — the report lists its limits. Over the limit you get HTTP 429 with a Retry-After header (MCP: a tool error with the same message). For a full graded report in the browser, use the tracker scanner.

MCP for AI agents

PrivacyPill runs a remote Model Context Protocol server. Connecting needs no account: pre_consent_scan works right away. The first time the assistant uses an account tool, your client asks you to sign in to PrivacyPill and approve access. The assistant then acts as you: it sees only your sites and is bound by your plan's limits. It can't buy plans, see payment details or delete sites.

MCP server URL
https://privacy-pill-consent-studio.lovable.app/mcp
code
claude mcp add --transport http privacypill https://privacy-pill-consent-studio.lovable.app/mcp

Run once. The free check works straight away; account tools ask you to sign in on first use (or type /mcp to manage the connection).

Try asking your agent

  • “Add a PrivacyPill cookie banner to this site in German and English.”
  • “Scan example.com, apply what you find and give me the embed for Webflow.”
  • “Make my banner a bottom bar with our brand teal and rounded buttons.”

MCP tools

ToolWhat it does
pre_consent_scanFree · no sign-inWhich cookies and trackers load on any public page before the visitor consents, and how to fix it.
get_accountYour plan, licenses, site count and limits.
list_sitesEvery site on your account with its domain, plan and site key.
get_siteOne site's banner settings, install status and latest scan.
create_siteCreate a site for a domain, optionally with banner settings.
configure_bannerChange layout, colours, languages, categories or texts.
get_embed_snippetThe one-line embed plus install steps for HTML, GTM, WordPress, Shopify and Webflow.
run_compliance_scanScan the live site for trackers and optionally apply results.
list_banner_presetsBuilt-in colour presets and allowed values.

REST quick start

  1. Create a key under Dashboard → Developers and store it as PRIVACYPILL_KEY.
  2. Create a site with its banner settings.
  3. Fetch the embed snippet and paste it first in your site's <head>.
1 · Create a site
curl -X POST https://privacy-pill-consent-studio.lovable.app/api/public/v1/sites \
  -H "Authorization: Bearer $PRIVACYPILL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "name": "Example shop",
    "design": {
      "preset": "mint",
      "layout": "pill",
      "languages": ["en", "de", "nl"],
      "categories": { "marketing": true, "functional": false }
    }
  }'
2 · Get the embed and per-platform install steps
curl https://privacy-pill-consent-studio.lovable.app/api/public/v1/sites/$SITE_ID/embed \
  -H "Authorization: Bearer $PRIVACYPILL_KEY"
Or from JavaScript
const res = await fetch("https://privacy-pill-consent-studio.lovable.app/api/public/v1/sites", {
  headers: { Authorization: `Bearer ${process.env.PRIVACYPILL_KEY}` },
});
const { sites } = await res.json();

Authentication

Send your key as Authorization: Bearer ppk_… (or an X-API-Key header). Keys act as your account and are shown once — we only store a hash. You can have up to 10 active keys and revoke them any time. Never put a key in browser code; the embed script doesn't need one.

Base URL: https://privacy-pill-consent-studio.lovable.app/api/public/v1

Endpoints

  • GET/pre-consent-scan?url=…Free: which cookies and trackers load before consent · no key needed
  • POST/pre-consent-scanSame check with a JSON body { url } · no key needed
  • GET/accountYour account, licenses and limits
  • GET/sitesList your sites
  • POST/sitesCreate a site, optionally with banner settings
  • GET/sites/{siteId}Get a site and its banner settings
  • PATCH/sites/{siteId}Update the banner, domain, geo-targeting or license
  • DELETE/sites/{siteId}Delete a site
  • GET/sites/{siteId}/embedEmbed snippet + per-platform install steps
  • GET/sites/{siteId}/scansRecent compliance scans of a site
  • POST/sites/{siteId}/scansScan the site now (optionally apply results to the banner)
  • POST/scansScan any public URL for trackers and cookies
  • GET/presetsBanner colour presets and allowed values · no key needed

The design object is a partial patch: send only what you want to change and nested objects (theme, categories, Consent Mode, text overrides) merge into the current settings. Strictly necessary cookies are always on. Use GET /presets to list colour presets and allowed values.

Switch to a bottom bar in your brand colour
curl -X PATCH https://privacy-pill-consent-studio.lovable.app/api/public/v1/sites/$SITE_ID \
  -H "Authorization: Bearer $PRIVACYPILL_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "design": { "layout": "bar", "theme": { "accent": "#0f766e", "radius": 14 } } }'

Compliance scans

Scans fetch the public page, detect common trackers (GA4, Google Ads, Meta Pixel, Hotjar, TikTok, LinkedIn and more) and check whether the PrivacyPill script loads first. Pass "apply": true to switch on the matching cookie categories automatically.

Scan a site and apply the results
curl -X POST https://privacy-pill-consent-studio.lovable.app/api/public/v1/sites/$SITE_ID/scans \
  -H "Authorization: Bearer $PRIVACYPILL_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "apply": true }'

Errors & limits

Errors use normal HTTP status codes (400 invalid input, 401 bad key, 402 plan limit, 404, 409 duplicate domain, 422 page couldn't be fetched, 429 rate limit, 503 briefly unavailable) with a JSON body. Each key can make 1,200 requests an hour; each account can run 30 API scans an hour. The free pre-consent check allows 10 checks per hour per visitor, without a key. Plan limits — like one site on the free plan — apply exactly as in the dashboard.

Error body
{
  "error": {
    "code": "invalid_request",
    "message": "Some fields are missing or invalid.",
    "details": [{ "path": "design.theme.accent", "message": "Invalid string: must match pattern" }]
  }
}

OpenAPI, llms.txt & discovery

Agents can find everything from the domain alone: the API catalog (RFC 9727) links to the OpenAPI spec, these docs and the MCP server card, and the MCP server card is also listed in the AI catalog.

DocumentURL
API catalog (RFC 9727 linkset)/.well-known/api-catalog
OpenAPI 3.1 spec/api/public/v1/openapi.json
MCP server card/mcp/server-card
MCP server card (well-known alias)/.well-known/mcp/server-card.json
AI catalog/.well-known/ai-catalog.json
OAuth protected resource metadata/.well-known/oauth-protected-resource
llms.txt/llms.txt