API Reference
📄 Kit Schema Reference
The complete Bot Kit JSON structure — every field, type, constraint, and example. This is the authoritative reference for what goes into a Bot Kit.
📌Note
You never write Kit JSON by hand — the Canvas serializes it for you. This reference is for understanding what Kitcord stores and executes, and for power users who want to inspect or export their Kit.
🏗️Top-Level Structure
📐Under the hood — DraftKit — TypeScript interface
TypeScript
interface DraftKit {
kitVersion: string; // Semver, e.g. "1.0.0" — the Kit schema version
botId: string; // UUID, stable for the bot's entire lifetime
meta: KitMeta; // Display name and description
expansions: string[]; // Must include "base" — e.g. ["base", "mod"]
packs?: string[]; // Booster pack ids (e.g. ["naughty", "patterns"])
commands: KitCommand[]; // Spell / slash command definitions
events: KitEvent[]; // Trigger / Discord event bindings
timers: KitTimer[]; // Cron-scheduled flows
flows: KitFlow[]; // Logic graphs (may be empty in draft)
database: { // Vault / SQLite schema
tables: VaultTable[];
};
}| Field | Type | Req | Description |
|---|---|---|---|
kitVersion^\d+\.\d+\.\d+$ | string | yes | Semver string for the Kit schema version. Bump when the Kit shape changes. Engine supports current and N-1. |
botIduuid format | string (UUID) | yes | Stable UUID for this bot. Never changes for the lifetime of the bot, even across Kit versions. Generated by Kitcord on bot creation. |
meta{ name, description? } | object | yes | Display metadata. name is required (1–100 chars). description is optional (max 500 chars). |
expansionsMust contain 'base' | string[] | yes | IDs of expansions installed on this bot. App-only validation contract — the Engine ignores this field at runtime. |
packsPack catalog IDs | string[] | no | Booster pack IDs active on this bot. Provides lib.* sparks in flows. |
commandsDefault [] | KitCommand[] | no | Slash command (Spell) definitions. Each maps to a flow via flowId. |
eventsDefault [] | KitEvent[] | no | Discord gateway event (Trigger) bindings. Each maps to a flow via flowId. |
timersDefault [] | KitTimer[] | no | Cron-scheduled flows. Run automatically on the given interval. |
flowsMay be empty for draft | KitFlow[] | yes | The bot's logic as directed graphs. Triggered by commands, events, or timers. |
database{ tables: VaultTable[] } | object | no | Vault schema. Engine creates/migrates on deploy. |
🪄Command (Spell) Schema
TypeScript
interface KitCommand {
id: string; // Pattern: ^[a-z][a-z0-9_]*$ — e.g. "cmd_ping"
name: string; // Pattern: ^[a-z0-9_-]{1,32}$ — Discord slash name
description: string; // 1–100 chars — shown in Discord command picker
flowId: string; // Must reference a flow in flows[]
options?: KitCommandOption[];
requiredPermissions?: DiscordPermissionFlag[];
}
interface KitCommandOption {
name: string; // Pattern: ^[a-z0-9_-]{1,32}$
description?: string; // Max 100 chars
type: 3|4|5|6|7|8|10; // Discord ApplicationCommandOptionType
required?: boolean; // Default false (required options must come first)
sparkType?: "string" | "number" | "boolean";
choices?: { name: string; value: string | number }[];
minValue?: number; // INTEGER / NUMBER only
maxValue?: number; // INTEGER / NUMBER only
minLength?: number; // STRING only
maxLength?: number; // STRING only
}
type DiscordPermissionFlag =
| "KICK_MEMBERS" | "BAN_MEMBERS" | "MANAGE_CHANNELS"
| "SEND_MESSAGES" | "MANAGE_MESSAGES" | "READ_MESSAGE_HISTORY"
| "MANAGE_ROLES" | "MODERATE_MEMBERS" | "ADMINISTRATOR";⚡Event (Trigger) Schema
TypeScript
interface KitEvent {
id: string; // Pattern: ^[a-z][a-z0-9_]*$ — e.g. "evt_member_join"
type: EventType; // One of the supported Discord event type strings
flowId: string; // Must reference a flow in flows[]
label?: string; // Canvas display name (auto-generated if omitted)
filters?: Record<string, unknown>; // Event-specific constraints
}
// Supported filters by event type:
// messageCreate: { ignoreBots: boolean }⏰Timer Schema
TypeScript
interface KitTimer {
id: string; // Pattern: ^[a-z][a-z0-9_]*$
name: string; // Canvas display name
cron: string; // 5-field cron expression (UTC) — "0 9 * * *"
flowId: string; // Must reference a flow in flows[]
}🔗Flow Schema
TypeScript
interface KitFlow {
id: string; // Pattern: ^[a-z][a-z0-9_]*$ — e.g. "flow_welcome"
name: string; // Canvas display name (1–100 chars)
entry: string; // Node id of the first node to execute
nodes: KitNode[];
edges: KitEdge[];
}
interface KitNode {
id: string; // Pattern: ^[a-z][a-z0-9_]*$ — unique within flow
piece: string; // Piece type — e.g. "base.reply", "base.db.read", "mod.kick"
// Pattern: ^[a-z][a-z0-9_-]+\.[a-z][a-z0-9_.-]+$
config: Record<string, unknown>; // Piece-specific; supports {{sparks}}
x?: number; // Canvas X position (cosmetic)
y?: number; // Canvas Y position (cosmetic)
}
interface KitEdge {
from: string; // Source node id (must exist in nodes[])
to: string; // Destination node id (must exist in nodes[])
port?: string; // Output port — "true" | "false" | "default"
// Omit for linear (non-branching) pieces
}🗄️Database (Vault) Schema
TypeScript
interface VaultDatabase {
tables: VaultTable[];
}
interface VaultTable {
name: string; // Pattern: ^[a-z][a-z0-9_]*$ — e.g. "scores"
columns: VaultColumn[];
}
interface VaultColumn {
name: string; // Pattern: ^[a-z][a-z0-9_]*$ — e.g. "user_id"
type: ColumnType;
primaryKey?: boolean; // At most one per table; default false
default?: string | number | boolean; // Optional default value
}
type ColumnType =
| "TEXT" // String data
| "INTEGER" // Whole numbers
| "REAL" // Floating-point numbers
| "BLOB" // Binary data
| "BOOLEAN"; // Stored as INTEGER 0/1 (SQLite convention)✅Validation Rules
Before publishing, Kitcord validates the Kit against all of these rules. Failures block publish and are highlighted in the Canvas.
✓JSON Schema validation against kit-definition.schema.json
✓All flowId references in commands[], events[], and timers[] must resolve to a flow in flows[]
✓All piece type ids in flows must belong to one of the declared expansions
✓All edge from/to ids must reference node ids within the same flow
✓Database table and column names must match ^[a-z][a-z0-9_]*$
✓No more than one primaryKey column per table
✓Required command options must be listed before optional ones
✓Command names: ^[a-z0-9_-]{1,32}$
✓No top-level unknown keys (warns in draft, errors on publish)