GDPR Website Audit Checklist for Dutch Businesses

Steven | TrustYourWebsite · 4 May 2026 · Last updated: May 2026

This GDPR website audit checklist is calibrated for a typical Dutch small or medium business. The walkthrough takes two to three hours if you follow a structured pass. A GDPR audit is not a one-time exercise. Every new plug-in, form or third-party integration can introduce a compliance gap.

The checklist below maps to what the Autoriteit Persoonsgegevens (AP) and the Autoriteit Consument & Markt (ACM) actually look at when they review a Dutch website. Cookie banners, privacy policies, third-party transfers and security headers all sit on their checklist. Yours should match.

Audit overview at a glance

StepWhat to checkWhere to lookTime
1Cookie banner mechanics and pre-load behaviourHomepage in incognito, DevTools Network30 min
2Privacy policy completeness against Art. 13/14Privacy policy page30 min
3Forms (contact, newsletter, checkout)Every public form20 min
4Third parties and data processing agreementsCMS plug-in list, account settings30 min
5Security headers and HTTPSDevTools Network response headers15 min
6Retention periods and deletion routinesCMS settings, server logs15 min
7Breach response procedureInternal documentation20 min

Before you start

You will need access to your website's front end, your CMS admin, your hosting control panel and a list of all plug-ins and third-party services. Open a spreadsheet to track findings. For each item, note pass, fail or investigate. That spreadsheet becomes the audit record.

Always work in an incognito or private browser window. Otherwise existing cookies and consent decisions distort what you see.

Cookies sit at the centre of recent Dutch enforcement. The Telecommunicatiewet article 11.7a governs the consent requirement separately from GDPR. The AP enforces both in tandem when a tracking cookie processes personal data.

Open your homepage in incognito and observe.

  • Is there a banner? If your site loads Google Analytics, Hotjar, Meta Pixel, embedded YouTube or any non-essential tracker, a banner is required.
  • Accept and Reject on the first layer. A banner that only says "OK" or "I understand" is not valid consent. Reject must be present and equally accessible.
  • Equal visual weight. A bright green Accept All against a grey "Manage settings" link fails. The AP has cited this asymmetry repeatedly in its 2024 and 2025 enforcement actions.
  • One click to reject. If accepting takes one click, rejecting must also take one click. Hiding Reject behind a multi-step settings panel is a dark pattern.
  • No cookie wall. Conditioning access to the site on consent is not freely given consent. The Dutch implementation explicitly prohibits this.

Pre-load check

Open DevTools (F12), go to Network, reload the page and do not interact with the banner. Filter on "google-analytics", "facebook" or "hotjar". If those domains receive requests before you click anything, the banner is showing but not blocking. This is the most common technical failure on Dutch websites. Many low-cost cookie plug-ins display a banner without actually deferring scripts.

In DevTools go to Application → Cookies. List every cookie: name, domain, purpose, retention. Categorize:

  • Strictly necessary (session, cart, language). No consent needed.
  • Analytics (_ga, _gid). Consent required.
  • Marketing (_fbp, _gads). Consent required.
  • Functional (live chat, embedded video). Usually consent required.

Compare this list to your cookie statement. Cookies present on the site but missing from the statement mean the statement is inaccurate. The AP cross-references both during a complaint review.

Step 2: Privacy policy review

Open your privacy policy alongside GDPR Articles 13 and 14. For each required element, mark present, missing or vague.

The AP looks specifically for:

  • Controller identity and contact details. Your business name, address and a working contact method.
  • Purpose and legal basis for each processing activity. Not a single blanket statement. Analytics, contact form, newsletter and payment each need separate entries.
  • Categories of personal data. Be specific. "Personal data" is too vague. List names, email addresses, IP addresses, payment details.
  • Recipients. Name your hosting provider, analytics service, email tool, payment processor and any other party that sees the data.
  • Retention periods. Concrete timeframes, not "as long as necessary".
  • Data subject rights. Access, rectification, erasure, restriction, portability, objection. Plus the right to lodge a complaint with the AP via the AP complaint form.
  • Third-country transfers. If you use Google, Mailchimp, Stripe or any US-based processor, state the legal basis for that transfer.

Common failure pattern: template policies that mention services you do not use and omit services you do use. Walk your policy line by line against your actual stack.

Step 3: Forms

Audit each form on your site that collects personal data.

Contact forms

  • Is the privacy policy linked near the submit button?
  • Are you asking only for what you need? A contact form requiring date of birth, gender and home address violates Article 5(1)(c) (data minimisation).
  • Where does the data go? Database, mailbox, third-party service such as Formspark or Typeform. Every destination belongs in the privacy policy.

Newsletter signups

  • Newsletter consent must be separate from terms acceptance. You cannot bundle them in a single checkbox.
  • Boxes must be unchecked by default. Pre-ticked boxes are invalid consent. The EU Court of Justice settled this in Planet49 (C-673/17).
  • Double opt-in is strongly recommended in the Netherlands. It is the simplest defense against complaints.

Checkout

  • Forced account creation has been flagged by the ACM as an unfair commercial practice. Offer guest checkout.
  • Collect only what the transaction requires.
  • Payment data should never touch your servers unless you operate PCI-DSS infrastructure. Use a payment provider's hosted fields.

Step 4: Third parties and data processing agreements

List every external service that sees your visitors' personal data:

  • Hosting provider
  • Email tool (Mailchimp, ActiveCampaign, etc.)
  • Analytics
  • Live chat or helpdesk
  • CDN or security proxy (Cloudflare)
  • Payment provider (Mollie, Stripe, Adyen)
  • Marketing automation
  • A/B testing
  • CRM

For each: do you have a data processing agreement under GDPR Article 28? Major SaaS vendors provide standard DPAs through account settings or legal pages. Sign or accept them and store evidence.

Special case, US transfers. Many tools are US-based (Google, Mailchimp, Stripe, Cloudflare). Since July 2023, the EU-US Data Privacy Framework provides an adequacy decision for certified US companies. Verify the specific vendor is certified. If not, Standard Contractual Clauses plus supplementary measures are required. You should also reconsider the vendor relationship.

The AP issued a €290 million fine against Uber in 2024 for transferring European driver data to US servers without adequate safeguards. This is the largest fine ever issued by the AP. It signals that international transfer compliance is a live enforcement priority, not a theoretical risk.

Want a quick automated check?

Our free website scan automatically checks for common GDPR issues: cookie banner failures, trackers loading before consent, missing security headers and absent privacy policies. You receive a list of fixable findings within minutes.

Step 5: Security headers and HTTPS

GDPR Article 32 requires "appropriate technical and organisational measures". The AP applies a baseline of:

  • HTTPS site-wide. Visit your site over http://. Does it auto-redirect to HTTPS?
  • Valid TLS certificate. Use SSL Labs for a thorough check.
  • HSTS header. Forces browsers to use HTTPS only.
  • Content-Security-Policy. Mitigates XSS attacks.
  • X-Content-Type-Options: nosniff.
  • Referrer-Policy: strict-origin-when-cross-origin.

In DevTools, Network → first request → Response Headers shows what is currently set.

Most data breaches at Dutch SMBs follow two paths: an outdated plug-in (especially WordPress) or a stolen admin password. Patch the CMS and plug-ins monthly. Require two-factor authentication on every admin account.

Step 6: Retention periods

GDPR Article 5(1)(e) requires that data is not kept longer than necessary. In the Netherlands, GDPR retention rules sit alongside fiscal retention obligations.

<figure> <svg viewBox="0 0 600 240" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="retention-fig-title" style={{ maxWidth: '100%', height: 'auto' }}> <title id="retention-fig-title">Dutch retention timeline overview</title> <rect x="10" y="20" width="580" height="200" fill="none" stroke="#cbd5e1" strokeWidth="1" rx="6" /> <line x1="40" y1="180" x2="560" y2="180" stroke="#475569" strokeWidth="2" /> <line x1="40" y1="175" x2="40" y2="185" stroke="#475569" strokeWidth="2" /> <line x1="200" y1="175" x2="200" y2="185" stroke="#475569" strokeWidth="2" /> <line x1="360" y1="175" x2="360" y2="185" stroke="#475569" strokeWidth="2" /> <line x1="560" y1="175" x2="560" y2="185" stroke="#475569" strokeWidth="2" /> <text x="40" y="200" fontFamily="sans-serif" fontSize="11" fill="#475569" textAnchor="middle">0</text> <text x="200" y="200" fontFamily="sans-serif" fontSize="11" fill="#475569" textAnchor="middle">6-12 mo</text> <text x="360" y="200" fontFamily="sans-serif" fontSize="11" fill="#475569" textAnchor="middle">2 yr</text> <text x="560" y="200" fontFamily="sans-serif" fontSize="11" fill="#475569" textAnchor="middle">7 yr</text> <rect x="40" y="50" width="160" height="22" fill="#dbeafe" stroke="#3b82f6" /> <text x="48" y="65" fontFamily="sans-serif" fontSize="12" fill="#1e3a8a">Server logs / IPs</text> <rect x="40" y="80" width="320" height="22" fill="#fef3c7" stroke="#f59e0b" /> <text x="48" y="95" fontFamily="sans-serif" fontSize="12" fill="#78350f">Customer relationship + tail</text> <rect x="40" y="110" width="520" height="22" fill="#dcfce7" stroke="#16a34a" /> <text x="48" y="125" fontFamily="sans-serif" fontSize="12" fill="#14532d">Accounting records (7 years)</text> <text x="20" y="40" fontFamily="sans-serif" fontSize="12" fill="#0f172a" fontWeight="bold">Typical Dutch SMB retention windows</text> </svg> <figcaption>Indicative retention windows. Always check the legal basis per data category.</figcaption> </figure>
Data typeStatutory windowSource
Accounting records7 yearsAlgemene wet inzake rijksbelastingen art. 52
Customer records without bookkeeping relevanceRelationship duration plus a reasonable tail (often 2 years)GDPR Art. 5(1)(e)
Newsletter subscribersUntil unsubscribe, then deleted or anonymisedGDPR Art. 7(3)
Contact form submissionsUntil handled plus a 3-12 month windowGDPR Art. 5(1)(e)
Server logs with IP addressesTypically 6-12 monthsAP guidance

Do you actually have a deletion routine in place? Or only a paper policy? The AP has explicitly cited "retention policy without technical implementation" as an aggravating factor in several cases on its enforcement overview.

Step 7: Breach response procedure

The 72-hour breach notification clock under GDPR Article 33 does not start when you are ready. It starts when a controller becomes aware. A documented procedure beats discovering you do not have one mid-incident.

<figure> <svg viewBox="0 0 620 280" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="breach-fig-title" style={{ maxWidth: '100%', height: 'auto' }}> <title id="breach-fig-title">72-hour breach decision path</title> <rect x="10" y="10" width="600" height="260" fill="none" stroke="#cbd5e1" strokeWidth="1" rx="6" /> <rect x="40" y="30" width="180" height="50" fill="#fee2e2" stroke="#dc2626" rx="6" /> <text x="130" y="55" fontFamily="sans-serif" fontSize="12" fill="#7f1d1d" textAnchor="middle">Incident detected</text> <text x="130" y="72" fontFamily="sans-serif" fontSize="11" fill="#7f1d1d" textAnchor="middle">Clock starts at awareness</text> <line x1="220" y1="55" x2="280" y2="55" stroke="#475569" strokeWidth="1.5" /> <polygon points="280,55 272,51 272,59" fill="#475569" /> <rect x="280" y="20" width="200" height="70" fill="#fef9c3" stroke="#ca8a04" rx="6" /> <text x="380" y="42" fontFamily="sans-serif" fontSize="12" fill="#713f12" textAnchor="middle">Personal data involved</text> <text x="380" y="58" fontFamily="sans-serif" fontSize="12" fill="#713f12" textAnchor="middle">AND likely risk to rights</text> <text x="380" y="74" fontFamily="sans-serif" fontSize="12" fill="#713f12" textAnchor="middle">and freedoms?</text> <line x1="380" y1="90" x2="380" y2="120" stroke="#475569" strokeWidth="1.5" /> <polygon points="380,120 376,112 384,112" fill="#475569" /> <rect x="40" y="140" width="240" height="60" fill="#dcfce7" stroke="#16a34a" rx="6" /> <text x="160" y="160" fontFamily="sans-serif" fontSize="12" fill="#14532d" textAnchor="middle">No risk: log internally</text> <text x="160" y="178" fontFamily="sans-serif" fontSize="11" fill="#14532d" textAnchor="middle">Register in breach log</text> <text x="160" y="192" fontFamily="sans-serif" fontSize="11" fill="#14532d" textAnchor="middle">(Art. 33(5))</text> <rect x="320" y="140" width="240" height="60" fill="#fee2e2" stroke="#dc2626" rx="6" /> <text x="440" y="160" fontFamily="sans-serif" fontSize="12" fill="#7f1d1d" textAnchor="middle">Risk present: notify AP</text> <text x="440" y="178" fontFamily="sans-serif" fontSize="11" fill="#7f1d1d" textAnchor="middle">within 72 hours via</text> <text x="440" y="192" fontFamily="sans-serif" fontSize="11" fill="#7f1d1d" textAnchor="middle">datalekken portal</text> <rect x="320" y="220" width="240" height="40" fill="#fecaca" stroke="#dc2626" rx="6" /> <text x="440" y="245" fontFamily="sans-serif" fontSize="11" fill="#7f1d1d" textAnchor="middle">High risk: also inform data subjects</text> </svg> <figcaption>Decision path under GDPR Art. 33-34 for Dutch controllers.</figcaption> </figure>

Walk through the scenario: a hacker publishes your customer database tomorrow morning. Who do you call first? How do you submit a notification at the AP datalek portal? How do you communicate with affected customers? If you cannot answer these, draft a one-page playbook today. See our 72-hour breach reporting decision tree for a starting point.

Producing the audit record

After the walkthrough you have a spreadsheet of findings. Triage:

  • Fix this week: cookie banner failures, missing privacy policy elements, forms collecting data without disclosure
  • Plan for this month: missing data processing agreements, security header gaps, retention routine implementation
  • Strategic items: vendor changes (for example, migrating from a US tracker to an EU-hosted alternative), CMS upgrades

Save the audit record. In any AP review or complaint, documented audit history demonstrates accountability under GDPR Article 5(2). A quarterly manual audit plus a monthly automated scan is a reasonable cadence for a Dutch SMB.

For a related itemised compliance review, see our GDPR compliance checklist for Dutch businesses.


This article is technical analysis, not legal advice. Consult a lawyer for advice specific to your situation.

Share this article