Generate a birth-chart SVG with Node.js

Turn a date, time and location into a chart you can display in your app. This walkthrough makes one server-side API call and saves the SVG to a file.

Available on Free: 500 standard requests per UTC calendar month. No credit card required.

Tropical birth chart with equal houses for the synthetic example: January 1, 1990, noon in New York. The wheel shows planetary placements, house divisions and major aspects.
The chart produced by the settings below. Synthetic birth details; tropical zodiac, equal houses, dark theme. Download the example SVG.

1. Set up your project and key

You need Node.js 22+ and a verified Cosmic Ephemeris account. The SDK calls the hosted calculation API; you do not need to install an ephemeris or run Python.

  1. Create a free account and verify your email.
  2. Open API Keys. Enter a Key label, such as Birth chart tutorial. Under Access scopes, select astro:natal-svg, then click Create API key.
  3. Click Copy key and save the complete key privately. It is shown only once; the shortened prefix in the key list will not work. Follow the environment-file steps below.
mkdir birth-chart-demo
cd birth-chart-demo
npm init -y
npm install cosmicephemeris@0.5.0

Already have a key? Reuse it if it includes this tutorial’s scope. One key can serve several projects: select all their required scopes when creating it. You do not need a separate key for each tutorial.

Save your key in a private .env file

Inside the project folder you just created, use your text editor to create a file named .env (not .env.txt). Put this single line in it:

COSMICEPHEMERIS_KEY=PASTE_YOUR_FULL_API_KEY_HERE

Replace PASTE_YOUR_FULL_API_KEY_HERE with the full key you copied. This is a placeholder, not a working key. Keep .env in the same folder where you will run birth-chart.mjs; the command later uses --env-file=.env to load it.

Create or open .gitignore in that folder and add this line so Git will ignore the key file:

.env

Keep the key on your server or local development computer. Do not put it in browser JavaScript, URLs, screenshots or a public repository. Signing in to this website does not authenticate your Node.js script; it still needs the key. See the authentication guide.

2. Save this as birth-chart.mjs

The .mjs extension lets Node run the imports directly. natalSvg() calculates and renders the chart in one request; a separate birth-chart call is unnecessary.

The SDK calls POST https://api.cosmicephemeris.com/api/astro/natal-svg and returns the SVG in chart.svg.

Download the complete Node.js script, or copy it below.

// Run on your server with Node.js 22 or newer.
// Install: npm install cosmicephemeris@0.5.0
// Configure COSMICEPHEMERIS_KEY privately, then run: node birth-chart.mjs
import { writeFile } from "node:fs/promises";
import { CosmicEphemeris, CosmicEphemerisError } from "cosmicephemeris";

try {
  // Reads COSMICEPHEMERIS_KEY from the server environment.
  const api = new CosmicEphemeris();
  const chart = await api.natalSvg({
    // Synthetic example, not a real person's birth record.
    birth: {
      date: "1990-01-01",
      time: "12:00",
      timezone: "America/New_York",
      lat: 40.7128,
      lon: -74.006,
    },
    zodiac: "tropical",
    house_system: "equal",
    theme: "dark",
    show_aspects: true,
  });

  // The SVG is a top-level field in the response.
  // "wx" avoids overwriting an existing chart; 0600 keeps the file private.
  await writeFile("birth-chart.svg", chart.svg, {
    encoding: "utf8", flag: "wx", mode: 0o600,
  });
  console.log("Created birth-chart.svg. Open it in your browser.");
} catch (error) {
  if (error instanceof CosmicEphemerisError) {
    // SDK errors expose sanitized fields. Do not log credentials or payloads.
    console.error("Chart request failed:", error.code, error.status ?? "");
  } else if (error?.code === "EEXIST") {
    console.error("birth-chart.svg already exists. Rename it before running again.");
  } else {
    console.error("Could not save the chart. Check your folder permissions.");
  }
  process.exitCode = 1;
}

The date and time are local to America/New_York. Latitude and longitude are numeric coordinates; west longitude is negative. Keep the timezone explicit so the local time can be resolved correctly.

3. Run the script

If you used the private .env file:

node --env-file=.env birth-chart.mjs

If your server already sets COSMICEPHEMERIS_KEY, run node birth-chart.mjs. A successful run prints:

Created birth-chart.svg. Open it in your browser.

Open birth-chart.svg from the project folder. It is a vector image with a 1200 × 1100 viewBox and can scale with your interface. Rename an existing output file before running again.

Each admitted request uses one standard unit, including failed calculations. The SDK does not retry automatically; a timeout may still consume quota. Downloading the preview above makes no calculation request.

4. Display the chart in your app

Generate the SVG on your server and return it through an image route with Content-Type: image/svg+xml. Keep personal charts behind your application's access controls. For the synthetic demo, an image element is enough:

<img
  src="/images/birth-chart.svg"
  width="1200"
  height="1100"
  alt="Birth chart for the synthetic example"
>

Serve your generated file at that image path, or change src to your own image route. Apply max-width: 100%; height: auto; in your stylesheet. The browser loads the image; the API credential stays on your server.

Make it your own

  • Light or print-friendly output: change theme to "light" or "monochrome".
  • A simpler wheel: set show_aspects: false to hide aspect lines.
  • Sidereal charts: use zodiac: "sidereal" with ayanamsa: "lahiri", or another supported ayanamsa.
  • Different house conventions: choose from the documented house systems and their limits.

Modern civil dates span 1800-01-01 through 2200-12-31, subject to the selected method’s limits. Historical dates use a separate explicit date format; see the complete request examples before adapting it for BCE inputs.

If Node says it cannot find .env: run the command from the project folder and check that the filename is exactly .env. If the key is missing or invalid, replace the placeholder with your complete key. If you receive HTTP 403, check the key’s required scope above.

If the request fails

ResultWhat to check
CONFIGURATIONUse Node.js 22 or newer and set the complete API key in the environment. A missing or malformed key is rejected before any request.
400 or REQUESTCheck the input shape, date, timezone, numeric coordinates and supported options against the API reference.
401 or 403Check that your key and account are active and the key allows astro:natal-svg.
429Check your account allowance, key budget and any concurrency or rate limit. Inspect the SDK's sanitized retryAfter value when present.
EEXISTThe file already exists. Rename it before another run. The request has already completed and used quota.

For timeouts or server errors, inspect service status before deciding whether to try again. Avoid automatic retry loops.

Build your first chart

Start with the synthetic example, then connect the same server-side call to your application's birth-data form.

All developer projects · SDK quickstart · Postman collection · Plan your astrology app