Config is a key-value store for values that should not live in your codebase: feature flags, banner copy, discount rules, support email addresses.
Reading a value
const flag = await kookee.config.getByKey('feature-new-checkout');
if (flag.value === true) {
// enabled
}
The response shape is minimal — a key and a value. Keys are lowercase letters, numbers and hyphens.
Values are any JSON
This is where Config earns its place. A whole UI configuration fits under one key:
const banner = await kookee.config.getByKey('homepage-banner');
// { text: 'Summer Sale!', enabled: true, color: '#ff6b00' }
Or a business rule your finance team owns:
const discount = await kookee.config.getByKey('pricing-discount');
// { percentage: 20, minOrderValue: 50 }
Grouping related settings into one object also means they change atomically. Three separate keys can be read midway through an edit, giving you a banner with new text and an old color.
Batch your reads
Fetching keys one at a time is the common mistake — every call counts against your rate limit and your monthly requests.
// One request
const configs = await kookee.config.list({
keys: ['homepage-banner', 'feature-new-checkout', 'pricing-discount'],
});
// Every enabled key in the project
const all = await kookee.config.list();
Read config once per server render, or once at client boot, and pass values down. On the Free plan's 300 requests a minute per project and 100,000 a month across all your projects, per-component config reads will exhaust your budget quickly.
Always keep a safe default
An unreachable API should degrade to known-good behavior, not throw on your checkout page:
let showNewCheckout = false; // safe default in code
try {
const flag = await kookee.config.getByKey('feature-new-checkout');
showNewCheckout = flag.value === true;
} catch {
// network hiccup — keep the default
}
Compare explicitly against the type you expect. flag.value === true is safer than a truthiness check, since a value edited to the string "false" is truthy.
Version history
Every change creates a snapshot, and any version from the last 30 days can be restored from the dashboard with one click.
That changes who can safely hold a key. The worst case for a mistyped discount is not an incident and a hotfix — it is a rollback performed by the person who made the mistake, seconds after noticing.
Write a description for every key when you create it. enable-v2 means nothing to whoever inherits it in six months, and Config is searchable by key and description.
Where Config stops
Config is deliberately simple: a key, a value, and history. It has no percentage rollouts, no per-user targeting, no A/B assignment. To show a feature to 5% of users in one country, use a dedicated experimentation platform.
What Config covers is the far more common case — a global value your team needs to change without a deploy. That is most flags, most of the time, and it lives behind the same API key as the rest of your content instead of adding a vendor.
Naming keys
Consistency beats cleverness, since keys are what you search. A prefix convention works well:
feature-*for flags —feature-new-checkoutui-*for presentation —ui-homepage-bannerlimit-*for business rules —limit-free-plan-projects
Prefixes also make list({ keys: [...] }) calls easy to assemble per surface.