@insitive/api
v0.4.1
Published
Official TypeScript SDK for the Insitive Property Intelligence API (api.insitive.com.au).
Maintainers
Readme
@insitive/api
Official TypeScript SDK for the Insitive Property Intelligence API.
Auto-generated from the live /openapi.json on every release. Paths and (where the server declares them) request parameters stay in lock-step with the production surface. Built on openapi-fetch, so the runtime footprint is ~6 KB and there's no codegen of imperative client classes.
Type coverage note (v0.2.0): path / method / query-param types are exhaustive. Response body typing is still being rolled out — many endpoints currently return
unknownuntil each route declares itsresponseschema server-side. Track progress indocs/API_PRODUCTISATION_ROADMAP.md. Query params forlat/lngare typed as strings because that matches the wire format.
Source attribution
Endpoints that return third-party open data — cadastre/parcel, G-NAF address, planning zones & overlays (incl. risk), building footprints, and suburb trends — carry the required source credit in the response body as optional attribution and license fields (mirrored in the X-Insitive-Attribution / X-Insitive-License headers). These fields are now part of the generated types.ts, so read them straight off the typed data — no helper needed:
import { createInsitiveClient } from '@insitive/api';
const insitive = createInsitiveClient({ apiKey: process.env.INSITIVE_API_KEY! });
const { data } = await insitive.GET('/api/cadastre/lookup', {
params: { query: { lat: '-37.8136', lng: '144.9631' } },
});
console.log(data?.attribution, data?.license);If you display or redistribute this data you must reproduce the supplied attribution to meet the upstream licence terms.
Install
npm install @insitive/api
# or
bun add @insitive/api
# or
pnpm add @insitive/apiQuickstart
import { createInsitiveClient } from '@insitive/api';
const insitive = createInsitiveClient({
apiKey: process.env.INSITIVE_API_KEY!, // ins_live_… or ins_test_…
userAgent: 'my-app/1.0.0', // optional, helps our support team
});
// lat/lng are URL query strings on the wire — pass as strings.
const { data, response } = await insitive.GET('/api/locality/proximity', {
params: { query: { lat: '-37.8136', lng: '144.9631' } },
});
if (!response.ok) {
throw new Error(`Insitive API ${response.status}: ${JSON.stringify(data)}`);
}
console.log(data);Sandbox
When the sandbox service ships (roadmap item #5):
import { createInsitiveClient, INSITIVE_API_SANDBOX } from '@insitive/api';
const insitive = createInsitiveClient({
apiKey: process.env.INSITIVE_TEST_KEY!, // ins_test_…
baseUrl: INSITIVE_API_SANDBOX,
});What you get
- URL + method type safety.
insitive.GET('/api/cadastre/lookup', …)autocompletes; typo'd paths fail at compile time. - Path + query parameter inference.
params: { path: { suburb: 'Richmond' }, query: { state: 'VIC' } }is type-checked against the route definition. - Response narrowing by status code.
datais typed to the 2xx schema;erroris typed to the 4xx/5xx schema; the discriminated union is enforced. - Bearer-token injection. Pass
apiKeyonce; every request getsAuthorization: Bearer ….
Scopes & rate limits
Every key is granted one or more scopes (cadastre.read, planning.read, envelope.read, locality.read, dossier.read, catalog.read, ai-vision.read). A request to a route requiring a scope your key doesn't hold returns 403 Forbidden.
Per-key rate limit defaults to 60 requests/minute (token bucket). Limits are surfaced via the X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and (on 429) Retry-After headers — read them off response.headers.
Examples
The examples/ folder has runnable scripts:
examples/cadastre-lookup.ts— resolve a lot by pointexamples/locality-proximity.ts— nearest essentials for a coordinateexamples/suburb-trends.ts— median price history for a suburbexamples/risk-summary.ts— per-property risk summary (/v1/risk-summary, scoperisk.summary.read)examples/siting-earthworks.ts— async earthworks compute (/v1/siting/*, scopesiting.earthworks) using thesubmitEarthworksAndWaitpolling helperexamples/siting-compliance.ts— pre-lodgement siting compliance report (/v1/siting/compliance, scopesiting.compliance), with the PDF variant noted inline
Run any of them with bun run examples/<name>.ts (after INSITIVE_API_KEY=… export).
Async siting (earthworks) polling helper
The /v1/siting/earthworks endpoint is asynchronous: it enqueues a DEM-derived
cut/fill compute and returns an earthworksJobId, which you poll via
GET /v1/siting/jobs/{jobId} until the job is completed / failed. The SDK
ships a convenience helper that does the submit → poll loop with a bounded
timeout and exponential backoff:
import { createInsitiveClient, submitEarthworksAndWait } from '@insitive/api';
const insitive = createInsitiveClient({ apiKey: process.env.INSITIVE_API_KEY! });
// GeoJSON Polygon (WGS84) for the lot, and the proposed house footprint —
// either a GeoJSON Polygon or a rectangle spec `{ widthM, depthM, position }`.
const lotPolygon = {
type: 'Polygon',
coordinates: [
[
[144.9631, -37.8136],
[144.9635, -37.8136],
[144.9635, -37.814],
[144.9631, -37.814],
[144.9631, -37.8136],
],
],
};
const footprint = {
widthM: 12,
depthM: 18,
position: { lat: -37.8138, lng: 144.9633 },
};
const status = await submitEarthworksAndWait(
insitive,
{ lotPolygon, footprint, state: 'VIC', level: { mode: 'balanced' } },
{ timeoutMs: 90_000, onPoll: (s) => console.log(s.state) }
);
if (status.state === 'completed') console.log(status.result);Use waitForSitingJob(client, jobId, opts) directly if you already hold a job id
(e.g. from POST /v1/siting/fit with computeEarthworks: true). A failed job
is returned (inspect failedReason); a timeout throws SitingJobTimeoutError.
Regenerating types
Types are generated by openapi-typescript from spec/openapi.json and committed. From the repo root:
bun run sdks:generateThis re-dumps the spec from the live server and regenerates src/types.ts. Do not hand-edit src/types.ts.
Publishing
First publish is operator-driven (npm token must be set out-of-band):
cd packages/sdk-ts
bun run clean && bun run generate && bun run build && bun test
npm publish --access publicCI auto-publish-on-release is tracked separately; for now bump version in package.json by hand before publishing.
Changelog
0.4.1
- Fix Node.js ESM compatibility: emitted
dist/files now use explicit.jsextensions on relative imports. 0.4.0 loaded under Bun but failed withERR_MODULE_NOT_FOUNDunder Node's ESM loader.
0.4.0
- Add typed methods for the pre-lodgement siting compliance endpoints —
POST /v1/siting/compliance(JSON report) andPOST /v1/siting/compliance/pdf(PDF variant), scopesiting.compliance— in the generated types, plus the runnableexamples/siting-compliance.tsexample. - Publish the productised async siting surface (
/v1/siting/earthworks,/v1/siting/fit,/v1/siting/envelope,/v1/siting/jobs/{jobId}) in the generated types. - Add the
waitForSitingJob/submitEarthworksAndWaitpolling helpers (submit → poll with bounded timeout + exponential backoff), plusSitingJobTimeoutError/SitingJobPollError, and anexamples/siting-earthworks.tsrunnable example.
0.3.0
- Retire the hand-authored
SourceAttribution/WithAttribution<T>types andATTRIBUTION_HEADER/LICENSE_HEADERconstants. Theattribution/licenseresponse fields are now part of the generatedtypes.ts, so read them directly off the typeddata(single source of truth, no drift).
0.2.0
- Add
SourceAttributionandWithAttribution<T>types plusATTRIBUTION_HEADER/LICENSE_HEADERconstants so integrators can read theattribution/licensefields returned by cadastre/parcel, address, risk, building-footprints and suburb-trends endpoints type-safely.
0.1.0
- Initial release: typed paths, methods, and query params over
openapi-fetch.
License
MIT © Insitive Pty Ltd.
