Node.js astrology API quickstart

Native fetch, no dependencies.

Node 18+ ships fetch, so calling AstroNode needs nothing installed. This is a server-side call: the API key must never reach the browser, so put it behind your own route handler rather than calling from client code.

There is no official JavaScript SDK yet. The API is plain JSON over HTTPS, so `fetch` is the whole integration - about fifteen lines including error handling.

Step 1

Keep the key out of your code

The key authenticates every call and should never reach a client bundle or a commit. Put it in the environment and read it from there.

bash
# .env  (git-ignored)
ASTRONODE_API_KEY=aie_test_your_key_here

Step 2

Make the call

Node 18 and later have `fetch` built in. Nothing to install.

ts
const API_KEY = process.env.ASTRONODE_API_KEY;

const res = await fetch("https://api.astronode.dev/v1/charts/birth", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
    Accept: "application/json",
  },
  body: JSON.stringify({
    "date": "1993-07-04",
    "time": "09:27:11",
    "tz_offset_minutes": 330,
    "lat": 31.7473,
    "lng": 77.7754
  }),
});

const { data, meta } = await res.json();
console.log(data.ascendant, meta.engine_version);

Step 3

Wrap it once

A single helper keeps the key, the base URL and the error handling in one place, so calling a second endpoint is one line.

ts
const API = "https://api.astronode.dev";

export class AstroNodeError extends Error {
  constructor(readonly status: number, readonly code: string, message: string) {
    super(message);
  }
}

export async function astronode<T>(path: string, body: unknown): Promise<T> {
  const res = await fetch(API + path, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.ASTRONODE_API_KEY}`,
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify(body),
  });

  const json = await res.json();
  if (!res.ok) {
    // Errors use the same envelope, with `error` in place of `data`.
    throw new AstroNodeError(res.status, json.error?.code ?? "unknown", json.error?.message ?? res.statusText);
  }
  return json.data as T;
}

// Any endpoint, same shape:
const chart = await astronode("/v1/charts/birth", {
  "date": "1993-07-04",
  "time": "09:27:11",
  "tz_offset_minutes": 330,
  "lat": 31.7473,
  "lng": 77.7754
});

Step 4

Never call it from the browser

A key in client JavaScript is a key anyone can read and spend. Proxy through your own server route and let it hold the secret.

ts
// app/api/chart/route.ts  (Next.js App Router)
export async function POST(req: Request) {
  const birth = await req.json();
  // Validate `birth` before forwarding - this route is public.
  const data = await astronode("/v1/charts/birth", birth);
  return Response.json(data);
}

Next

Where to go from here

The call above is one of 110 endpoints. They all take the same bearer token and return the same envelope, so the second one is a path change. Each endpoint page carries its request fields and constraints.

Free tier covers 1,000 requests / month. No card, and test keys work on every endpoint.

Other languages

Same call, different stack