The official TypeScript SDK
Every one of the 243 endpoints, typed, with each field's documentation on hover. No dependencies, so it adds nothing to your install but the client itself.
npm install occult-api- 243
- Endpoints, all typed
- 2,392
- Documented fields
- 492
- Enums as autocomplete
- 0
- Dependencies
Quick start
With no apiKey the client reads OCCULT_API_KEY from the environment. Create a key — it is shown once, so copy it before you leave the page.
import { OccultApi } from "occult-api";
const occult = new OccultApi({ apiKey: process.env.OCCULT_API_KEY });
const sun = await occult.astro.sunrise({
date_time: "2026-09-01T06:00:00+05:30",
latitude: 26.9124,
longitude: 75.7873,
timezone_as_float: 5.5,
});
console.log(sun.sunrise, sun.sunset);Endpoints mirror the URLs
/api/astro/eclipse/next-solar/ is occult.astro.eclipse.nextSolar(). Seven paths are both an endpoint and a parent, so those are callable objects — occult.astro.eclipse() and occult.astro.eclipse.upcoming() both work.
Field names are exactly what the API expects — date_time, not dateTime. There is no translation layer, so what you write is what goes on the wire.
One credit, however much you ask for
The single most useful thing to know about the pricing. Asking for six calculations in one call costs a sixth of what six calls would.
// Six calculations, ONE credit. A call costs the same whether you
// ask for one key or twenty, so batch what the screen needs.
const panchang = await occult.astro.panchanga({
...place,
keys: ["tithi", "nakshatra_segments", "yogam", "karana", "choghadiya", "rahu_kaalam"],
});Those names are typed per endpoint. Panchanga accepts 57 of them, and one wrong name rejects the whole request — so the SDK makes that a compile error rather than a wasted call.
Errors you can branch on
import { OccultApiError } from "occult-api";
try {
await occult.astro.panchanga({ ...place, keys: ["tithi"] });
} catch (error) {
if (error instanceof OccultApiError) {
if (error.code === "insufficient_credits") await topUp();
if (error.code === "validation_error") console.log(error.fields);
// error.retryable is false for anything a retry cannot fix
}
}Every failure is an OccultApiError with a stable machine code, so you branch on the cause rather than parsing a sentence that may be reworded. Transient failures are retried once; a revoked key never is, because retrying a metered API turns one failure into three.
Nothing is locked behind the generated methods
// Released after this SDK version? Call it anyway.
await occult.call("/api/astro/some-new-endpoint/", { date_time });The typed methods are wrappers over one public call, so an endpoint released after your installed version is reachable immediately — without waiting for an SDK release.
Server-side only
Your key spends real credits and must never reach a browser bundle, where anyone opening devtools can read it. The API declines cross-origin browser calls for exactly that reason, so a frontend request fails regardless — call the SDK from your backend and pass the result down.
Where it fits
This SDK
For writing code. You are building a product and want types, autocomplete and errors you can handle.
The MCP server →
For asking. You want Claude or Cursor to run a calculation conversationally, with no code at all.