Docs/SDK/TypeScript SDK quickstart

TypeScript SDK quickstart

The generated TypeScript SDK (client class SolomonPub) is a typed wrapper over the [[The published API and SDKs|published read API]]. It is not yet published to npm (see that doc for exactly what's gated) — the snippets below match the generated code's real, golden-tested shape, ready for when it ships.

Construct a client

import { SolomonPub } from "@pantheon-ai/solomon-pub"; // package name unconfirmed — see gating note

const client = new SolomonPub();

ClientOptions (all optional):

interface ClientOptions {
  apiKey?: string;        // Bearer reader key, for restricted-audience publications
  baseUrl?: string;       // defaults to https://app.lomon.dev
  fetch?: typeof fetch;   // custom fetch implementation
  maxRetries?: number;    // default 2 — retries 429/5xx with jittered backoff
  retryBaseMs?: number;   // default 200
}

Get a view's listing

const view = await client.site("my-site");
console.log(view.status, view.data?.notes);

Get one note

const note = await client.note("my-site", "guides/getting-started");
console.log(note.data?.markdown);

note()'s second argument is the note path — extension-stripped or literal .md, same as the URL form.

Search a published view

const hits = await client.search("solomon-docs", "publish a folder");
console.log(hits.data?.results[0]);
// { path, note_id, title, snippet, line, score }

search's exact signature (from the generated operations):

async search(
  slug: string,
  q: string,
  limit?: number,
  options?: RequestOptions,
): Promise<ApiResponse<SearchResults>>

SearchResults:

interface SearchResults {
  query: string;
  slug: string;
  results: Array<{
    path: string;
    note_id: string;
    title: string;
    snippet: string;
    line: number;
    score: number;
  }>;
  truncated: boolean;
}

The ApiResponse<T> envelope

Every method call — site(), note(), search() — returns the same envelope, never the bare payload:

interface ApiResponse<T> {
  data: T | null;      // parsed body on 2xx; null on 304
  etag: string | null; // weak ETag from the response, if any
  notModified: boolean;// true on a 304 Not Modified
  status: number;
}

Pass a prior response's etag back in as { ifNoneMatch } on site()/note() to revalidate cheaply:

const first = await client.site("my-site");
const again = await client.site("my-site", { ifNoneMatch: first.etag ?? undefined });
if (again.notModified) {
  // reuse first.data — nothing changed
}

A non-2xx, non-304 response throws SolomonPubError (with .status and a machine-readable .code, e.g. not_found, rate_limited) rather than returning a value — only 2xx and 304 come back through ApiResponse.

See also

  • [[The published API and SDKs]] — the underlying endpoints, rate limits, and what's gated (registry publishing) vs. live (the generated code itself).
  • [[Reader keys and audiences]] — how to obtain an apiKey for a restricted-audience publication.
  • [[Publish a folder or vault]] — what a slug actually exposes, and the scopes/audiences a publish config can have.