kite~/kite/docs/SDKs
v0.2.2
Reference

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

bash
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

bash
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:

OptionType (TS)DefaultNotes
teamId / team_idstringRequired. Your team id.
sourcestringRequired. Source slug. Validated client-side: lowercase alphanumeric + hyphen, must start alphanumeric, ≤ 64 chars, not kite.
tokenstringRequired. Hook token from kite endpoints create --source <name>.
ingestUrl / ingest_urlstringhttps://api.getkite.shIngest base URL.
authMode / auth_mode`"bearer" \"path"`"bearer"bearer sends Authorization: Bearer <token>; path puts the token in the URL.
maxRetries / max_retriesnumber3Max retry attempts for retryable failures.
fetchtypeof fetchglobal fetchTypeScript only — injectable for testing / custom runtimes.

TypeScript

ts
import { Kite } from "@getkite/sdk";

const kite = new Kite({
  teamId: "your-team",
  source: "my-app",
  token: process.env.KITE_HOOK_TOKEN!,
});

Rust

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:

OptionMaps toDefault
summarykitesummary extension
subjectCloudEvent subject
sourceUriCloudEvent sourcehttps://{source}
idCloudEvent idgenerated UUID
timeCloudEvent timenow

In TypeScript these are passed as an options object; in Rust they are builder methods on the emit call:

ts
await kite.emit("com.myapp.user.signup", { userId: "u_123" }, {
  summary: "User u_123 signed up",
  subject: "u_123",
});
rust
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

ts
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
KiteValidationErrorBad config, invalid source, or invalid event — thrown client-side before any request.
KiteAuthErrorHTTP 401 / 403.
KiteRateLimitErrorHTTP 429. Carries retryAfterSecs?.
KitePayloadTooLargeErrorHTTP 413, or the client-side pre-check when the serialized body exceeds 256 KB. Carries maxBytes.
KiteServerErrorHTTP 5xx or a network failure.
ts
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_secs from 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.