npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

divyastroapi

v0.1.1

Published

Official Node.js / TypeScript SDK for DivyAstroAPI — Vedic & Western astrology, panchang, matchmaking, dashas, numerology and tarot. DrikPanchang-level precision, pay-per-call.

Readme

divyastroapi

Official Node.js / TypeScript SDK for DivyAstroAPI — a B2B Vedic & Western astrology API with DrikPanchang-level precision and pay-per-call billing.

  • 287 endpoints, fully typed, across 21 namespaces — panchang, charts, dashas, matchmaking, transits, horoscopes, numerology, tarot, muhurta, reports, narratives, and a complete Western (tropical) module.
  • Zero runtime dependencies — uses the platform fetch (Node 18+, Bun, Deno, and edge / serverless runtimes). Server-side by design — see Authentication.
  • ESM + CommonJS with bundled .d.ts types.
  • ✅ Typed errors, automatic retries (429/5xx) with Retry-After, timeouts, and a generic escape hatch for any endpoint.
  • Branded PDF reports (optional) — turn report JSON into white-label, print-ready kundli / matchmaking / numerology / horoscope PDFs. See Branded PDF reports.
npm install divyastroapi

Get an API key at https://divyastroapi.com/dashboard/keys.

Quick start

import { DivyAstro } from "divyastroapi";

const client = new DivyAstro({ apiKey: "dv_live_..." });
// or: new DivyAstro({ apiKey: process.env.DIVYASTRO_API_KEY })
// or just: new DivyAstro("dv_live_...")

// Today's panchang for a location
const tithi = await client.panchang.tithi({
  lat: 28.6139,
  lon: 77.209,
  tz: "Asia/Kolkata",
});

// A Vedic birth chart
const planets = await client.chart.planets({
  date: "1990-01-15",
  time: "10:30",
  tz: "Asia/Kolkata",
  lat: 19.076,
  lon: 72.8777,
});

// Kundli matchmaking score
const match = await client.milan.ashtakootaTotal({
  boy:  { date: "1988-05-04", time: "06:15", tz: "Asia/Kolkata", lat: 28.61, lon: 77.20 },
  girl: { date: "1992-03-20", time: "21:40", tz: "Asia/Kolkata", lat: 19.07, lon: 72.87 },
});

CommonJS works too: const { DivyAstro } = require("divyastroapi");

Authentication

Your API key (dv_live_…) authenticates every request and is sent as a Authorization: Bearer … header. Provide it in any of three ways:

new DivyAstro({ apiKey: "dv_live_..." });   // 1. explicit (recommended)
new DivyAstro("dv_live_...");                // 2. shorthand
new DivyAstro();                             // 3. reads process.env.DIVYASTRO_API_KEY

If no key is found (neither argument nor env var), the constructor throws a clear error. Get a key at https://divyastroapi.com/dashboard/keys.

🔒 Keep your key secret — use the SDK server-side

A dv_live_… key carries your account's full billing access. Use this SDK from a server, serverless function, or edge runtime — and load the key from an environment variable / secrets manager, never hard-coded. Do not embed the key in browser, mobile, desktop, or any client-side code, where end users could extract it and run up your bill. For client apps, call DivyAstroAPI from your own backend and forward the results.

(Need PDFs in the browser? The dependency-free divyastroapi/pdf render*Html functions take no key and are safe to run anywhere — see Branded PDF reports.)

Configuration

const client = new DivyAstro({
  apiKey: "dv_live_...",          // or set DIVYASTRO_API_KEY
  baseUrl: "https://api.divyastroapi.com", // override for local dev (http://localhost:8080)
  timeoutMs: 30_000,              // per-request timeout (default 30s)
  maxRetries: 2,                  // retries on 429 / 5xx / network (default 2)
  defaultHeaders: {},             // extra headers on every request
  fetch: myFetch,                 // inject a custom fetch (older runtimes / proxies / tests)
});

Input shapes

Most methods accept one of a few ergonomic input objects. The SDK maps these to the exact wire parameters the API expects (birth.lat, boy.date, start_date, …) for you.

| Shape | Used by | Example fields | |-------|---------|----------------| | Moment | panchang.*, calendars | { lat, lon, tz, date?, time? } | | Birth | chart.*, dasha.*, numerology, narratives, reports | { date, time, tz, lat, lon } | | Boy/Girl | milan.*, reports.matchMaking | { boy: Birth, girl: Birth } | | Two-person | western.synastry.*, western.composite.* | { personA: Birth, personB: Birth } | | Rashi | horoscope.* | { rashi: "aries", date?, lang? } | | Date range | eclipses.*, western.ingresses | { startDate, endDate } | | Muhurta | muhurta.vivah, naamkaran, bestTime | { lat, lon, tz, startDate, endDate } |

Vedic endpoints also accept optional calculation settings: ayanamsa ("lahiri" default, "krishnamurti", "raman", …), houseSystem, and useTrueNode.

await client.chart.planets({ ...birth, ayanamsa: "krishnamurti", houseSystem: "placidus" });

Namespaces

client.<namespace>.<method>(input) — every method returns the unwrapped data payload.

| Namespace | What it covers | |-----------|----------------| | panchang | tithi, nakshatra, yoga, karana, vara, sunrise/sunset, rahu-kaal, choghadiya, hora, muhurtas, monthly calendar, composite basic/advanced | | chart | planets, ascendant, houses, divisional (D1–D60), dignity, aspects, shadbala, ashtakvarga, avakhada, KP, astro-details | | dasha | full + current Vimshottari (5-level drill-down) and Yogini | | milan | Ashtakoota (total / full / per-koota), mangal/nadi/shani dosha, navamsa & dasha compatibility | | transit | positions, sade-sati, ashtakavarga, tarabala, vedha, double-transit, small-panoti | | horoscope | daily / weekly / monthly by rashi | | numerology | driver, conductor, soul, personality, destiny, full, advanced, challenges, periods | | muhurta | vivah, naamkaran, griha-pravesh, vyapar, yatra, best-time, … | | varshaphal | annual chart, lord, muntha, mudda-dasha, harsha-bala, tajika yogas | | prashna | horary answer, chart, arudha, significators | | eclipses | solar / lunar / all (date range, optional visibility) | | calendar | Hindu month, ritu, samvatsara, adhik-maas | | festivals | festivals by month / on a date | | planetMoments | retrograde windows, ingress, combustion window, speed | | ashtakavarga | sarva, bhinna (per planet), kaksha, transit-score | | geo | place search, reverse geocode, timezone, place by id | | tarot | cards, single card, daily, spread, yes/no | | reports | kundli (lite/detailed/brihad), match-making, mangal-dosha, sade-sati, varshaphal, numerology, horoscopes | | narrative | authored Vedic interpretations (lagna, planets, yogas, doshas, dasha-phal, outlooks, …) in en/hi/mr/bn/kn/ta/te/gu | | remedies | remedies by rule id; mantra / pooja / vrat detail | | western | full tropical module (see below) |

Western (tropical)

Nested under client.western.*:

await client.western.natal.chart({ date, time, tz, lat, lon, houseSystem: "placidus" });
await client.western.synastry.score({ personA, personB });
await client.western.transits.toNatal({ birth, date: "2026-06-16", time: "12:00", tz: "UTC" });
await client.western.returns.solar({ date, time, tz, lat, lon, returnYear: 2026 });
await client.western.profections.annual({ birthDate: "1990-01-15", ascSign: "capricorn" });

Sub-namespaces: natal, houses, synastry, composite, davison, transits, progressions, solarArc, returns, dignities, profections, zodiacalReleasing, primaryDirections, interpretation, narrative, heliocentric, astrocartography, eclipses, lunar, compatibility, plus firdaria, ingresses, retrogradeWindow.

Error handling

Every non-2xx response throws a typed error carrying the API's code, HTTP status, and request_id:

import { DivyAstro, PaymentRequiredError, RateLimitError, DivyAstroError } from "divyastroapi";

try {
  await client.chart.planets(birth);
} catch (err) {
  if (err instanceof PaymentRequiredError) {
    // 402 — out of credits / trial exhausted
  } else if (err instanceof RateLimitError) {
    console.log(`retry after ${err.retryAfter}s`);
  } else if (err instanceof DivyAstroError) {
    console.error(err.code, err.status, err.message, err.requestId);
  }
}

Error classes: BadRequestError (400), AuthenticationError (401), PaymentRequiredError (402), PermissionError (403), NotFoundError (404), RateLimitError (429), ServerError (5xx), DivyAstroConnectionError (network/timeout). All extend DivyAstroError.

Typing the response

Responses are returned as the unwrapped data, typed unknown by default. Narrow it with a type parameter, or pass { raw: true } to get the full { data, meta } envelope.

interface TithiData { number: number; name_en: string; paksha: string }
const t = await client.panchang.tithi<TithiData>({ lat, lon, tz });

const full = await client.request("/v1/panchang/tithi", { lat, lon, tz }, { raw: true });
// full = { data, meta: { request_id, cache, tier, ... } }

Escape hatch

Call any /v1/* endpoint directly — useful for brand-new endpoints not yet wrapped:

const data = await client.request("/v1/panchang/tithi", { lat: 28.61, lon: 77.20, tz: "Asia/Kolkata" });
// client.get(...) is an alias

Per-call options

const controller = new AbortController();
await client.chart.planets(birth, { signal: controller.signal, timeoutMs: 5000 });

Branded PDF reports

The divyastroapi/pdf subpath turns the JSON from client.reports.* into branded, print-ready PDFs — same designs the API was built to produce (cover page, planet/dasha tables, narrative sections), white-labelled with your client's logo, colors, footer, and optional watermark.

Two layers:

  1. render*Html(data, branding?) — pure, zero-dependency functions that produce a self-contained, branded HTML document. Run anywhere (Node, edge, browser).
  2. htmlToPdf(html, opts?) and the *Pdf(...) convenience wrappers — produce PDF bytes via the optional puppeteer peer dependency.
npm install puppeteer   # only if you want the SDK to emit PDF bytes
import { DivyAstro } from "divyastroapi";
import { kundliDetailedPdf, renderMatchMakingHtml } from "divyastroapi/pdf";
import { writeFileSync } from "node:fs";

const client = new DivyAstro({ apiKey: process.env.DIVYASTRO_API_KEY });

// 1. Fetch the report JSON
const report = await client.reports.kundliDetailed({
  date: "1990-01-15", time: "10:30", tz: "Asia/Kolkata", lat: 19.076, lon: 72.8777,
  lang: "hi",
});

// 2. Render a branded PDF in one call
const pdf = await kundliDetailedPdf(report, {
  branding: {
    companyName: "Acme Astro",
    logoUrl: "https://cdn.acme.com/logo.png", // or a data: URI
    primaryColor: "#6b21a8",
    secondaryColor: "#9333ea",
    footerText: "© Acme Astro — astrology for everyone",
    watermarkText: "SAMPLE", // optional diagonal watermark
  },
});
writeFileSync("kundli.pdf", pdf);

Prefer to bring your own renderer (or run on serverless)? Use the HTML layer and convert however you like — it has no dependencies:

const html = renderMatchMakingHtml(matchReport, { primaryColor: "#b91c1c" });
// → feed `html` to your own Puppeteer/Playwright, a print service, Gotenberg, etc.

Branding precedence: caller branding overrides the per-account branding embedded in the report JSON, which falls back to neutral system defaults.

Security note: branding inputs are sanitized — colors are validated against a safe-color allowlist, the watermark is CSS-escaped, and logoUrl is restricted to http(s) / data:image/... / relative URLs (other schemes are dropped). Chromium fetches logoUrl when rendering, so if you ever pass untrusted / end-user logo URLs, run Puppeteer with restricted network egress to avoid SSRF to internal hosts.

Performance: launching Chromium per call is slow. On a server, launch Puppeteer once and reuse it:

import puppeteer from "puppeteer";
const browser = await puppeteer.launch();
const pdf = await kundliDetailedPdf(report, { branding, browser }); // browser not closed for you

On serverless (AWS Lambda etc.), inject puppeteer-core + a Chromium layer:

import chromium from "@sparticuz/chromium";
import puppeteer from "puppeteer-core";
const browser = await puppeteer.launch({ executablePath: await chromium.executablePath(), args: chromium.args });
const pdf = await horoscopePdf(report, { browser });

Covered reports: kundliLite, kundliDetailed, kundliBrihad, matchMaking, dashaAnalysis, numerology, sadeSati, varshaphal, horoscope (each has both a render*Html and a *Pdf form). All render in en/hi/mr (and other locales where the report data carries them); Chromium's bundled Noto fonts handle every Indic script.

Contributing

The typed surface is generated from a manifest. After editing scripts/endpoints_part*.json, regenerate and build:

npm run generate   # regenerate src/resources/*
npm run typecheck
npm run build
npm test

License

MIT © DivyGuru