Install guide
Two things need to be live on your site: the notice your visitors see, and a small public file that declares your AI use (yoursite.com/.well-known/ai-disclosure.json). The snippet tag is pasted once, is identical on every page, and your declaration decides which notices appear where. Pick your platform below; most take about ten minutes.
Banner and AI labels your visitors see on the page.
ai-disclosure.json, a public file readable from your own domain.
the checker shows Level 2 · Rendered.
Pick your platform
WordPress
Install the plugin
In your WordPress admin: Plugins → Add New → Upload Plugin, choose the file you downloaded below, then click Activate.
Let it do both jobs
The plugin shows the notices and publishes your declaration file automatically. Mark AI content on any post or image with its "AI content" toggle. No code edits.
-
Verify
Done when the checker shows Level 2 · Rendered.
Run the checker
Shopify
Add the snippet
Online Store → Themes → ⋯ → Edit code → theme.liquid: paste this one tag just before </body>. theme.liquid is the layout every page renders through, so one paste covers the store. Shopify cannot host files at your domain root, so the tag carries your AIDisclose site key (data-aidisclose) and loads the manifest we host for you.
theme.liquid <script src="https://cdn.aidisclose.io/v1/aidisclose.js" data-aidisclose="YOUR_SITE_KEY" defer></script>Link your declaration
Paste this link inside <head> in the same file. Your dashboard shows both lines pre-filled with your site key.
<head> <link rel="ai-disclosure" href="https://cdn.aidisclose.io/v1/hosted-manifest/YOUR_SITE_KEY">This is an allowed method under the spec.
-
Verify
Done when the checker shows Level 1 · Declared with a note. That is the expected result on this platform, and it is compliant.
Run the checker
Webflow
Add the snippet
Site settings → Custom code → Footer code: paste the snippet block below, then Publish. Site-level custom code loads on every page.
Footer code <script src="https://cdn.aidisclose.io/v1/aidisclose.js" data-aidisclose="YOUR_SITE_KEY" defer></script>Link your declaration
In Head code, add the declaration link line (second block below). Prefer serving the file from your own domain? Use the proxy under Advanced if your DNS runs through Cloudflare.
Head code <link rel="ai-disclosure" href="https://cdn.aidisclose.io/v1/hosted-manifest/YOUR_SITE_KEY">This is an allowed method under the spec.
-
Verify
Done when the checker shows Level 1 · Declared with a note. That is the expected result on this platform, and it is compliant.
Run the checker
Squarespace
Add the snippet
Settings → Advanced → Code Injection → Footer: paste the snippet block below. Code injection applies to every page. It needs the Business plan.
Footer <script src="https://cdn.aidisclose.io/v1/aidisclose.js" data-aidisclose="YOUR_SITE_KEY" defer></script>Link your declaration
In Header injection, add the declaration link line (second block below).
Header <link rel="ai-disclosure" href="https://cdn.aidisclose.io/v1/hosted-manifest/YOUR_SITE_KEY">This is an allowed method under the spec.
-
Verify
Done when the checker shows Level 1 · Declared with a note. That is the expected result on this platform, and it is compliant.
Run the checker
Google Tag Manager
Create the tag
New tag → Tag configuration → Custom HTML → paste the snippet. Triggering: All Pages (Page View). Do not use a delayed or scroll trigger: disclosure rules require the notice from first exposure. Publish the workspace.
Custom HTML <script src="https://cdn.aidisclose.io/v1/aidisclose.js" defer></script>Publish your declaration too
Tag Manager only handles the notices. Your declaration file still needs to go live: follow the step for your platform in the other tabs, or the Custom code tab if you run your own site.
-
Verify
Done when the checker shows Level 2 · Rendered.
Run the checker
Custom code
Add the snippet
Once in your site template or layout, before </body>, so it ships with every page. Production hardening (version pinning, SRI) is under Advanced.
HTML <script src="https://cdn.aidisclose.io/v1/aidisclose.js" defer></script>Serve the declaration file
ai-disclosure.json must be readable at /.well-known/ on your domain. On Vercel or Netlify, commit the file. If your framework rewrites every route to index.html, that file needs an exception: see Single-page apps under Advanced. nginx and Apache configs are under Advanced too.
Vercel / Netlify # Vercel / Netlify: commit the file public/.well-known/ai-disclosure.json # SPA that rewrites every route to index.html? # Exclude /.well-known/ from the rewrite (see Advanced).-
Verify
Done when the checker shows Level 2 · Rendered.
Run the checker
Verify
Run the checker. It confirms three things: your declaration file is valid, the snippet is running, and the notices actually appear on the page. (For engineers: checks C1, C3, and C4 to C6.)
If your site blocks our checker (AIDiscloseBot)
Scans and evidence captures come from AIDiscloseBot/1.0. It reads public pages only: it never signs in, never submits forms, and obeys robots.txt. If your robots.txt or bot protection blocks unknown crawlers, allow it explicitly:
User-agent: AIDiscloseBot
Allow: /
Is allowing it a risk? No. A robots.txt allow grants no access. It only tells polite bots they may read pages that are already public. Anyone can fake a User-Agent string, but a faker gains nothing your public pages don't already give them.
If you gate traffic with a WAF or bot manager, never allowlist on User-Agent alone. Pair it with source verification. We publish our crawler identity, and the egress IP ranges as they are provisioned, at aidisclose.io/bot.json.
Advanced
Theming with CSS variables, custom copy, single-page-app setup, and the full option reference are in the snippet reference.
Lock the script to an exact version (SRI)
An integrity hash in the script tag makes the browser refuse to run a modified file. Pin the versioned URL and generate the hash from the exact file you deploy:
curl -sO https://cdn.aidisclose.io/v1/aidisclose.js
openssl dgst -sha384 -binary aidisclose.js | openssl base64 -A
Serve the file yourself (nginx / Apache)
For servers you control, serve the downloaded ai-disclosure.json directly:
location = /.well-known/ai-disclosure.json {
alias /var/www/site/ai-disclosure.json;
default_type application/json;
add_header Cache-Control "max-age=3600";
}
Alias "/.well-known/ai-disclosure.json" "/var/www/site/ai-disclosure.json"
<Files "ai-disclosure.json">
ForceType application/json
</Files>
Serve the dashboard-hosted file from your own domain
Your server forwards requests for that one address to us: you edit the file in the dashboard, and it still serves from your domain. The dashboard shows these pre-filled with your site key.
location = /.well-known/ai-disclosure.json {
proxy_pass https://cdn.aidisclose.io/v1/hosted-manifest/YOUR_SITE_KEY;
proxy_set_header Host cdn.aidisclose.io;
proxy_ssl_server_name on;
}
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/.well-known/ai-disclosure.json") {
return fetch("https://cdn.aidisclose.io/v1/hosted-manifest/YOUR_SITE_KEY");
}
return fetch(request);
}
};
Single-page apps and static hosts
Frameworks that rewrite every route to index.html, and some static hosts, intercept /.well-known/ai-disclosure.json and return your app's HTML with a 200 status. The file looks committed, but the checker reads HTML instead of the manifest. Two fixes: exclude /.well-known/ from the catch-all rewrite so the static file is served with the application/json type, or add data-aidisclose="YOUR_SITE_KEY" to the script tag to load the AIDisclose-hosted manifest and skip serving the file entirely.
# netlify.toml: serve the real file before the SPA fallback
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
force = false # a real file at the path wins over this fallback
# vercel.json: rewrite everything EXCEPT /.well-known to the app
{ "rewrites": [
{ "source": "/((?!\.well-known/).*)", "destination": "/index.html" }
] }