@geog-ai/sdk
v0.1.1
Published
Official TypeScript / JavaScript stub client for the geog.ai Spatial Intelligence API.
Maintainers
Readme
@geog-ai/sdk (TypeScript)
Stub client for the geog.ai Spatial Intelligence API.
Generated from openapi.yaml (v1). All 28 documented endpoints are exposed as
typed methods on a single GeogClient.
Stub status. Method signatures cover every documented path and method. Request bodies for
/simulate/*,/optimize/*,/rf/*,/trajectory/predictare typed asRecord<string, unknown>for now — refine to your needs or regenerate from the OpenAPI spec when stricter types are required.
Install
npm install @geog-ai/sdk
# or
pnpm add @geog-ai/sdk
# or
yarn add @geog-ai/sdkRequires Node ≥ 18 (uses the global fetch). For older runtimes, pass a
fetch implementation in the constructor options.
Usage
import { GeogClient } from "@geog-ai/sdk";
const geog = new GeogClient({ apiKey: process.env.GEOG_API_KEY! });
// 1. Resolve spatial context for a registered device
const ctx = await geog.context({ device_id: "sensor_h2s_023" });
// 2. Run an async plume simulation
const job = await geog.simulatePlume({
source: { lat: 31.9642, lon: -99.9035, alt_m: 545, emission_rate_gs: 2.4, stack_height_m: 12 },
duration_min: 60,
tier: 1,
species: "H2S",
});
// 3. Wait for completion
const result = await geog.waitForJob(job.job.id);
console.log(result.result);Async-job polling (typed result)
/simulate/*, /rf/mesh/viability, /rf/optimize/placement and /optimize/*
return the same AsyncJobAccepted envelope (HTTP 202) — just an
acknowledgement with a job.id. The actual payload lands at
GET /jobs/{job_id}, typed as JobResponse<TResult>. Pass the result
generic so result is typed instead of unknown:
import { GeogClient, type JobResponse } from "@geog-ai/sdk";
interface PlumeResult {
contours: Array<{ ppb: number; geometry: unknown }>;
peak_ppb: number;
impacted_receptor_ids: string[];
}
const geog = new GeogClient({ apiKey: process.env.GEOG_API_KEY! });
// 1. Submit — 202 AsyncJobAccepted, no `result` yet
const accepted = await geog.simulatePlume({ /* … */ });
// 2. Poll until terminal state, with a typed generic
const done: JobResponse<PlumeResult> =
await geog.waitForJob<PlumeResult>(accepted.job.id, {
intervalMs: 2000,
timeoutMs: 5 * 60_000,
});
// 3. Narrow on status before reading the result
if (done.job.status === "complete" && done.result) {
console.log(done.result.peak_ppb, done.result.impacted_receptor_ids);
} else {
throw new Error(`Job ${accepted.job.id} failed`);
}
// One-shot snapshot (no polling loop):
const snapshot = await geog.job<PlumeResult>(accepted.job.id);Swap PlumeResult for FloodResult, RFCoverageResult,
MeshViabilityResult, NodePlacementResult, etc. — the SDK shape is the
same; only your generic changes per endpoint.
Two envelopes, not one.
AsyncJobAccepted(returned immediately by the submit call) only carries{ ok, job: { id, status, eta_seconds, … } }— noresult. The eventualJobResponse<TResult>fromGET /jobs/{id}only populatesresultwhenjob.status === "complete"; on"failed"inspectjob.error/meta.
Errors
Non-2xx responses throw a GeogApiError with status, code, message,
optional details, and requestId.
Regenerating types from the spec
The primitive request/response shapes (Location, WindVector, SpatialState,
AsyncJobResponse, etc.) live in src/openapi.gen.ts, which is auto-generated
from QHPA/marketing/geog/docs/openapi.yaml by
openapi-typescript.
The hand-written src/types.ts re-exports these shapes under public aliases
and adds curated request envelopes for endpoints whose query/body shapes are
not modelled as named schemas in the spec.
After editing the spec, regenerate with either:
# from this directory
npm run generate-types
# or from the repo root, regenerates both SDKs in one shot
bash QHPA/marketing/geog/docs/sdks/scripts/generate-types.shsrc/openapi.gen.ts carries an auto-generated — do not edit header. Treat
it as build output: never hand-edit it; change the spec and rerun the script.
License
Proprietary — © geog.ai. Contact [email protected].
