Build your kid brand on KIDIGLOO.
Skip auth, billing, and parental-consent plumbing. Your app does three things: federate login, ask about entitlements, and honor webhooks. KIDIGLOO owns identity, consent, and money.
/developers/kidigloo-integration.md and read §0 then §7 before writing code.Status
What's live vs. the contract
Live is callable today. Contractis the committed target (KIDIGLOO Phase 4–5) — scaffold against it now; shapes won't change.
Mental model
The guardian holds the only credential
The authenticated principal is always the guardian. A child is a data-minimized profile you reference by child_profile_id — never a login. You receive booleans and reason codes, neverthe child's personal data or date of birth.
entitled =
household has an active entitlement for (tenant, feature)
AND the guardian GRANTED per-child consent for this tenant
AND the child's age_band satisfies the minimum
AND no blocking request
ELSE false // default-deny, even if the household paysguardian pairwise sub, household_id, locale, entitled, reason, age_band, consent_status.
child name, date of birth, precise age, child email/password (they don't exist), Stripe internals, sibling data, consent records.
Integration
Three surfaces, that's it
1 · Sign in with KIDIGLOO (OIDC)
Authorization code + PKCE. Use OIDC discovery — don't hardcode endpoints. Thesub is pairwise (unique to your client). The ID token carries identity only (no child/consent/entitlement claims).
export const { GET, POST } = kidigloo.auth.nextHandler({
scopes: ["openid", "kidigloo.household", "kidigloo.entitlements"],
afterSignIn: "/select-child",
});2 · Entitlements API
The single source of revocable truth. Opaque bearer token, introspected per request. Re-check per gating decision; default-deny.
const { entitled, reason } = await kidigloo.entitlements.check({
childProfileId, // from your session, set after /select-profile
feature: "nook.plus",
});
if (!entitled) {
// reason ∈ "consent_pending" | "no_entitlement" | "age_band_blocked" | ...
redirect(kidigloo.subscribeUrl({ feature: "nook.plus", returnTo }));
}3 · Webhooks
KIDIGLOO POSTs signed events on every consent / entitlement / graduation change. Verify, be idempotent, re-resolve on revocation, merge accounts on graduation.
const event = await kidigloo.webhooks.verify(req); // throws on bad signature
switch (event.type) {
case "consent.revoked":
case "entitlement.revoked":
await invalidateAccess(event.data.child_profile_id, event.data.feature_key);
break;
case "profile.graduated":
await mergeAccount(event.data.old_sub, event.data.new_sub);
break;
}SDK
AI-first by design
The SDK makes integration a trivial, autocomplete-driven task — for humans and AI agents. One typed client, verb-first methods, discriminated-union returns that never throw for expected states, and fail-closed defaults.
import { Kidigloo } from "@kidigloo/sdk";
export const kidigloo = new Kidigloo({
clientId: process.env.KIDIGLOO_CLIENT_ID!,
clientSecret: process.env.KIDIGLOO_CLIENT_SECRET!,
webhookSecret: process.env.KIDIGLOO_WEBHOOK_SECRET!,
baseUrl: process.env.KIDIGLOO_BASE_URL ?? "https://kidigloo.com",
});- ▸One client, fully typed + JSDoc — discoverable via autocomplete
- ▸Verb-first, namespaced: kidigloo.entitlements.check(...)
- ▸Returns { entitled, reason } — never throws for a non-consented child
- ▸Fail-closed defaults (entitled = false)
- ▸Web-standard Request/Response — Node, Edge, Bun, Workers
- ▸Self-describing errors with code + hint (a next_action for agents)
- ▸Machine-readable companions: OpenAPI, llms.txt, raw markdown
- ▸No hidden global state — config is explicit
Until @kidigloo/sdk is published, the full spec gives the raw REST equivalents for every method.
Quickstart
Wire your app in 5 steps
- 1Register as a tenantGet client id/secret, set redirect + webhook URLs, declare your feature keys, sign the DPA. Email support@quarlabs.com.
- 2Add the login routeReplace local password login with “Sign in with KIDIGLOO” (OIDC).
- 3Add the child pickerRedirect to /select-profile; store the returned child_profile_id in your session.
- 4Gate every protected routekidigloo.entitlements.check(...) — default-deny; send non-entitled users to subscribe.
- 5Add the webhook handlerVerify, be idempotent, re-resolve on revocation, merge on graduation.
Contract
Rules for AI agents (non-negotiable)
Reference
Environment variables
KIDIGLOO_CLIENT_IDyesfrom tenant registrationKIDIGLOO_CLIENT_SECRETyessecret — env only, never commitKIDIGLOO_WEBHOOK_SECRETyesHMAC key to verify webhook signaturesKIDIGLOO_REDIRECT_URIyesmust match the registered URIKIDIGLOO_BASE_URLnodefaults to https://kidigloo.com