Skip to content
← Public packages

@kentcdodds/kit

Kit.com helpers for subscribers, tags, forms, sequences, and broadcasts.

AGENTS.md

118 lines · 3.8 KB · Markdown

@kentcdodds/kit — agent notes

Human setup and intent live in README.md. This file is for agents: imports, smoke checks, snippets, and edge cases. Secrets by name only — never paste key values. Do not disable live webhooks or jobs.

Secret

  • Name: kitApiKey (user scope)
  • Host: api.kit.com
  • Header: X-Kit-Api-Key (Kit v4 does not accept Bearer)

Import paths

ExportImport
root (createBroadcastDraft)kody:@kentcdodds/kit
create-broadcast-draftkody:@kentcdodds/kit/create-broadcast-draft
subscribe-and-tagkody:@kentcdodds/kit/subscribe-and-tag
list-broadcastskody:@kentcdodds/kit/list-broadcasts
named barrelkody:@kentcdodds/kit/named
smoke-testkody:@kentcdodds/kit/smoke-test

Prefer focused paths when one exists. Prefer static kody:@kentcdodds/kit/... imports from execute. Do not lead with packages.invoke.

Smoke test (read-only)

import smokeTest from 'kody:@kentcdodds/kit/smoke-test'

export default async function main() {
	return await smokeTest()
	// => { ok: true, account: { name }, broadcastCount, sampleBroadcast }
}

Run this before any writes to confirm secret + host approval.

Common snippets

Waitlist subscribe + tag:

import subscribeAndTag from 'kody:@kentcdodds/kit/subscribe-and-tag'

export default async function main() {
	return await subscribeAndTag({
		email_address: 'person@example.com',
		first_name: 'Ada',
		tagName: 'waitlist::kody',
	})
}

Draft broadcast (never sends):

import createBroadcastDraft from 'kody:@kentcdodds/kit'

export default async function main() {
	return await createBroadcastDraft({
		subject: 'Product Engineering Workshop',
		content: '<p>Workshop details go here.</p>',
	})
	// => { id, status: 'draft', editUrl, ... }
}

List recent broadcasts — always pass maxItems:

import listBroadcasts from 'kody:@kentcdodds/kit/list-broadcasts'

export default async function main() {
	return await listBroadcasts({ maxItems: 10 })
}

BWK YouTube episode draft (required helper / defaults):

import { createBwkYoutubeBroadcastDraft } from 'kody:@kentcdodds/kit/named'

export default async function main() {
	return await createBwkYoutubeBroadcastDraft({
		subject: 'Episode title',
		preview_text: 'Short preview',
		description: 'BWK 12-slug YouTube early access',
		thumbnail_url: 'https://i.ytimg.com/vi/VIDEO_ID/maxresdefault.jpg',
		content:
			'<p>{% if subscriber.first_name != blank %}Hey {{ subscriber.first_name }},{% else %}Hey friend,{% endif %}</p>',
	})
}

Edge cases

  • Broadcast helpers are draft-only. Never claim a broadcast was sent. Destructive: deleteBroadcast, unsubscribeSubscriber, untagSubscriber.
  • subscribeAndTag and active sequences write live audience data — use test addresses when experimenting. Active sequences with delay_value: 0 email immediately.
  • Always pass maxItems on exploratory list/pagination helpers or execute can time out paging the full history.
  • Templates (KIT_TEMPLATES): textOnly (684651, account default), epePodcast (5215129), betterWithKent (5341436). Verify ids in Kit UI before relying on new ones.
  • BWK YouTube drafts: do not call bare createBroadcastDraft. Use createBwkYoutubeBroadcastDraft or copy BWK_YOUTUBE_BROADCAST_DEFAULTS. Required: email_address hello@kentcdodds.com, template KIT_TEMPLATES.betterWithKent, public: false, and mute filter excluding KIT_MUTE_TAGS.betterWithKentYoutube (20860981). After create/update, verify with getBroadcast(id).
  • Cross-package import: if another package imports this one, kitApiKey must also be approved for the calling package (secrets UI → allowed packages). Ad hoc execute is unaffected.
  • Failures throw KitApiError with status, body, method, path.