No build tools required. One script tag gives you the full SDK on any HTML page.
Quick start
<script src="https://kookee.dev/sdk/latest.js"></script>
<script>
const kookee = new Kookee({ apiKey: 'your-api-key' });
kookee.blog.list({ limit: 5 }).then(({ data: posts }) => {
console.log(posts);
});
</script>
The SDK is exposed globally as Kookee — the client class itself, so you construct it directly with new Kookee({...}). Every module and method behaves exactly as it does in the npm package.
Setup
Include the script in your <head>, or anywhere before the code that uses it:
<script src="https://kookee.dev/sdk/latest.js"></script>
Then create a client:
<script>
const kookee = new Kookee({
apiKey: 'your-api-key',
});
</script>
Constructor options are the same as the npm package: apiKey, plus the optional baseUrl and timeoutMs. projectId can take the place of apiKey, but only while the project's hosted portal is enabled; see Installing the SDK.
Do not add async to the SDK tag: your inline code below it runs immediately and needs the Kookee global to exist. The plain tag guarantees that. (The chat and consent widgets are different — they mount themselves, so their tags are safe to load with async.)
Anything in a script tag is visible to anyone who views source. That is fine for the Kookee API key — it reads only content you have already published, and its only writes are reactions, chat messages, consent records and the site widget's feedback messages, which stay private until your team reviews them. See API keys and security.
The other Kookee script tags
The SDK is one of three separate builds. They are independent — load only the ones you need:
<!-- The SDK: fetch content and build your own UI -->
<script src="https://kookee.dev/sdk/latest.js"></script>
<!-- The AI chat widget -->
<script async src="https://kookee.dev/chat/latest.js" data-api-key="YOUR_API_KEY"></script>
<!-- The cookie consent widget -->
<script async src="https://kookee.dev/consent/latest.js" data-api-key="YOUR_API_KEY"></script>
The chat widget needs no SDK and no code of its own — see Install the site widget on your website.
Example: rendering blog posts
<div id="blog"></div>
<script src="https://kookee.dev/sdk/latest.js"></script>
<script>
const kookee = new Kookee({ apiKey: 'your-api-key' });
kookee.blog.list({ limit: 10 }).then(({ data: posts }) => {
const container = document.getElementById('blog');
posts.forEach((post) => {
const article = document.createElement('article');
const heading = document.createElement('h2');
heading.textContent = post.title;
article.appendChild(heading);
container.appendChild(article);
});
});
</script>
Building nodes with textContent rather than assembling an HTML string keeps titles safe from breaking your markup.
Example: help center search
<input id="search" type="text" placeholder="Search help articles..." />
<div id="results"></div>
<script src="https://kookee.dev/sdk/latest.js"></script>
<script>
const kookee = new Kookee({ apiKey: 'your-api-key' });
document.getElementById('search').addEventListener('input', async (e) => {
if (e.target.value.length < 2) return;
const results = await kookee.help.search({ query: e.target.value });
const container = document.getElementById('results');
container.innerHTML = '';
results.forEach((result) => {
const link = document.createElement('a');
link.href = '/help/' + result.slug;
link.textContent = result.title;
container.appendChild(link);
});
});
</script>
Search on every keystroke will burn through your rate limit quickly. Debounce the handler by 200–300ms before shipping this.
Versioning
<script src="https://kookee.dev/sdk/latest.js"></script>
latest.js always serves the most recent release.
TypeScript definitions
Types are published alongside the two widget scripts:
Chat widget globals —
https://kookee.dev/chat/latest.d.tsConsent widget globals —
https://kookee.dev/consent/latest.d.ts
Download the one you need for editor autocomplete:
curl -o kookee-chat.d.ts https://kookee.dev/chat/latest.d.ts
If you already install the npm packages, the equivalent types come from them instead:
import type { KookeeChatApi } from '@kookee/react/chat';
import type { KookeeConsentApi } from '@kookee/sdk/consent';
Error handling
The script build exposes only the Kookee class — the KookeeApiError class is not available as a global, so check error.name instead of instanceof:
<script>
const kookee = new Kookee({ apiKey: 'your-api-key' });
kookee.blog
.getBySlug('my-post')
.then((post) => {
console.log(post.title);
})
.catch((error) => {
if (error.name === 'KookeeApiError') {
console.error(error.code, error.message, error.status);
}
});
</script>
When to use the CDN
Good for static HTML sites, quick prototypes, demos, and CMS-hosted pages (WordPress, Squarespace) where you cannot change the build pipeline.
If your project already uses a bundler such as Vite, webpack or Next.js, prefer the npm package — you get tree-shaking and TypeScript support without extra steps.