Privacy Policy
This page explains what personal data is collected when you visit bradshaw.cloud, why, who else is involved, and what rights you have. It's written to be specific rather than boilerplate — what's described here matches what the site actually does.
Last updated: 2 November 2026
Who's responsible (data controller)
The data controller for this site is John Bradshaw, acting in a personal capacity, based in the United Kingdom. This site is a personal site — not an Akamai site — so Akamai Technologies is not the controller of any personal data processed here. See the Legal notice for context.
For any data-protection question or request, get in touch via the channels on the About page and mark your message as a privacy request.
What data the site collects
The site is a static site — there are no user accounts, no comments, and no login. Personal data is only collected in the following narrow ways:
1. Product analytics (PostHog)
The site uses (opens in a new tab)
for analytics, hosted in the EU. Requests are sent to the
first-party subdomain t.bradshaw.cloud, which proxies
PostHog's EU service. The analytics script is configured with
PostHog's defaults: '2026-01-30' preset and exception
tracking enabled (capture_exceptions: true).
That setup collects, on each page view:
- the URL of the page you visited and the referring URL;
- your browser, operating system, device type, and language;
- a coarse approximation of location derived from your IP address (typically country, region, and city); your full IP address is not stored by PostHog;
- autocaptured interaction events (clicks, form interactions, page-leave events) and basic web-vitals performance metrics;
- a randomly-generated identifier stored in a first-party cookie / local storage so repeat visits can be linked into a session.
On top of those defaults, the site emits a number of named custom events to understand which content and call-to-action buttons resonate. The current set includes:
outbound_link_clicked— when you click a link to another site, with the destination URL, the link text (truncated), the section of the site you were on, and (if the link was inside a content card) the card's title and content type;share_clicked— when you use the share bar (X, LinkedIn, Bluesky) or, on a phone, your device's own share sheet, with the channel, the URL being shared, and the page path. The device share sheet is your operating system's, not ours: we record only that you used it, never which app you picked;hero_cta_clicked— when you click a call-to-action button in the homepage hero, with the button label;contact_link_clicked— when you click one of the contact buttons on the About page (LinkedIn, Signal, X);follow_clicked— when you click one of the social profile icons in the site footer (LinkedIn, X, Bluesky), with the channel and the page path;speaking_cta_clicked,speaking_external_link_clicked,speaking_register_clicked,speaking_calendar_downloaded,speaking_recording_clicked— interactions on speaking pages, and with the "book a talk" links on media and writing pages, with the event slug, event title, and (where relevant) the type of link;media_external_link_clicked,media_coverage_link_clicked— when you click through to a media item or one of its syndicated pickups, with the destination and media slug;calculator_cta_clicked,writing_calculator_clicked— when you open an interactive calculator from a strategy insight or a writing post, with the insight slug and the calculator's title;related_link_click— when you follow a related-content card or a "more on this" link (on writing, insight, talk, media and topic pages, the strategy index and the homepage), with the kind of page you were on, the kind of item the link leads to and, where the link carries them, the shared topic, the linked insight's slug, where on the page the link sat and the kind of talk resource, plus the page;topic_hub_click— when you follow a link to a topic page from an insight's topic label, the homepage topic band or the topic chips on the speaking page, with the topic's slug and the page;diagram_downloaded— when you download a diagram from a strategy insight or a writing post, with the diagram's id and title and the insight or post slug;template_downloaded— when you download a worksheet, scorecard or table from a writing post, with the post slug, the file's name and where on the page you chose it (onward, the card at the end of the post, ortable, the bar above a table); never the file's contents;insight_nav_clicked— when you use the previous/next arrows between strategy insights, with the direction and the destination's title;insight_sort_changed— when you change the order of the strategy insights list (by theme or latest first), with the order you chose and the page;insight_scope_click— when you use one of the section links under an insight's title (concepts, decisions, diagrams or calculator), with which one and the page;insight_markdown_click— when you open an insight's Markdown version from the link under its title, with the insight's slug and the page;ai_fundamentals_concept_viewed— when you select a concept tab on the AI Fundamentals insight, with the concept's id and label;search_opened— when you open the site search overlay, with the page path only; what you type into it is never sent;speaking_book_viewed— when you reach the speaker booking page;audio_play,audio_pause,audio_seek,audio_progress,audio_complete,audio_listen,audio_rate_changed,audio_chapter_click,audio_edition_changed,audio_transcript_toggled,audio_download,audio_error— how you use the audio player on a post or insight that has a narration, or on the podcast page: play, pause and seek, the quarter-way points you reach, finishing the episode, how many seconds you actually listened (counted only while it plays, so skipping ahead adds nothing), the playback speed and edition you choose, a chapter you jump to, switching the follow-along highlight, downloading the MP3, and a playback error's code. The playback events carry the page (on the podcast page, also which control started playback and which playlist it was part of), the episode's edition and file identifier, the position and duration in seconds, and the speed; the download event records only the page and the episode — never the audio itself or anything you typed;podcast_subscribe_click— when you use a subscribe button or app link on the podcast page, copy the feed URL, or choose "Subscribe to the podcast" in an audio player, with the directory or app you picked, where on the site you were, and (from a player) the page's slug. Opening a podcast app hands the feed address to that app; we never learn whether you subscribed;podcast_playlist_play— when you start one of the playlists on the podcast page: which playlist, how many episodes it holds, and the page;podcast_read_click— when you follow a link from the podcast page to an episode's written version: which episode, and where on the page the link was;newsletter_form_submitted— when you submit the newsletter form (see below).
New CTA / link-click events of the same kind may be added as new content ships, following the same pattern: an event name, the page or component it fired from, and the URL or label involved — never your identity or any data you didn't submit.
Unhandled JavaScript exceptions and rejected promises are also captured automatically and sent to PostHog's error-tracking feature so production bugs can be diagnosed. Source maps are uploaded as part of deployment so stack traces can be de-minified. Error reports may include the URL where the error occurred, a stack trace, and the browser/device information already listed above.
Content-Security-Policy violations are recorded in PostHog too. The
site's Content-Security-Policy is a browser security rule that blocks
resources the page didn't explicitly allow; when a block happens, a
csp_violation event captures only technical metadata — the
policy directive that fired, the blocked resource's address (its origin
and path, with any query string stripped off), the script location
involved, the page path, and whether the policy was enforcing or only
reporting. It never includes anything you type or any real-world
identity, and is separate from the browser's own violation reports sent
to the site's report collector.
Missing pages and files that fail to load are recorded too, so broken
links and broken deployments can be found and fixed. When you reach
the "Page not found" page, a page_not_found event records
the address you asked for (its path only, with any query string
stripped off) and where you came from: the referring site's name only,
or "direct" if there was none, plus the referring page's path only
when that page is on this site. When an image, script, stylesheet,
font or media file on a page fails to load, a
resource_error event records the kind of element, the
file's address (its origin and path, with any query string stripped
off), whether it is on this site, the HTTP status when your browser
exposes one, and the page path. Only files on this site and the video
thumbnails it shows are reported; a file that a browser extension or
ad blocker stops is not. Neither event includes anything you type or
any real-world identity.
Session replay is enabled. PostHog records a playback of your visit — the pages you move through and how you interact with them — so usability problems can be diagnosed from the visitor's point of view. Every input field is masked, so anything you type (and the contents of password and email fields in particular) is never captured in the recording. Replays are linked only to the anonymous person profile described below, never to your name or email.
Replays also record two technical layers. Anything the page draws
into a <canvas> element — charts and similar
graphics rendered by the site — is captured as it appears on
screen. And whatever is written to the browser's developer console
while the page is open travels with the replay, so a problem can be
seen next to what the code reported at the time. That means
warnings, errors, and diagnostic output from every script running
in the page: the site's own, the third-party services described on
this page, and any browser extension that injects code into it. Neither changes the masking:
what you type into a field is still never captured.
Heatmaps are enabled. PostHog records where on a page you click, how the mouse moves, and how far down you scroll, and aggregates those positions across visitors to show which parts of a page draw attention and which get missed. Like replays, this is linked only to the anonymous person profile described below.
Surveys, feature flags, and PostHog's identification of named individuals are not enabled. PostHog keeps an anonymous person profile, keyed only to the random device identifier stored in your browser, so repeat visits can be measured as returning visitors. It is never linked to your name, email, or any other real-world identity.
2. Newsletter subscriptions (Buttondown)
If you submit the newsletter form, your email address is sent directly to (opens in a new tab), the third-party service that runs the mailing list. The form opens Buttondown's own confirmation page in a new tab. Buttondown becomes the processor for your email address and any analytics data it captures about email opens, clicks, or unsubscribes; their practices are governed by Buttondown's own privacy policy.
We also fire the newsletter_form_submitted analytics event
in PostHog at the moment of submission so we know how many people
signed up from a given page. That event does not include your
email address.
You can unsubscribe from the newsletter at any time using the link in the footer of any email it sends.
3. Speaking inquiries (Typeform)
The Book speaking page embeds an inquiry form operated by (opens in a new tab). Anything you enter into that form — typically your name, email address, organisation, and details of the event you're inviting John to — is submitted directly to Typeform, which stores it as a processor so the inquiry can be read and answered. It is used only to evaluate and respond to your inquiry; it is not added to the newsletter or any other mailing list.
Loading that page also loads Typeform's embed script and renders the form from Typeform's own domains, so your browser connects to Typeform even if you never submit anything. At that point Typeform receives standard request data (such as your IP address and user agent) and may set its own cookies, all governed by Typeform's own privacy policy — independently of this site.
Nothing you type into the form is sent to PostHog: the form renders inside a Typeform iframe, which the session-replay recording described above cannot see into, and no analytics event includes your answers.
4. Hosting and CDN logs
The site is served as static files from Linode Object Storage, fronted by the Akamai content-delivery network, which also handles edge logic such as custom error pages. When you request a page, the CDN and origin storage receive standard HTTP request information — including your IP address, the URL requested, your user agent, and the referring URL — which is processed for the purposes of delivering content, operating the network, and protecting against abuse.
These logs are operated by Linode (an Akamai company) and Akamai respectively as processors. They are not used for site-level analytics and are not joined with the PostHog data described above.
The Akamai delivery configuration also injects
mPulse, Akamai's real-user monitoring tool, into
pages as they are served. mPulse measures how fast pages load for
real visitors and sends those performance timings — together with
standard request metadata such as your IP address, user agent, and
the page URL — to Akamai-operated collection endpoints
(go-mpulse.net / akstat.io). Akamai
processes that data as a processor to monitor and improve delivery
performance; it is not joined with the PostHog analytics described
above.
Embedded third-party content
Some pages embed video players from YouTube (for
recorded talks and interviews). When you load a page containing a
YouTube embed, your browser connects directly to YouTube; YouTube
may set cookies and process your data in line with Google's
privacy policy, independently of this site. We use standard
youtube.com/embed/… URLs and do not control what
YouTube collects via that connection.
A small number of speaking pages embed a LinkedIn post about the event. When you load one of those pages, your browser connects directly to LinkedIn to render the embedded post; LinkedIn may set cookies and process your data in line with LinkedIn's own privacy policy, independently of this site.
The Book speaking page embeds the Typeform inquiry form described above — it is the only page on the site that connects to Typeform.
Share buttons on content pages, and the social profile icons in the site footer, link to X, LinkedIn, Bluesky, and your email client. They are plain links — they only contact those services if you click them.
The audio edition is also intended for a YouTube channel, as uploaded videos. Nothing on this site embeds those videos; any link to the channel on the podcast page is a plain link to YouTube, and only contacts it if you click.
Podcast downloads
The audio edition is available as a podcast feed
(/podcast.xml). In that feed, and only there, each
episode's audio URL is prefixed with
OP3 (the Open Podcast Prefix Project,
op3.dev), an open-source download counter. When a
podcast app fetches an episode it first contacts OP3, which
records an anonymised download — it hashes IP addresses and does
not store them raw — and then redirects the app to the file on
this site. OP3 publishes the resulting counts on a public statistics
page for the show. OP3 is operated independently and processes
that request under its own
privacy policy.
Only the feed carries the prefix. Every link to an episode on this site itself — on the podcast page and wherever a page offers its own episode — uses the direct URL and never passes through OP3.
Once a day, OP3's download records for this show are copied into
this site's PostHog project as podcast_download events,
so podcast-app listening can be counted alongside the audio player
above. Each record carries what OP3 publishes about a download: the
time, the episode, the podcast app and device type, and the
approximate location OP3 derived (country, region, time zone), keyed
to OP3's own pseudonymous audience identifier. OP3's hashed IP
address is not copied, no PostHog person profile is created, and
nothing links these records to your visits to this site.
What the site doesn't do
- It does not show advertising or share data with ad networks.
- It does not sell, rent, or trade any personal data.
- It does not capture what you type — session replay masks every input field.
- It does not run surveys or pop-up questionnaires.
- It does not track you across other websites you visit.
- It does not build a profile of you under a real-world identity — the anonymous PostHog person profile described above is keyed only to a random device identifier, never your name or email.
Cookies and similar technologies
The only cookie / local-storage entry set directly by this site is
the PostHog identifier described above, stored as a first-party
item on the bradshaw.cloud domain. It is used to group
your page views into sessions and to recognise repeat visits for
analytics purposes, and is not used for advertising.
The audio player on posts and insights that carry a narration keeps
your resume position and chosen playback speed per episode in the
browser's localStorage, on this domain only, so an
episode you leave half-way picks up where you stopped. It holds no
identifier and is never sent anywhere; clearing site data removes
it, and the player works without it.
The mPulse monitoring described above runs
cookie-less: its Boomerang script can set a
first-party RT cookie to carry timing state between
page loads, and that is switched off in our configuration, so it
sets no cookie and no local- or session-storage entry on this
domain. Each measurement is sent on its own, with no identifier
stored in your browser to link one page view to the next.
Embedded YouTube players and LinkedIn posts may set their own cookies on their respective domains when they load or when you interact with them, and the embedded Typeform form on the Book speaking page may set its own cookies on Typeform's domains. The site does not control those cookies.
Most browsers let you block or delete cookies and local-storage
entries from their settings. PostHog also exposes a programmatic
opt-out: running posthog.opt_out_capturing() from your
browser's developer console disables analytics for the current
browser. mPulse has no equivalent switch, but it is loaded from
go-mpulse.net, so a content blocker or a DNS filter
that blocks that domain stops it running — the site works normally
without it. The site does not currently auto-honour Do Not
Track or Global Privacy Control headers; if
you'd like that added, please get in touch.
Legal basis for processing (UK GDPR / EU GDPR)
For visitors in the UK or the EEA:
- Analytics, error tracking, and the related first-party identifier are processed on the basis of our legitimate interest in understanding which content people find useful and in keeping the site working correctly. The processing is limited to what's necessary for those purposes, no profiles under a real-world identity are built, and you can opt out as described in the Your rights section below.
- Newsletter subscription is processed on the basis of your consent, given by submitting the form. You can withdraw consent at any time by unsubscribing.
- Speaking inquiries are processed because the processing is necessary to take steps at your request before entering into a possible speaking engagement and, where that doesn't strictly apply, on the basis of our legitimate interest in reading and answering messages sent to us. You choose what to include in the form.
- Hosting, CDN logs, and mPulse performance monitoring are processed on the basis of legitimate interest in delivering the site quickly and reliably and protecting it from abuse, and (for security-related processing) the legitimate interest of network operators in maintaining service integrity.
How long data is kept
- Analytics events: retained in PostHog for as long as needed to spot trends in site usage — typically up to PostHog's default retention window. Aggregated data may be kept longer.
- Error-tracking data: typically retained for a shorter period sufficient to diagnose and fix bugs.
- Session replays, including their canvas and console capture: deleted after 30 days.
- Newsletter subscriber data: kept by Buttondown until you unsubscribe (or you ask for it to be deleted).
- Speaking-inquiry submissions: kept in Typeform (and in any follow-up correspondence) for as long as needed to handle the inquiry and any engagement that comes out of it, and deleted on request.
- Hosting and CDN logs: retained according to Linode's and Akamai's standard operational retention periods.
International transfers
PostHog data is processed on PostHog's EU infrastructure. Buttondown is based in the United States; when you subscribe to the newsletter, your email address is transferred to the US under the safeguards provided by Buttondown's terms (which typically include the EU Standard Contractual Clauses for any onward transfers from the UK / EEA). The speaking-inquiry form is operated by Typeform S.L., based in Barcelona, Spain; where Typeform or its sub-processors handle data outside the UK / EEA (parts of Typeform's infrastructure run in the United States), the transfer is covered by the safeguards described in Typeform's privacy policy, which include the EU Standard Contractual Clauses. Akamai and Linode operate global networks; CDN edge nodes outside the UK / EEA may briefly process your request data to deliver content from the nearest location.
Your rights
If UK or EU data-protection law applies to you, you have the right to:
- access the personal data we hold about you;
- have inaccurate data corrected;
- have your data erased (where the legal basis allows);
- restrict or object to processing (including objecting to analytics processing carried out on the basis of legitimate interest);
- withdraw consent at any time, where consent is the legal basis;
- receive your data in a portable format, where applicable;
- complain to a supervisory authority. In the UK that is the Information Commissioner's Office (opens in a new tab); in the EEA, the supervisory authority of the country where you live or work.
To exercise any of these rights, contact us via the channels on the About page. Because the site does not identify individual visitors by name, fulfilling an access or erasure request usually requires you to supply enough information for us to locate the relevant data (for example, the date range and approximate IP range you used, or the email address you subscribed with).
Children
This site is aimed at a professional adult audience and is not directed at children. We do not knowingly collect personal data from anyone under 16.
Changes to this policy
Material changes to this Privacy Policy will be reflected by updating the "Last updated" date at the top of this page. If a change is significant — for example, the introduction of a new third-party service that collects personal data — we will try to flag it more prominently before it takes effect.