Quick start
Three steps: get a key, send a birth, read the envelope. Ten minutes, and the first thousand credits a month cost nothing — a kundli is one credit.
1. Get a key#
Sign up at the dashboard and create a key. You will see the whole key once — we store only its SHA-256, so we cannot show it to you again. Put it somewhere your code can read it:
export KAALJYOTI_API_KEY="kj_live_…"
A new account is on the Free plan: 1,000 credits a month, 10 requests a minute,
no card and no expiry. Create a kj_test_… key too if you want a second key
to point your staging environment at — test keys count against the same quota
but are easy to revoke separately.
2. Ask for a chart#
curl -s https://api.kaaljyoti.com/v1/kundli \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $KAALJYOTI_API_KEY" \
-d '{
"birth": {
"datetime": "1990-05-14T10:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.2090,
"place": "New Delhi"
},
"options": { "ayanamsa": "lahiri", "language": "en" }
}'Two details in that body are the whole contract, and they are the two people get wrong:
datetimeis the clock on the wall where the birth happened, not UTC and not your server's zone.1990-05-14T10:30:00means half past ten in the morning in New Delhi, andtimezonesays which wall that was.- Give
timezoneorutc_offset, or neither — never both. With neither, the API works the zone out from the coordinates and tells you what it used. Giving both is a400: they can disagree, and we will not guess which one you meant. See time zones.
Everything else has a default. options.ayanamsa is lahiri,
options.language is en, and you can leave options out entirely.
3. Read the envelope#
Every success looks the same:
{ "status": "ok", "data": { … }, "meta": { … } }
data is the calculation. meta says how it was computed — which is what you
show a user who asks why a number is what it is:
"meta": {
"cached": false,
"ayanamsa": { "id": "lahiri", "value": 23.7257290910… },
"timezone": { "name": "Asia/Kolkata", "utc_offset": "+05:30", "source": "given" },
"engine": "0.15.2",
"compute_ms": 1,
"language_fallback": [],
"credits": 1
}
source: "given" means you named the zone; "derived" means we worked it out
from the coordinates. engine is the calculation engine's version — pin it in
your own logs and a future difference is explainable rather than mysterious.
credits is what this request cost: 1 for a kundli.
Inside data, every id comes back with a name attached:
"lagna_sign": { "id": "cancer", "name": "Cancer" }
Ask for two languages — "language": ["en", "hi"] — and you get both:
"nakshatra": { "id": "vishakha", "name": "Vishakha", "names": { "en": "Vishakha", "hi": "विशाखा" } }
The id is the stable, machine-readable half and never changes. The name is
for people. Every id is lower-case snake_case, the panchang's included — a
tithi comes back as { "id": "dashami", "name": "Dashami" }, a month as
{ "id": "ashwina", "name": "Ashwina" }.
The whole answer, trimmed
{
"status": "ok",
"data": {
"ascendant": 99.0467252886…,
"ascendant_dms": "99°02'48.2\"",
"lagna_sign": { "id": "cancer", "name": "Cancer" },
"moon_sign": { "id": "sagittarius", "name": "Sagittarius" },
"positions": {
"sun": {
"longitude": 29.4246346912…,
"longitude_dms": "29°25'28.7\"",
"sign": { "id": "aries", "name": "Aries" },
"nakshatra": { "id": "krittika", "name": "Krittika" },
"pada": 1,
"speed": 0.9646146190…,
"is_retrograde": false
},
"moon": { … }
},
"houses": [ … ], "house_cusps": [ … ], "panchang": { … }, "yogas": [ … ]
},
"meta": {
"cached": false,
"ayanamsa": { "id": "lahiri", "value": 23.7257290910… },
"timezone": { "name": "Asia/Kolkata", "utc_offset": "+05:30", "source": "given" },
"engine": "0.15.2",
"compute_ms": 1,
"language_fallback": [],
"credits": 1
}
}A failure#
Failures have their own shape, and it always carries a code and a link:
{
"status": "error",
"error": {
"code": "validation_error",
"message": "give either timezone or utc_offset, not both",
"field": "birth.utc_offset",
"docs": "https://kaaljyoti.com/api/docs/errors#validation_error"
}
}
Branch on error.code, never on the message — messages get clearer over time,
codes do not. The full list is on the errors
page, and a refused request costs nothing.
Something smaller to start with#
A panchang needs no birth at all — just a place:
curl -s https://api.kaaljyoti.com/v1/panchang \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $KAALJYOTI_API_KEY" \
-d '{
"latitude": 28.6139,
"longitude": 77.2090,
"timezone": "Asia/Kolkata",
"place": "New Delhi",
"options": { "language": ["en", "hi"] }
}'Where to go next#
- Every endpoint, generated from the API itself.
- Keys — live, test and publishable, and where each may travel.
- What each API costs.
- MCP, if what you are building is an agent.
Base URL for everything: https://api.kaaljyoti.com/v1.