TypeScript client for the Kikai building data API.
npm install @project-niffler/kikai-client
import { KikaiClient } from "@project-niffler/kikai-client";
const kikai = new KikaiClient({
baseUrl: "https://your-kikai-instance.example.com",
apiKey: "your-api-key",
});
import { KikaiClient } from "@project-niffler/kikai-client";
const kikai = new KikaiClient({
baseUrl: "https://your-kikai-instance.example.com",
getToken: async () => {
const session = await supabase.auth.getSession();
return session.data.session?.access_token ?? null;
},
});
// List buildings with filters
const page = await kikai.buildings.list({
page: 1,
pageSize: 25,
occupancyClass: "Commercial",
ownerTypeGroup: "CORPORATION",
});
// Get a single building (full JSON-LD)
const building = await kikai.buildings.getById("abc-123");
// Get all buildings for an owner
const buildings = await kikai.buildings.getByOwner("CITY OF PITTSBURGH");
// Get buildings by H3 cells (for map rendering)
const mapBuildings = await kikai.buildings.getByH3(["882a8444d7fffff"]);
// List portfolio summaries
const portfolios = await kikai.portfolios.list({ search: "PITTSBURGH" });
// Get full portfolio with buildings
const portfolio = await kikai.portfolios.get("COUNTY OF ALLEGHENY");
const results = await kikai.geocode("2610 Perrysville Ave, Pittsburgh PA");
// Push custom data onto buildings
await kikai.ingest.upsert([{
twin_id: "abc-123",
provenance: { updated_by: "energy-audit-2024" },
data: { audit_score: 85, last_audit: "2024-03-15" },
}]);
// List enrichment records
const records = await kikai.ingest.list();
// Delete enrichment for a building
await kikai.ingest.delete("abc-123");
import { KikaiClient, KikaiError } from "@project-niffler/kikai-client";
try {
const building = await kikai.buildings.getById("nonexistent");
} catch (err) {
if (err instanceof KikaiError) {
console.log(err.status); // 404
console.log(err.isNotFound); // true
console.log(err.isUnauthorized); // false
}
}
Note: buildings.getById() returns null for 404s instead of throwing.