SDK Reference
Configuration, methods, errors, and retry semantics for the Kite TypeScript and Rust SDKs for emitting events.
The Kite SDKs emit structured events from your application into Kite's ingest pipeline. They post CloudEvents to POST /hooks/{team_id}/{source} with a hook token, and the events flow through the normal pipeline into kite stream, kite proxy, and agent sessions.
For a step-by-step walkthrough, see the Emitting events guide. Source code and issues live at github.com/Alpha-Centauri-Cyberspace/kite-sdk.
// 01Install
TypeScript — @getkite/sdk
npm install @getkite/sdk # or: pnpm add @getkite/sdk / bun add @getkite/sdk
Ships dual ESM + CJS with full TypeScript types and no runtime dependencies. Runs on Node.js 18+, Bun, Deno, and Cloudflare Workers / edge runtimes (it uses the platform fetch and crypto.randomUUID).
Rust — kite-sdk
cargo add kite-sdk
Async, built on reqwest. Emit calls are async and return a Result.
// 02Configuration
A client is created once and reused. Both SDKs accept the same options:
| Option | Type (TS) | Default | Notes | |
|---|---|---|---|---|
teamId / team_id | string | — | Required. Your team id. | |
source | string | — | Required. Source slug. Validated client-side: lowercase alphanumeric + hyphen, must start alphanumeric, ≤ 64 chars, not kite. | |
token | string | — | Required. Hook token from kite endpoints create --source <name>. | |
ingestUrl / ingest_url | string | https://api.getkite.sh | Ingest base URL. | |
authMode / auth_mode | `"bearer" \ | "path"` | "bearer" | bearer sends Authorization: Bearer <token>; path puts the token in the URL. |
maxRetries / max_retries | number | 3 | Max retry attempts for retryable failures. | |
fetch | typeof fetch | global fetch | TypeScript only — injectable for testing / custom runtimes. |
TypeScript
import { Kite } from "@getkite/sdk";
const kite = new Kite({
teamId: "your-team",
source: "my-app",
token: process.env.KITE_HOOK_TOKEN!,
});Rust
use kite_sdk::Kite;
let kite = Kite::builder()
.team_id("your-team")
.source("my-app")
.token(token)
.build()?;// 03Methods
emit(type, data, options?)
Builds a structured CloudEvent with the given type and data and sends it (Content-Type: application/cloudevents+json). Returns an EmitResult.
Options map onto CloudEvents fields:
| Option | Maps to | Default |
|---|---|---|
summary | kitesummary extension | — |
subject | CloudEvent subject | — |
sourceUri | CloudEvent source | https://{source} |
id | CloudEvent id | generated UUID |
time | CloudEvent time | now |
In TypeScript these are passed as an options object; in Rust they are builder methods on the emit call:
await kite.emit("com.myapp.user.signup", { userId: "u_123" }, {
summary: "User u_123 signed up",
subject: "u_123",
});kite.emit("com.myapp.user.signup", json!({ "userId": "u_123" }))
.summary("User u_123 signed up")
.subject("u_123")
.send()
.await?;emitEvent(event) (TypeScript)
Escape hatch: send a fully-specified structured CloudEvent as-is. Missing specversion, id, and source are filled in; everything else — including extension attributes — is preserved. Extension keys must be lowercase alphanumeric.
emitRaw(data) / emit_raw(data)
Send plain JSON (Content-Type: application/json). The server wraps it into a CloudEvent, deriving type = com.{source}.event and source = https://{source}.
EmitResult
interface EmitResult {
id: string; // event id from the server
status: "accepted" | "duplicate_ignored"; // "duplicate_ignored" on a dedup no-op
createdAt?: string; // server-stamped RFC3339 time
usage?: { // quota snapshot, when provided
eventsUsed?: number;
eventsLimit?: number;
amountChargedAtomic?: number;
};
}// 04Errors
All errors extend a common KiteError and carry the HTTP status (when server-side) and the server's error string (when present). The Rust SDK exposes the equivalent cases on its error enum.
| Error (TS) | When |
|---|---|
KiteValidationError | Bad config, invalid source, or invalid event — thrown client-side before any request. |
KiteAuthError | HTTP 401 / 403. |
KiteRateLimitError | HTTP 429. Carries retryAfterSecs?. |
KitePayloadTooLargeError | HTTP 413, or the client-side pre-check when the serialized body exceeds 256 KB. Carries maxBytes. |
KiteServerError | HTTP 5xx or a network failure. |
import { KiteError, KiteRateLimitError } from "@getkite/sdk";
try {
await kite.emit("com.myapp.thing", { a: 1 });
} catch (err) {
if (err instanceof KiteRateLimitError) {
console.warn(`rate limited; retry after ${err.retryAfterSecs}s`);
} else if (err instanceof KiteError) {
console.error(`${err.name} (${err.status}): ${err.message}`);
}
}// 05Retry semantics
emit, emitEvent, and emitRaw automatically retry on:
- 429 — respecting
retry_after_secsfrom the server when present (capped at 30s). - 502 / 503 / 504.
- Network errors (connection reset, DNS failure, and similar).
Retries use exponential backoff with full jitter, up to maxRetries attempts. Other 4xx responses (400, 401, 403, 413, …) are never retried — they throw immediately. A serialized body over 256 KB fails before any network call.
// 06Limits
- 256 KB maximum serialized event size.
- Source slug: lowercase alphanumeric + hyphen, starts alphanumeric, ≤ 64 chars, not
kite. - `kitesummary`: client-supplied summaries are preserved, trimmed and capped at 500 characters.
- Delivery is at-least-once — make consumers idempotent.