Birth Chart API Tutorial for JavaScript Developers
Learn how to generate, parse, and render astrological birth charts using the GitStrology API and the official TypeScript SDK. This tutorial walks through everything from basic natal chart generation to advanced features like aspect interpretation and chart visualization — with production-ready code samples.
What Is a Birth Chart?
A birth chart — also called a natal chart — is a snapshot of the sky at the exact moment and location of your birth. It maps the positions of the sun, moon, and planets across the twelve zodiac signs and astrological houses, and calculates the angular relationships (aspects) between them. A birth chart is the foundation of natal astrology: your sun sign, moon sign, and rising sign all come from it.
Computing a birth chart accurately requires four pieces of data: the date of birth, the time of birth, the latitude, and the longitude of the birth location. The GitStrology natal chart endpoint takes these inputs and returns a complete chart with planetary positions, house cusps, and major aspects.
Why Use an API for Birth Charts?
Astronomical calculations are complex. Computing planetary positions requires ephemeris data, Julian day conversions, and spherical geometry. Building this from scratch is a multi-month project. The GitStrology API handles all of the heavy computational work and returns clean, structured JSON that you can immediately render in your application.
Each natal chart request costs 5 credits. On the free tier, you get 100 credits per month — enough for 20 full natal charts during development. When you scale to production, the Pro plan provides 10,000 credits for $19/month. See rate limits and credits for full details.
Prerequisites
- Node.js 18+ and npm
- A GitStrology API key (free tier is fine)
- Basic knowledge of TypeScript and async/await
Step 1: Install and Configure the SDK
Install the GitStrology SDK in your JavaScript or TypeScript project:
npm install gitstrology
Set your API key as an environment variable. The SDK reads it automatically:
# .env GITSTROLOGY_API_KEY=gs_live_your_key_here
If you do not have a key yet, follow the quickstart guide to create a free account and generate one.
Step 2: Generate Your First Birth Chart
Initialize the client and call gs.natalChart() with birth data. Here is the minimal example:
import { Gitstrology } from "gitstrology";
const gs = new Gitstrology({
apiKey: process.env.GITSTROLOGY_API_KEY!,
});
const response = await gs.natalChart({
date: "1990-03-15",
time: "14:30",
latitude: 44.8,
longitude: 20.4,
timezone: "Europe/Belgrade",
});
const chart = response.data;
console.log("Sun Sign:", chart.sunSign); // "pisces"
console.log("Moon Sign:", chart.moonSign); // "leo"
console.log("Rising Sign:", chart.risingSign); // "gemini"That single call computes the positions of all planets, the twelve houses, and every major aspect. The response includes a credits envelope showing usage:
{
"data": {
"sunSign": "pisces",
"moonSign": "leo",
"risingSign": "gemini",
"planets": [
{
"planet": "sun",
"longitude": 354.2,
"sign": "pisces",
"degreeInSign": 24.2,
"house": 10,
"retrograde": false
}
],
"houses": [
{ "number": 1, "sign": "gemini", "longitude": 60.0 }
],
"aspects": [
{
"planetA": "sun",
"planetB": "moon",
"type": "opposition",
"orb": 2.1
}
]
},
"credits": { "used": 5, "remaining": 95 }
}For the complete response schema including every field and its type, see the natal chart API reference.
Step 3: Parse and Display Planetary Positions
The planets array contains one object per celestial body. Each entry includes the planet name, its ecliptic longitude, the zodiac sign it occupies, the degree within that sign, its house placement, and whether it is retrograde. Let's write a function to format these for display:
type Planet = {
planet: string;
sign: string;
degrees: number;
minutes: number;
house: number;
retrograde: boolean;
};
function formatPlanet(p: Planet): string {
const direction = p.retrograde ? " R" : "";
return `${p.planet} in ${p.sign} ${p.degrees}°${p.minutes}' (House ${p.house})${direction}`;
}
// Usage
const response = await gs.natalChart({
date: "1990-03-15",
time: "14:30",
latitude: 44.8,
longitude: 20.4,
});
response.data.planets.forEach((p) => {
console.log(formatPlanet(p));
});
// Output:
// sun in pisces 24°12' (House 10)
// moon in leo 5°30' (House 2)
// mercury in pisces 10°15' (House 10)
// mars in capricorn 18°45' (House 8)Step 4: Work with Astrological Aspects
Aspects describe the angular relationships between planets. The major aspect types returned by the API are conjunction, opposition, trine, square, sextile, and quincunx. Each aspect includes an orb value (how close to exact the angle is) and whether the aspect is applying (tightening) or separating.
type Aspect = {
planetA: string;
planetB: string;
type: "conjunction" | "opposition" | "trine" | "square" | "sextile" | "quincunx";
orb: number;
applying: boolean;
};
const ASPECT_MEANINGS: Record<string, string> = {
conjunction: "energies merge and amplify",
opposition: "tension between opposing forces",
trine: "natural harmony and flow",
square: "internal conflict demanding growth",
sextile: "opportunity through effort",
quincunx: "adjustment and adaptation needed",
};
function describeAspects(aspects: Aspect[]): string[] {
return aspects
.filter((a) => a.orb <= 3) // tight aspects only
.map((a) => {
const meaning = ASPECT_MEANINGS[a.type] || a.type;
const trend = a.applying ? "tightening" : "separating";
return `${a.planetA} ${a.type} ${a.planetB} (orb ${a.orb}°, ${trend}) — ${meaning}`;
});
}
const chart = (await gs.natalChart(birthData)).data;
const descriptions = describeAspects(chart.aspects);
descriptions.forEach(console.log);Step 5: Build a Chart Rendering Component
A common next step is to render the chart visually. While the API returns raw data, you can build a simple text-based wheel or use an SVG-based component. Here is a React component that renders the chart data in a structured layout:
// components/NatalChart.tsx
import { gs } from "@/lib/gitstrology";
export default async function NatalChart({
birthData,
}: {
birthData: {
date: string;
time: string;
latitude: number;
longitude: number;
timezone?: string;
};
}) {
const response = await gs.natalChart(birthData);
const chart = response.data;
return (
<div className="natal-chart">
<h2>
{chart.sunSign.toUpperCase()} Sun ·{" "}
{chart.moonSign} Moon ·{" "}
{chart.risingSign} Rising
</h2>
<h3>Planetary Positions</h3>
<table>
<thead>
<tr>
<th>Planet</th>
<th>Sign</th>
<th>Degree</th>
<th>House</th>
<th>Rx</th>
</tr>
</thead>
<tbody>
{chart.planets.map((p) => (
<tr key={p.planet}>
<td>{p.planet}</td>
<td>{p.sign}</td>
<td>{p.degrees}°{p.minutes}'</td>
<td>{p.house}</td>
<td>{p.retrograde ? "℞" : ""}</td>
</tr>
))}
</tbody>
</table>
<h3>Major Aspects</h3>
<ul>
{chart.aspects.map((a, i) => (
<li key={i}>
{a.planetA} {a.type} {a.planetB} — orb {a.orb}°
</li>
))}
</ul>
</div>
);
}Step 6: Handle Birth Time Uncertainty
Not everyone knows their exact birth time. The natal chart endpoint accepts a request without the time field — it defaults to noon UTC. However, this affects the accuracy of the moon sign, rising sign, and house placements. If you are building a form for users to enter their birth data, make the time field optional but clearly communicate the trade-off:
// Without birth time — moon and rising may be approximate
const chart = await gs.natalChart({
date: "1990-03-15",
// time omitted — defaults to noon UTC
latitude: 44.8,
longitude: 20.4,
});
// With birth time — full accuracy
const chartExact = await gs.natalChart({
date: "1990-03-15",
time: "14:30",
latitude: 44.8,
longitude: 20.4,
timezone: "Europe/Belgrade",
});For best results, always encourage users to provide a birth time and IANA timezone (e.g., America/New_York). The timezone field improves the accuracy of house calculations.
Step 7: Compute Compatibility Between Two Charts
Once you can generate a natal chart, the natural next step is comparing two charts. The compatibility endpoint (also called synastry) accepts two sets of birth data and returns an overall compatibility score plus a breakdown by category. It costs 5 credits. See the compatibility documentation for the full response schema.
const response = await gs.compatibility(
{
date: "1990-03-15",
time: "14:30",
latitude: 44.8,
longitude: 20.4,
},
{
date: "1988-07-22",
time: "09:00",
latitude: 40.7,
longitude: -74.0,
}
);
const compat = response.data;
console.log("Overall:", compat.overallScore); // 78
console.log("Emotional:", compat.breakdown.emotional); // 82
console.log("Physical:", compat.breakdown.physical); // 75
console.log("Summary:", compat.summary);Step 8: Track Current Transits
Transits tell you what planetary energies are currently affecting a natal chart. This is the basis of predictive astrology. The transits endpoint takes birth data plus a target date and returns active transit aspects with intensity ratings:
const response = await gs.transits({
date: "1990-03-15",
time: "14:30",
latitude: 44.8,
longitude: 20.4,
timezone: "Europe/Belgrade",
});
const transits = response.data;
transits.activeTransits.forEach((t) => {
console.log(
`${t.transitingPlanet} ${t.type} natal ${t.natalPlanet} — ${t.intensity}`
);
});Transits cost 5 credits per call. For the complete response structure, see transits documentation.
Step 9: Test from the Command Line
Use the CLI to quickly verify birth chart calculations without writing code:
npx gitstrology chart --birth 1990-03-15 --time 14:30 --lat 44.8 --lon 20.4
This prints the full chart to your terminal, including sun, moon, rising signs, and a planet summary. Perfect for quick debugging or one-off lookups.
Step 10: Error Handling and Validation
Always validate user-supplied birth data before sending it to the API. Invalid dates, out-of-range coordinates, or malformed times will cause errors. Here is a validation utility:
type BirthData = {
date: string;
time?: string;
latitude: number;
longitude: number;
timezone?: string;
};
function validateBirthData(input: Partial<BirthData>): BirthData {
// Validate date
if (!input.date || !/^d{4}-d{2}-d{2}$/.test(input.date)) {
throw new Error("Invalid date format. Use YYYY-MM-DD.");
}
const parsedDate = new Date(input.date);
if (isNaN(parsedDate.getTime())) {
throw new Error("Invalid date value.");
}
// Validate time (optional)
if (input.time && !/^d{2}:d{2}$/.test(input.time)) {
throw new Error("Invalid time format. Use HH:MM.");
}
// Validate coordinates
if (
typeof input.latitude !== "number" ||
input.latitude < -90 ||
input.latitude > 90
) {
throw new Error("Latitude must be between -90 and 90.");
}
if (
typeof input.longitude !== "number" ||
input.longitude < -180 ||
input.longitude > 180
) {
throw new Error("Longitude must be between -180 and 180.");
}
return input as BirthData;
}
// Usage in an API route
try {
const birthData = validateBirthData(requestBody);
const chart = await gs.natalChart(birthData);
return Response.json(chart);
} catch (error) {
return Response.json(
{ error: (error as Error).message },
{ status: 400 }
);
}Key Takeaways
- The GitStrology natal chart endpoint accepts date, time, latitude, and longitude, and returns a complete chart in structured JSON.
- Each natal chart costs 5 credits. The free tier provides 100 credits per month — enough for 20 charts during development.
- The
planetsarray gives you sign, degree, house, and retrograde status for every celestial body. - The
aspectsarray provides angular relationships between planets with orb values and applying/separating indicators. - Birth time is optional but strongly recommended — without it, rising sign and house placements may be inaccurate.
- Always validate user input before calling the API, and wrap calls in try/catch to handle errors gracefully.
- Use the CLI (
npx gitstrology chart) for quick debugging and verification.
Ready to generate your first chart? Get an API key from the dashboard and follow the quickstart guide to make your first request in under a minute.