The base endpoint of the Korean Saju (사주 / Four Pillars, the Korean reading of Bazi) engine. Post a birthdate and get the Four Pillars (year, month, day, hour), the distribution of the five elements (wood, fire, earth, metal, water), the Day Master, and the zodiac animal — pure structured data, no interpretation layer. One POST, clean JSON, 10 languages.
Where /interpret adds an analysis layer (Ten Gods, Yongshin, Daeun),
/calculate stays at the foundation: it converts a birthdate into the eight
characters of a Saju chart and counts how the five elements are distributed across them.
That makes it the right call when you only need the raw chart and the
elemental balance — for example to drive a color theme, a personality
summary, or your own downstream scoring.
wood, fire, earth, metal, and water across the chart.POST /api/v1/calculate takes a solar birthdate as
year, month, day, hour, gender, plus an optional lang.
Use hour: -1 when the birth time is unknown — the Hour Pillar comes back
null and the element counts are computed from the remaining three pillars.
curl -X POST https://saju-api.pages.dev/api/v1/calculate \
-H "X-API-Key: sajuapi_free_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"year": 1990,
"month": 5,
"day": 15,
"hour": 14,
"gender":"M",
"lang": "en"
}'
const res = await fetch("https://saju-api.pages.dev/api/v1/calculate", {
method: "POST",
headers: {
"X-API-Key": "sajuapi_free_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
year: 1990, month: 5, day: 15, hour: 14, gender: "M", lang: "en",
}),
});
const data = await res.json();
console.log(data.pillars); // Four Pillars
console.log(data.elements); // { wood, fire, earth, metal, water }
console.log(data.day_master); // stem, element, polarity
import requests
res = requests.post(
"https://saju-api.pages.dev/api/v1/calculate",
headers={"X-API-Key": "sajuapi_free_YOUR_KEY"},
json={"year": 1990, "month": 5, "day": 15, "hour": 14, "gender": "M", "lang": "en"},
)
data = res.json()
print(data["pillars"]) # Four Pillars
print(data["elements"]) # {"wood":..,"fire":..,"earth":..,"metal":..,"water":..}
print(data["day_master"]) # stem, element, polarity
| Field | Type | Notes |
|---|---|---|
year | integer | Required. Solar (Gregorian) year, 1920–2050. |
month | integer | Required. 1–12. |
day | integer | Required. 1–31. |
hour | integer | Required. 0–23, or -1 if the birth time is unknown. |
gender | string | Required. M or F. |
lang | string | Optional. One of ko, en, ja, zh, es, pt-br, vi, id, hi, th. |
| Field | What it is |
|---|---|
input | The normalized birthdate the engine used for this calculation. |
pillars | The Four Pillars (year / month / day / hour), each with stem, branch, and their Hanja. hour is null when the birth time is unknown. |
elements | The five-element distribution: integer counts for wood, fire, earth, metal, and water across the chart. |
day_master | The Day Master — the Day Pillar stem, with its element and polarity (yin / yang). |
zodiac | The zodiac animal for the chart, derived from the Year Pillar branch. |
tier | Your API tier (e.g. free). |
remaining | Requests left in your daily quota. |
{
"input": { "year": 1990, "month": 5, "day": 15, "hour": 14, "gender": "M", "lang": "en" },
"pillars": {
"year": { "stem": "...", "branch": "...", "stem_hanja": "...", "branch_hanja": "..." },
"month": { "stem": "...", "branch": "...", "stem_hanja": "...", "branch_hanja": "..." },
"day": { "stem": "...", "branch": "...", "stem_hanja": "...", "branch_hanja": "..." },
"hour": { "stem": "...", "branch": "...", "stem_hanja": "...", "branch_hanja": "..." }
},
"elements": { "wood": 0, "fire": 2, "earth": 2, "metal": 3, "water": 1 },
"day_master": { "stem": "...", "element": "metal", "polarity": "yang" },
"zodiac": "horse",
"tier": "free",
"remaining": 98
}
pillars.hour is null when the birth
time is unknown.
The elements object always sums to the number of pillars counted (eight characters
for a full chart, six when the birth time is unknown). A count of 0 for an element
means that element is absent from the chart — a common signal in Saju for an
imbalance. Because the values are plain integers, you can drive your own UI
from them directly:
const e = data.elements; // { wood, fire, earth, metal, water }
const total = e.wood + e.fire + e.earth + e.metal + e.water;
const dominant = Object.keys(e).reduce((a, b) => (e[b] > e[a] ? b : a));
const missing = Object.keys(e).filter((k) => e[k] === 0);
// e.g. theme the chart by its dominant element, or flag missing ones
console.log(dominant); // "metal"
console.log(missing); // ["wood"]
pillars — no interpretation needed.elements into a bar, radar, or donut chart, or map the dominant element to a color theme.day_master.stem once and reuse it to call the daily endpoint for a recurring fortune feature.| Status | Meaning |
|---|---|
400 | invalid_input with a reason (e.g. year_out_of_range, gender_must_be_M_or_F, unsupported_lang). Year range is 1920–2050. |
401 | Missing or malformed X-API-Key. |
405 | Use POST for this endpoint. |
429 | Daily quota for your tier exceeded. |