Emitting Events
Send structured events from your own application into Kite with the TypeScript or Rust SDK, then watch them arrive in the CLI and agent sessions.
Kite isn't only for third-party webhooks like GitHub or Stripe. Your own application can be a source too. The Kite SDK lets you emit structured events straight from your code:
your app ──(SDK)──▶ api.getkite.sh ──▶ kite stream / kite proxy / agents
Events you emit flow through the same ingest pipeline as provider webhooks and arrive as CloudEvents in kite stream, kite proxy, and agent sessions — so you can react to a user signup, a background job finishing, or any domain event the same way you react to a webhook.
// 01Prerequisites
- Kite installed and authenticated (
kite login) - A team id (visible in the dashboard or
kite status)
// 02Step 1 — Create an endpoint and hook token
Create a custom source for your application and mint a hook token:
kite endpoints create --source my-app
Kite prints a hook token. Store it as a secret (for example KITE_HOOK_TOKEN) — the SDK uses it to authenticate each emit. The source slug (my-app here) must be lowercase alphanumeric plus hyphens, start with an alphanumeric, be at most 64 characters, and cannot be kite.
// 03Step 2 — Install the SDK
TypeScript
npm install @getkite/sdk # or: pnpm add @getkite/sdk / bun add @getkite/sdk
Rust
cargo add kite-sdk
// 04Step 3 — Emit an event
Build and send a CloudEvent with a custom type and payload.
TypeScript
import { Kite } from "@getkite/sdk";
const kite = new Kite({
teamId: "your-team",
source: "my-app",
token: process.env.KITE_HOOK_TOKEN!,
});
await kite.emit(
"com.myapp.user.signup",
{ userId: "u_123", plan: "pro" },
{ summary: "User u_123 signed up (pro)" },
);Rust
use kite_sdk::Kite;
use serde_json::json;
let kite = Kite::builder()
.team_id("your-team")
.source("my-app")
.token(std::env::var("KITE_HOOK_TOKEN")?)
.build()?;
kite.emit("com.myapp.user.signup", json!({ "userId": "u_123", "plan": "pro" }))
.summary("User u_123 signed up (pro)")
.send()
.await?;The SDK posts the event with Content-Type: application/cloudevents+json and authenticates with the hook token (a Bearer header by default).
// 05Step 4 — Watch it arrive
In another terminal, stream your source:
kite stream --source my-app
Trigger the code path that emits, and you'll see the event:
[com.myapp.user.signup] User u_123 signed up (pro)
Proxy it to a local handler instead:
kite proxy --source my-app --target http://localhost:3000/events
// 06Custom types, summaries, and subjects
The event type is a reverse-DNS string you choose — com.myapp.user.signup, com.myapp.job.completed, and so on. It's what you filter on downstream:
kite stream --source my-app --event-type com.myapp.user.signup
Two optional fields make events easier to read and route:
- summary — a human-readable one-liner stored on the
kitesummaryextension. It's whatkite streamprints and what agent sessions surface. Kite preserves the summary you supply (trimmed, and capped at 500 characters); if you omit it, Kite derives a generic one. - subject — the CloudEvents
subject, useful for the specific entity the event is about (an order id, a user id).
TypeScript
await kite.emit(
"com.myapp.order.paid",
{ orderId: "o_42", amount: 4999 },
{ summary: "Order o_42 paid ($49.99)", subject: "o_42" },
);Rust
kite.emit("com.myapp.order.paid", json!({ "orderId": "o_42", "amount": 4999 }))
.summary("Order o_42 paid ($49.99)")
.subject("o_42")
.send()
.await?;// 07Plain-JSON fallback
If you'd rather not think about CloudEvents, send raw JSON and let Kite wrap it. The server derives the type com.{source}.event and a https://{source} source URI.
TypeScript
await kite.emitRaw({ hello: "world" });
// arrives as type "com.my-app.event"Rust
kite.emit_raw(json!({ "hello": "world" })).await?;// 08Limits and delivery semantics
- Payload size — a serialized event is capped at 256 KB. The SDK checks this before sending and the server enforces it (HTTP 413).
- Rate limits — ingest is rate limited per team. On HTTP 429 the SDK retries with backoff, honoring the server's
retry_after_secswhen present. - At-least-once delivery — Kite aims to deliver each event to your listeners at least once. Design consumers to be idempotent (for example, key off the event
idor your ownsubject) so a redelivery is harmless.
For the full configuration and error surface, see the SDK reference. Source code lives at github.com/Alpha-Centauri-Cyberspace/kite-sdk.