Changelog

What changed, and when

Rule corrections appear here alongside code changes, because a rule change can move a festival date without altering a single line of the API contract.

API changes

Endpoint by endpoint

Contract and behaviour changes, newest first. Entries are never rewritten — a changed endpoint gets a new entry, so what it used to do stays readable. The same source produces the badges in the API reference and GET /v1/changelog.

MODIFIED

Location Catalogue pages: up to 2000 rows per page

limit now accepts 1-2000 (was 1-200). The default stays 100; paging, ordering and metering are unchanged.

Previously
limit was capped at 200.
Now
limit may be up to 2000, so a bulk import needs a tenth of the requests. Each page is still one API request. India type=CITY (613 records) now fits in one page.
Why
Enterprise customers importing the catalogue asked for larger pages.
api-2026-10-07Backward compatibleView API →
/v1/locations/catalogue/pages
NEW

Location Catalogue pages: optional /v1/locations-compatible records

GET /v1/locations/catalogue/pages accepts representation=locations_v1: each item then carries the /v1/locations field names (id, name_en, latitude, longitude, timezone, timezone_offset, country_code, region, subdivision_code, is_default, name_native) plus the catalogue's identity, provenance and quality fields. Paging, catalogue_version, entitlement and metering are unchanged.

Previously
Catalogue pages returned the catalogue's own record shape only.
Now
Optionally /v1/locations-compatible. id is the GeoNames id, not a /v1/locations id (use curated_location_id for location_id; otherwise pass lat, lon and tz). timezone_offset is for timezone_offset_as_of (set it with offset_date). region is the engine's coordinate resolver, with region_confidence; name_native is null where no verified native-script name exists. Without the parameter the response is unchanged.
Why
Enterprise customers wanted to store catalogue pages directly in an existing /v1/locations schema.
api-2026-10-06Backward compatibleView API →
/v1/locations/catalogue/pages
NEW

Enterprise: page through the Location Catalogue (offset/limit)

GET /v1/locations/catalogue/pages returns the Location Catalogue in pages of up to 200 places: the same rows, fields and order as the Location Catalogue dataset for the same country, state and type, with items, limit, offset, total and next_offset (null on the last page). Pages carry catalogue_version; pass it back and a catalogue refresh between pages answers 409 instead of mixing versions. /v1/locations (the 27 curated locations) and /v1/locations/search are unchanged.

Previously
The full catalogue was available only as an asynchronous dataset download.
Now
Also readable page by page. Requires an active Location Catalogue grant; the grant's country, state and type scope applies. Each page is one API request against the account's quota and rate limit; it does not use the grant's dataset allowance. Place data (c) GeoNames contributors, CC BY 4.0, attribution required.
Why
Enterprise customers asked to load the catalogue into their own systems in small batches.
api-2026-10-06Backward compatibleView API →
/v1/locations/catalogue/pages
NEW

Classical Readings: nature and spouse

Two more cited readings. Nature: the disposition Bṛhat Jātaka 17 gives for the Moon's sign (with Sārāvalī 23 as a second witness) and Phaladīpikā IX for the lagna. Spouse: the husband as Bṛhat Jātaka 24.11-12 and Sārāvalī 45 describe him from a woman's chart, and the single conditions the texts give for the wife from a man's chart.

Previously
No temperament or spouse readings.
Now
POST /v1/readings/nature and /v1/readings/spouse (Pro). Only temperament traits are served; predictions about wealth, family, health or events and abusive wording are withheld and counted. The spouse reading keeps each text's frame (husband from a woman's chart, wife from a man's chart), never infers gender, and returns both lords when the 7th sign and the 7th navāṁśa sign differ.
Why
Follow-up to the classical readings: the next most-asked questions the classical texts answer.
api-2026-10-10Backward compatibleView API →
/v1/readings/nature/v1/readings/spouse
MODIFIED

Classical Readings: plain reading, interpretation and Moon nakshatra

Every Classical Readings response now opens with `reading` (plain sentences, each with its verse) and `interpretation` (a readable paragraph, labelled as TathaAstu's interpretation). Nature adds the Moon's nakshatra (Bṛhat Jātaka 16, Jātaka Pārijāta IX) and strengths, challenges, relationships and work. Spouse adds `partner_any_chart` from the 7th lord (labelled a modern convention). Soul origin reads the Sun as the soul and the Moon as the mind (Bṛhat Jātaka 2.1) with the traditional purpose of each world.

Previously
Responses were mostly cited data and references; some charts returned no readable statement.
Now
`reading` and `interpretation` come first; all earlier fields are unchanged, so existing integrations keep working.
Why
Customers found the cited data hard to read without an interpretation.
api-2026-10-10Backward compatibleView API →
/v1/readings/appearance/v1/readings/soul-origin/v1/readings/nature/v1/readings/spouse
NEW

Classical Readings: appearance and soul origin

Two readings from the classical texts, each statement with book, chapter and verse. Appearance: the form Bṛhat Jātaka 5.23 associates with the lord of the rising navāṁśa, the features given for the lagna sign and the Moon's sign, and bodily clauses for planets in the 1st house. Soul origin: the worlds Bṛhat Jātaka 25.14-15 associates with the chart, and one mokṣa yoga.

Previously
No appearance or soul-origin readings.
Now
POST /v1/readings/appearance and /v1/readings/soul-origin (Pro). Readings, not predictions: where a text leaves a point undefined (the strongest planet, the stronger luminary) nothing is guessed; both candidates are returned and a single answer is given only when they agree. Points where the texts disagree are listed in texts_differ.
Why
Customers asked for appearance and past-life readings grounded in the classical texts.
api-2026-10-10Backward compatibleView API →
/v1/readings/appearance/v1/readings/soul-origin
NEW

Locations: every country, at city level

The gazetteer now holds 163,531 places in 243 more countries: every populated place of 1,000 people or more (GeoNames cities1000, CC BY 4.0), with state codes in ISO 3166-2 where they could be verified. India, Nepal and Sri Lanka stay at village level and are unchanged.

Previously
Search and the catalogue covered India, Nepal and Sri Lanka only.
Now
Search any country with country=GB (or any ISO code), or every country with scope=world. Without either, search covers India, Nepal and Sri Lanka exactly as before. The catalogue pages and datasets accept any country that has places; each country has its own catalogue_version, so an India import in progress is unaffected. World places have region null (the festival traditions are defined for India, Nepal and Sri Lanka); calculations use their lat, lon and timezone.
Why
Customers serving users outside India asked to find places such as London or Toronto by name.
api-2026-10-07Backward compatibleView API →
/v1/locations/search/v1/locations/detail/{location_id}/v1/locations/catalogue/pages/v1/locations/catalogue/datasets
FIXED

Kundli: the response is now documented field by field

The /v1/kundli description listed only five vargas (D1/D7/D9/D10/D30) and did not say what the response contains. It now lists every block of the response, including all 16 divisional charts (D1 to D60), and the docs show a real example. The API response itself is unchanged.

Previously
Documentation named five vargas and did not describe the response.
Now
Documentation lists every response block and the 16 vargas the endpoint returns.
Why
Customers could not see from the docs what /v1/kundli returns.
api-2026-10-07Backward compatibleView API →
/v1/kundli
NEW

Festival stories (katha), significance and observance

142 festivals now carry content: 57 kathas (the story told for the festival), 93 significance notes and an observance note. Read it from GET /v1/festivals/content/{subject}, or add content=story (katha, significance, vidhi or all) to the festival and calendar endpoints to attach it to every festival in the response. Hindi is available for every katha; more languages are being added.

Previously
Festival responses gave dates, rules and names only.
Now
Each piece has title, body_html, the language served and provenance: original adaptations by TathaAstu, the scriptural or traditional source adapted (marked unverified until reviewed) and review_status draft. A piece not yet translated is served in English with language_note. Without content= every response is unchanged.
Why
Apps want to show the story of a festival next to its date.
api-2026-10-07Backward compatibleView API →
/v1/festivals/content/v1/festivals/content/{subject}/v1/festivals/v1/festivals/year/v1/festivals/month/v1/festivals/range/v1/calendar/month/v1/calendar/day
MODIFIED

Languages: Panchang, Jyotish and festival names in all 56 languages

Every name the API localizes (tithi, nakshatra, yoga, karana, months, samvatsara, choghadiya, planets, signs, houses, dashas, festivals and vrats) now exists in every registered language, including Japanese, Korean, Chinese, Thai, Vietnamese, Indonesian, Portuguese and the other European and Indian languages. World festivals now also return festival_name_local and religion_local. Additive: machine values are unchanged; English responses are unchanged.

Previously
About 40 languages carried only weekday, sign and planet names; world festival names were English only.
Now
Full vocabulary in all 56 languages. Much of it is machine translation and is recorded as such in the vocabulary provenance; corrections can be requested through support.
Why
Customers asked for Japanese, Korean and the other documented languages to be served, not just accepted.
api-2026-10-03Backward compatibleView API →
/v1/calendar/day/v1/panchang/v1/day-context/v1/festivals/v1/festivals/world/v1/festivals/world/upcoming/v1/festivals/world/religions
MODIFIED

Languages: Rashifal readings, error messages and labels in all 56 languages; Kundli honours body lang

Rashifal (daily, weekly, monthly, yearly) and Life-Area Rashifal now render their readings in every registered language through *_local fields, as Hindi always has. Every error carries message_local in all 56 languages. Muhurat, observance, condition and description labels are localized in every language. POST /v1/kundli now honours `lang` in the request body (it was silently ignored; the query parameter still takes precedence).

Previously
Rashifal prose and error messages in English and Hindi (errors in 13 languages); Kundli body lang ignored.
Now
All 56 languages. English and Hindi output is unchanged byte for byte. The new languages are machine translation pending native review and are recorded as such.
Why
Customers asked for every API in every documented language.
api-2026-10-03Backward compatibleView API →
/v1/rashifal/vedic/v1/rashifal/vedic/{period_type}/v1/rashifal/vedic/all/v1/rashifal/vedic/life-areas/daily/v1/rashifal/vedic/life-areas/daily/all/v1/kundli
NEW

Enterprise: Location Catalogue

A versioned download of the gazetteer behind /v1/locations/search for a country, state and place type, with GeoNames attribution (CC BY 4.0). Only places linked to a curated /v1/locations id are calculation_ready. /v1/locations is unchanged.

Previously
Not available.
Now
Asynchronous, signed download. Enterprise plan plus a location_catalogue_v1 grant, whose scope decides the countries, states and place types that may be requested.
Why
Enterprise customers keep a local copy of deterministic data instead of calling day by day.
api-2026-10-03Backward compatibleView API →
/v1/locations/catalogue/datasets/v1/locations/catalogue/datasets/coverage/v1/locations/catalogue/datasets/{request_id}/v1/locations/catalogue/datasets/{request_id}/cancel/v1/files/locations/{dataset_id}
NEW

Enterprise: Life-Area Rashifal Dataset (month or year)

Every day of a month or year for all twelve rashis, exactly as /v1/rashifal/vedic/life-areas/daily/all returns it, in English or Hindi. A delivery format only: no monthly or yearly synthesis, no score.

Previously
Not available.
Now
Asynchronous, signed download. Enterprise plan plus a rashifal_lifearea_bulk_v1 grant, which decides the years that may be requested.
Why
Enterprise customers keep a local copy of deterministic data instead of calling day by day.
api-2026-10-03Backward compatibleView API →
/v1/rashifal/vedic/life-areas/datasets/v1/rashifal/vedic/life-areas/datasets/coverage/v1/rashifal/vedic/life-areas/datasets/{request_id}/v1/rashifal/vedic/life-areas/datasets/{request_id}/cancel/v1/files/rashifal-life-areas/{dataset_id}
NEW

Enterprise: Annual Calendar Dataset

One request produces a complete, compressed calendar for a calculation-ready location, a year and a language: every date with Panchang, sunrise/sunset, festivals and observances, Hora, Choghadiya, Muhurat, Hindu calendar, conditions and eclipses.

Previously
Not available.
Now
Asynchronous (202 then 200), delivered as a signed download. Enterprise plan plus a calendar_bulk_v1 grant; the grant decides which years, locations and languages may be requested.
Why
Enterprise customers keep a local copy of deterministic data instead of calling day by day.
api-2026-10-03Backward compatibleView API →
/v1/calendar/datasets/v1/calendar/datasets/coverage/v1/calendar/datasets/{request_id}/v1/calendar/datasets/{request_id}/cancel/v1/files/calendar/{dataset_id}
MODIFIED

Panchang names localized in all 12 report languages

Yoga, karana, tithi, nakshatra, timing windows, Panchak and eclipse names, samvatsara, ayana, paksha, ritu and month names now carry `name_local` in Hindi, Marathi, Gujarati, Bengali, Tamil, Telugu, Kannada, Malayalam, Punjabi, German, Spanish and French.

Previously
883 catalogue names and 782 calendar names had no localized value in at least one of these languages and were reported in X-Localization-Missing; 216 values existed but were stored where the API did not read them.
Now
Every Panchang catalogue entry resolves in all 12 languages. The new values are machine translations (governed and labelled as such in the vocabulary's provenance), validated for script and checked against the source output; canonical English values are unchanged.
Why
Clients serving regional audiences saw English names or missing fields in their language.
vocab-2026-10-02Backward compatibleView API →
/v1/panchang/v1/panchang/full/v1/panchang/event-catalog/v1/choghadiya/v1/day-context
FIXED

Panchang: stored and live-computed days now return the same Hindu-calendar fields and flags

A day served from precomputed rows and a day computed live (locations 16-27, coordinate requests) returned different `hindu_calendar` fields, and live days always reported `is_panchak`/`is_bhadra` false and moon illumination null.

Previously
Stored days carried amanta_month_key/num, samvatsara_key/num and flat samvat fields; live days carried amanta, samvatsara and a nested `year`. Live special_day_flags never reported Panchak or Bhadra.
Now
Both carry both sets of fields (additive; nothing renamed or removed), plus `ayana_key` (UTTARAYANA / DAKSHINAYANA) and `engine.calculation_source` (stored | live). Live days report Panchak, Bhadra and illumination from the same engine output the stored rows were built from.
Why
One response contract whichever path answers.
api-2026-10-02Backward compatibleView API →
/v1/panchang/v1/calendar/day/v1/panchang/lite/v1/day-context
NEW

Lucky number, lucky colour, birth and destiny numbers with gemstone reference, from the date of birth

One call from the date of birth: the birth number (Mulank), destiny number (Bhagyank) and lucky number, each with the working shown, its planet and the colour and gem the classical texts associate with that planet, plus a lucky colour. Add the time and place of birth and the same call also names the rulers of the lagna and Moon sign and their gems.

Previously
No numerology or gemstone endpoint existed; the Vedic Rashifal deliberately carries no lucky number.
Now
A separate PRO route, labelled for what it is. The numbers are MODERN_NUMEROLOGY (Cheiro's Book of Numbers, with Rahu and Ketu in place of Uranus and Neptune): no classical Jyotish work assigns lucky numbers, and the response says so. The gems are REFERENCE_ONLY (Phaladeepika II.29; Jataka Parijata II.21): the classical texts give gems away in donation rather than wear them, and nothing here recommends wearing or buying a stone or claims any benefit. Existing endpoints are unchanged.
Why
Clients asked for a lucky number and a gemstone by date of birth. Both can be offered honestly only outside the classical Rashifal, with their real sources and classifications attached.
cheiro-birth-destiny-1 / gem-reference-1Backward compatibleView API →
/v1/numerology/birth-profile
FIXED

Eclipses: visibility on the local date, eclipse days by the place's own calendar day, real gamma

/v1/eclipse/visibility now looks for the eclipse on the local date of its maximum; the eclipse attached to a Panchang or day-context day is the one that overlaps that place's local day; gamma and penumbral magnitude are computed values instead of 0.

Previously
An eclipse whose maximum fell on a different UTC date than the local date (e.g. the lunar eclipse of 20 Feb 2027 UTC, 21 Feb in India) was reported not visible with a note, and was attached to the wrong day in Panchang responses east of Greenwich; gamma was 0 for every eclipse and penumbral magnitude 0 for every penumbral eclipse.
Now
Visibility, local contact times and Sutak are returned for these eclipses (Sutak rules unchanged); eclipse days follow the place's time zone; gamma and penumbral magnitude agree with NASA's Five Millennium Canon to within 0.001 for every eclipse 2001-2100.
Why
Eclipses near midnight UTC were missing on the day they occur locally (found in the E1 follow-up audit).
api-2026-10-02Backward compatibleView API →
/v1/eclipse/visibility/v1/panchang/v1/panchang/full/v1/day-context
FIXED

Day context: the panchang block is no longer null for locations 16-27; location_id alone is accepted

With location_id 16-27 every day's `panchang` came back null. /v1/day-context/range also refused a location_id on its own with a 400.

Previously
`panchang: null` on every day for locations without precomputed rows, cached for six hours; /v1/day-context/range?location_id=1 without lat/lon answered 400.
Now
The panchang block is computed for those locations, and a day whose panchang cannot be computed is no longer cached. /v1/day-context/range accepts location_id alone and serves that location's own coordinates; an unknown id is a 404.
Why
Every published location must be served by the aggregated endpoints.
api-2026-10-02Backward compatibleView API →
/v1/day-context/v1/day-context/range
FIXED

Day context: cached responses return eclipse numbers as numbers

A cached response returned eclipse `max_magnitude` and `gamma` as strings.

Previously
Fresh responses: numbers. Cached responses (6 h): the same values as strings.
Now
Both return JSON numbers. Values are unchanged.
Why
A cached answer must be indistinguishable from a fresh one.
api-2026-10-02Backward compatibleView API →
/v1/day-context/v1/day-context/range
FIXED

Compatibility: Mangal dosha uses the same rule as /v1/dosha

Each partner's Mangal dosha now follows BPHS 80.47-49, as /v1/dosha does: Mars in the 1st, 4th, 7th, 8th or 12th house unless a benefic aspects or joins it, ceasing when both partners have it.

Previously
Compatibility used a houses-only check that ignored the benefic clause, added a 'Severe' grade for the 7th/8th house, and listed own-sign, exaltation and Rahu 'cancellations' that have no classical source; it could disagree with /v1/dosha for the same chart.
Now
Verdicts match /v1/dosha; `cancelled_by_benefics` names the benefic when it decides; the Severe grade is gone; the old cancellations are reported only as CONVENTION and never change the verdict. Stored reports are not rewritten and are labelled `mangal_basis: legacy`.
Why
One rule for Mangal dosha across the API.
api-2026-10-02Backward compatibleView API →
/v1/compatibility/v1/compatibility/score/v1/compatibility/report/v1/compatibility/{compat_id}
FIXED

Calendar year: Ekadashi, Purnima and Amavasya are counted by observance date

Monthly summaries now come from the festival engine, so they agree with /v1/festivals. New additive fields list every date: `ekadashi_dates`, `purnima_dates`, `amavasya_dates`, and the response states `summary_basis: festival_observance`.

Previously
The summaries counted days on which the tithi prevailed at sunrise. A tithi that never prevails at a sunrise was missing and one spanning two sunrises counted twice: for 2027 in Delhi, February showed no Purnima (Magha Purnima is 20 Feb) and July one Ekadashi (Kamika Ekadashi is 29 Jul).
Now
`purnima_date` and `amavasya_date` are the first observance date in the month and `ekadashi_count` the number of Ekadashi observances, exactly as /v1/festivals dates them. Responses are also faster: the festival year is computed once for every language.
Why
One definition of an observance across the API (PO decision K-3).
api-2026-10-02Backward compatibleView API →
/v1/calendar/year
FIXED

Calendar month, range and year now answer for every location in /v1/locations

Twelve of the 27 locations that /v1/locations publishes (ids 16-27: Delhi, Jaipur, Lucknow, Bangalore, Kochi, Tirupati, Puri, Pune, Pokhara, Jammu, Jaffna, Kandy) returned an empty calendar.

Previously
/v1/calendar/month and /v1/calendar/range returned `days: []` for these ids, and /v1/calendar/year reported zero Ekadashis and no Purnima or Amavasya dates.
Now
Days without precomputed rows are computed with the same engine /v1/calendar/day already uses for these locations, with the same fields. Locations 1-15 are unchanged. An unknown location_id is now a 404, as on /v1/panchang.
Why
Every published location must be served by every calendar view.
api-2026-10-02Backward compatibleView API →
/v1/calendar/month/v1/calendar/range/v1/calendar/year
FIXED

Birth Report (predictive edition): unsourced verdicts and scores removed; Kuja explanation completed

Transit verdicts, year and life-area rankings, and the strong / moderate / weak planet labels are removed from the predictive edition. The Kuja dosha paragraph now states the benefic clause of the rule and the condition that decided the result.

Previously
Transits were called favourable or unfavourable without the obstruction (vedha) rule that is part of the same verse; years and life areas were ranked by summed scores no classical text supports; planets were labelled strong or weak by a heuristic; the Kuja sentence named only the houses, so a dosha withheld by a benefic read as a contradiction.
Now
The report shows the calculated facts (positions, dignities, dasha periods, transit positions) without those verdicts. The Kuja paragraph names the benefic that withholds the dosha when there is one. All 13 report languages; new wording in 11 languages is machine-translated and pending native review. The calculation edition is unchanged.
Why
Birth Report content is limited to what classical sources support (Birth Report interpretation research V1).
api-2026-10-02Backward compatibleView API →
/v1/kundli/birth-report
MODIFIED

Birth chart: legacy yoga detection is no longer in the default response

breaking

`include_yogas` now defaults to false on /v1/birth-chart, and stored charts no longer return yogas unless asked. A caller who opts in receives the legacy result labelled `yogas_status: legacy_unreviewed` with its known defects in `yogas_known_defects`.

Previously
/v1/birth-chart returned yogas from the legacy detector by default, including on cached and stored charts. That detector has four known defects, e.g. Shasha yoga is not recognised for Saturn exalted in Libra.
Now
Default responses carry `yogas: null` and `yogas_status: not_requested`. With include_yogas=true (also on GET /v1/birth-chart/{profile_id} and /v1/kundli) the legacy result is returned unchanged and labelled. The chart itself is unchanged.
Why
Yoga detection is being rebuilt against the classical sources; unreviewed output is opt-in only.
api-2026-10-02Breaking changeView API →
/v1/birth-chart/v1/birth-chart/{profile_id}/v1/kundli
MODIFIED

Muhurat: Abhijit now states whether it is available that day

`muhurat.auspicious.abhijit` carries a new `available` field (additive), the same flag /v1/abhijit already returns.

Previously
On Wednesdays, when Abhijit Muhurat is not observed, the window was returned without saying so.
Now
`available: false` on those days; the computed window (`start_time`/`end_time`) is still returned unchanged. `available: true` otherwise.
Why
One availability rule across /v1/abhijit, /v1/calendar/day and /v1/panchang.
api-2026-10-02Backward compatibleView API →
/v1/calendar/day/v1/panchang
NEW

Rashifal life areas: career, money, relationships, wellbeing, fortune and travel, in English and Hindi

A daily Moon-sign reading organised by life area. Each area lists the transit factors the classical source states for it -- Phaladeepika XXVI.9-24 names the result of each graha in each house from the Moon sign, and those named results are what the areas are built from -- with every factor's verse, whether Vedha or the XXVI.30-32 qualifying rules cancel it today, and a detailed narrative in English and Hindi. Career, money and fortune carry a presentation level; today's colour and a gem reference are included.

Previously
The daily Rashifal reported each graha's verdict but no life areas, because grouping by area needs an interpretation step the per-graha rule does not contain.
Now
Two new PRO routes; the existing Rashifal routes are byte-for-byte unchanged. The source text was re-verified cell by cell against two printed Sanskrit editions before any interpretation was admitted. Statements about death, injury, named disease or the illness of others are never returned. There is no numeric score: the level is a labelled TathaAstu convention summarising the counted factors. Health, relationship and travel carry no level. Travel says plainly when no transit carries a travel indication. No lucky number: no admitted Jyotish source gives one.
Why
Clients asked for career, money, love, health, travel and fortune sections. The classical transit chapter names those areas in its per-house results, so the sections can be sourced rather than invented -- and where the source is thin (travel) or one-sided (health, relationships) the response says so instead of filling the gap.
rashifal-lifearea-1 / lifearea-level-1 / rashifal-lifearea-content-1Backward compatibleView API →
/v1/rashifal/vedic/life-areas/daily/v1/rashifal/vedic/life-areas/daily/all
FIXED

Panchang: current status for the requested day, include= on coordinates, localized Choghadiya and spellings

Four fixes. `current_status` and `lagna.current` describe the requested place's own Panchang day; `include=` works for latitude/longitude requests; Choghadiya segments in /v1/panchang/full carry `type_local`; Mula, Vishkambha, Sukarman, Shoola, Gara and ayana now find their localized names.

Previously
The current-moment fields used the server clock for any requested date and place; include= was ignored unless a stored location was used; Choghadiya type had no localized value in /full; five limb names and ayana missed their vocabulary because of a spelling difference.
Now
For a date that is not the place's current Panchang day (sunrise to next sunrise, local time), the current fields are null with applicable=false and reason NOT_CURRENT_PANCHANG_DAY; unknown include values are a 422; English values are unchanged.
Why
Reported inconsistencies between stored-location and coordinate requests and across languages.
api-2026-10-01Backward compatibleView API →
/v1/panchang/v1/panchang/full
DEPRECATED

POST /v1/kundli/premium-report removed; use POST /v1/kundli/birth-report

breaking

The legacy premium report endpoint has been removed. The Birth Report (POST /v1/kundli/birth-report) is the single birth-chart report, in 13 languages. /v1/kundli/teaser now points to it (`report_endpoint`).

Previously
Two birth-chart report endpoints with different designs and language support.
Now
One: /v1/kundli/birth-report. Requests to /v1/kundli/premium-report return 404.
Why
One professional report design; the legacy report had no active consumers.
api-2026-09-30bBreaking changeView API →
/v1/kundli/premium-report
MODIFIED

Locations: the native-script name is `name_native`

breaking

The native-script place name is returned as `name_native`. It was `name_local`, which now means 'in the requested language' everywhere in the API.

Previously
`name_local` held one fixed native form (e.g. Bengali for Kolkata) whatever lang was asked for.
Now
Read `name_native`. Place names are not translated, so locations carry no `name_local`.
Why
One meaning for the `_local` suffix across the API.
api-2026-09-30bBreaking changeView API →
/v1/locations/v1/locations/{location_id}
MODIFIED

One multilingual contract: canonical fields stay, `<field>_local` carries the language

breaking

With lang, every /v1 response keeps its canonical fields unchanged and adds `<field>_local` with the requested-language value. A value without a translation has no `_local` field (never an English stand-in); X-Localization-Missing counts them and i18n_detail=missing lists them. lang is accepted in the query on every endpoint and in the body of POST endpoints (the query wins). Signs, grahas and nakshatras on chart routes, weekdays, Sankranti and Shraddha names are now localized in every language that has them.

Previously
Some endpoints replaced `name`, `type`, month names, rashifal content or the compatibility report text with the translation for lang=hi (and only Hindi), so the same field meant different things by language; a body lang was ignored.
Now
Read `<field>_local` for display text; match on the canonical fields, which never change with lang. Example: name 'Diwali', name_local 'दिवाली'; type 'Kaal', type_local 'काल'.
Why
A client must never have to guess whether a field holds English or another language.
api-2026-09-30bBreaking changeView API →
/v1/panchang/v1/today/v1/festivals/v1/festivals/range/v1/festivals/month/v1/festivals/year/v1/vrat/v1/tithi/v1/nakshatra/v1/yoga/v1/karana/v1/choghadiya/v1/hindu-month/v1/calendar/day/v1/calendar/month/v1/day-context/v1/kundli/v1/kundli/teaser/v1/rashifal/vedic/v1/compatibility/v1/compatibility/report/v1/bulk/panchang/v1/bulk/festivals
FIXED

Impossible dates are a 422 invalid_date on every endpoint

A date parameter that is not a calendar date in YYYY-MM-DD (e.g. 2026-13-45) is answered 422 invalid_date, naming the parameter. Coordinates for which no day can be built are 422 calculation_error.

Previously
Such dates returned 500 on some endpoints and an empty 200 on others.
Now
Always 422 with a code; never a 500, never a silent empty answer.
Why
Found by the API-wide contract suite.
api-2026-09-30bBackward compatibleView API →
/v1/festivals/v1/festivals/range/v1/festivals/explain/v1/festivals/muhurat/v1/calendar/range/v1/compatibility/score/v1/kundli/teaser/v1/government-holidays/v1/day-context/v1/vrat/v1/muhurat/find/v1/events/find-dates
NEW

Every error has a stable `error` code; `message_local` in 13 languages

Every /v1 error body carries `error` (a stable code to switch on). With lang, it also carries `message_local` in en, hi, bn, de, es, fr, gu, kn, ml, mr, pa, ta or te. `detail` and `message` are unchanged.

Previously
Some errors had only a `detail` string; none were localized; some 500s were plain text.
Now
One error shape with a code; unhandled errors are JSON `internal_error`.
Why
Clients should branch on codes, not English sentences.
api-2026-09-30bBackward compatibleView API →
/v1/panchang/v1/festivals/v1/kundli/v1/compatibility/report/v1/kundli/birth-report
FIXED

Compatibility report honours lang (13 languages)

/v1/compatibility/report now answers in the language requested with ?lang= (or a body lang): en, hi, mr, gu, bn, ta, te, kn, ml, pa, de, es, fr. The compatibility calculation is unchanged.

Previously
?lang=hi was accepted but ignored, so every report was returned in English.
Now
The report text is in the requested language. English and Hindi are authored; the other languages are translations pending native review. An unsupported language returns 422, never English.
Why
A customer asking for Hindi received English.
api-2026-09-30Backward compatibleView API →
/v1/compatibility/report
NEW

Compatibility: koota breakdown, localized koota names and details

/v1/compatibility/report adds `kootas` (the eight Ashtakuta kootas with score and max) and the report metadata `lang` and `translation_status`, as on the Birth Report. Koota names, details, grades and Mangal verdicts carry `_local` fields in the 13 report languages.

Previously
The report had no koota breakdown; koota text existed only in English.
Now
Both reports share one language contract: the same 13 languages, lang in query or body (query wins), and 422 language_not_available_for_reports for any other language.
Why
Report content must be consistently localized, including the koota details.
api-2026-09-30bBackward compatibleView API →
/v1/compatibility/report/v1/compatibility
NEW

Birth Report: forecast_years (1-20)

The predictive Birth Report's year-by-year outlook now starts with the current calendar year and covers forecast_years years: 1-20, default 10. The response carries forecast.start_year, forecast.end_year and forecast.years.

Previously
The outlook always covered 2026-2035.
Now
A report generated in 2027 covers 2027-2036 by default; forecast_years=20 covers twenty years. Values outside 1-20 return 422. The lifetime view remains the mahadasha chapter.
Why
A forecast must start from the year in which the report is generated.
api-2026-09-30Backward compatibleView API →
/v1/kundli/birth-report
MODIFIED

Birth Report: client-ready layout and optional name

The Birth Report PDF now prints the client's name (optional `name`) on the cover and page headers, shows dates as '15 May 1990', fits the contents on one page and closes with a short 'About this Report'. Technical and internal status text has been removed from the pages.

Previously
The PDF carried technical notes (calculation version, methodology status) meant for internal use.
Now
Only information meaningful to the reader is printed; the calculation version stays in the PDF metadata.
Why
A report the client pays for should read as a finished astrology report.
api-2026-09-30Backward compatibleView API →
/v1/kundli/birth-report
NEW

Vedic Birth Report PDF in 13 languages

New POST /v1/kundli/birth-report returns a signed PDF link to the Birth Report generated from the frozen Calculation Engine (calculation 1.2.0). edition=predictive (default) adds life-area chapters, the current and next mahadasha and a ten-year outlook from Jupiter, Saturn, Rahu and Ketu transits; edition=calculation gives the chart, tables and traditional interpretation only. Languages: en, hi, mr, gu, bn, ta, te, kn, ml, pa, de, es, fr.

Previously
Birth-chart PDFs were available only from /v1/kundli/premium-report, in English and Hindi.
Now
The Birth Report is available in 13 languages. English and Hindi are authored; the other eleven are translations pending native review, and each report states this. The response carries lang, edition, pages and translation_status. Links, storage and retention follow the same rules as /v1/kundli/premium-report. /v1/kundli/premium-report is unchanged.
Why
Customers asked for full reports in regional Indian languages.
api-2026-09-30Backward compatibleView API →
/v1/kundli/birth-report
FIXED

Bulk Panchang honours lat/lon

breaking

/v1/bulk/panchang now correctly honours lat/lon when location_id is not supplied. location_id takes precedence when supplied; with neither, New Delhi (location_id 1) is used. Each response includes a `location` block identifying the location used.

Previously
Coordinate parameters could be ignored and the request could fall back to the default New Delhi location.
Now
location_id > lat/lon > New Delhi. lat and lon must be sent together (otherwise 422); an unknown location_id returns 404. The 100-date limit is unchanged.
Why
A Panchang request must be answered for the location it asks for.
api-2026-09-29Breaking changeView API →
/v1/bulk/panchang
MODIFIED

Vimshottari dasha years are 365.25 days

Dasha dates use a 365.25-day year (an engine convention, stated in dashas.vimshottari.year_length_days and year_length_basis). /v1/jyotish/daily now also reports engine_calculation_version.

Previously
A 365.256363-day (sidereal) year: dates up to about 0.8 day later over a 120-year cycle.
Now
Boundaries move by up to about 0.8 day; the sequence and proportions are unchanged.
Why
No classical text fixes the astronomical length of a dasha year; 365.25 is the convention reproduced by independent software. It is declared as a convention, not a classical rule.
calculation-1.1.0Backward compatibleView API →
/v1/kundli/v1/jyotish/daily
FIXED

Source citations corrected to the witnesses as read

Descriptive source strings only; no value changes. /v1/kundli: planetary_relationships.combustion.source, planetary_relationships.planetary_war.source and winner_criterion, varga_metadata.*.source. /v1/jyotish/daily: the provenance entries node_type, house_placement, vimshottari and vimshottari_antardasha.

Previously
Combustion cited 'BPHS ch. 48', a citation withdrawn from the provenance registry earlier the same day; planetary war, node type and house placement cited 'BPHS' without a locus, although no BPHS witness states the node type or whole-sign houses; the vargas cited the 97-chapter numbering.
Now
Combustion, node type and house placement are declared conventions; planetary war cites the verse that governs it and labels its one-degree orb and winner rule as engine conventions; the vargas and Vimshottari cite the governing edition and pages.
Why
Every customer-visible rule must name its real source or declare itself a convention.
calculation-1.1.1Backward compatibleView API →
/v1/kundli/v1/jyotish/daily
FIXED

Planetary-war winner follows the classical verse

breaking

planetary_relationships.planetary_war.wars[].winner is now Venus whenever Venus is at war, and otherwise the graha with the greater (more northerly) ecliptic latitude. winner_rule is "venus" or "northern_latitude"; each war now carries the two latitudes. If two grahas other than Venus have exactly equal latitude, winner is null with winner_reason.

Previously
The graha with the lower longitude was named the winner, a rule no source states.
Now
BPHS (Jha ed. pravrajya-yoga sl. 9 = 97-chapter 79.9): Venus wins north or south; otherwise the northern graha.
Why
The winner must come from the text; the one-degree war orb remains a declared engine convention.
calculation-1.2.0Breaking changeView API →
/v1/kundli
FIXED

A longitude exactly on a nakshatra or pada boundary belongs to the later one

planets[].nakshatra, planets[].pada, lagna.nakshatra/pada and the Vimshottari start lord and balance now place a longitude lying exactly on a boundary (for example 40.0, 120.0 or 240.0 degrees) in the nakshatra or pada that begins there.

Previously
Floating-point division put 15 of the 26 exact nakshatra boundaries and 70 of the 107 pada boundaries in the previous part; a Moon exactly at 240.0 degrees (the start of Mula) was dated from the end of Jyeshtha with a zero Mercury balance.
Now
The boundary belongs to the later part, as it already did at 0 degrees. Every longitude that is not exactly on a boundary gives the same result as before.
Why
A boundary is the start of the next nakshatra; found by the calculation-freeze acceptance suite. No difference in 2,000,000 random longitudes.
calculation-1.1.1Backward compatibleView API →
/v1/kundli
FIXED

Chara karakas: an exact degree tie follows BPHS

When two grahas tie exactly at full precision, the karaka they tie for carries planet: null with shared_by listing both, and the karaka left without a graha carries lapsed: true, read_from: "sthira_karaka". Exact ties practically never occur; every other chart is unchanged.

Previously
A fixed graha order broke the tie and gave the grahas consecutive karakas.
Now
BPHS Pathak ed. karakadhyaya sl. 19-20: the tied grahas share one karaka and the vacated karaka lapses.
Why
The governing edition states the rule; a fixed order was an engine decision.
calculation-1.2.0Backward compatibleView API →
/v1/kundli
FIXED

Functional benefic/malefic follows the BPHS per-lagna lists

breaking

planetary_nature.planets.*.functional.nature follows the lagna-by-lagna lists in BPHS (3rd/6th/11th lords malefic; 2nd/12th lords by association). New fields say how each value was reached (basis, source_listing, rule_id, witness_variants, loci).

Previously
6th/8th/12th lords were malefic and trikona-plus-dusthana owners were "mixed"; many results contradicted the source's own lists.
Now
Values: benefic, malefic, neutral, not_good, not_classified (the source rules the rule-based value out), yogakaraka, not_applicable. "mixed" is no longer returned.
Why
The source lists the result for every lagna; an explicit source statement outranks an inferred rule.
calculation-1.1.0Breaking changeView API →
/v1/kundli
FIXED

Planet dignity follows BPHS by degree, with Moolatrikona

breaking

planets[].dignity is now decided by sign AND degree (BPHS 3.49-54): exaltation portions and moolatrikona spans apply, and the new value "Moolatrikona" appears. Rahu and Ketu get no dignity, with the reason in the new dignity_reason field.

Previously
Sign-only: the Moon anywhere in Taurus and Mercury anywhere in Virgo were "Exalted"; moolatrikona was never reported; Rahu and Ketu were given exaltation and own signs.
Now
The Moon is Exalted at Taurus 0-3 and Moolatrikona from 3; Mercury Exalted at Virgo 0-15, Moolatrikona 15-20, Own Sign 20-30; each graha's moolatrikona span is reported. Rahu/Ketu: dignity null, dignity_reason gives why.
Why
The verses assign these by degree and give the nodes no dignity; the engine already implemented them correctly for Avastha, and /v1/kundli now uses that one implementation.
calculation-1.1.0Breaking changeView API →
/v1/kundli
FIXED

Argala: equal counts are indeterminate; grading and viparita argala added

breaking

An obstruction with as many grahas as the argala is reported indeterminate (obstructed: null, net_effect "indeterminate") because the sources make it turn on strength. Argala is graded (alpa/madhyama/purna) and classed (shubha/papa/mishra); three or more malefics in the 3rd give unobstructed viparita argala; the 5th is no longer "secondary".

Previously
Equal counts were reported as obstructed (true); obstructed was always a boolean.
Now
obstructed is true, false or null; new fields grade, nature, strength_test, node_reversal.
Why
BPHS (Pathak ed. ch. 7; Jha ch. 32; 97-chapter ch. 31): fewer OR weaker grahas do not obstruct.
calculation-1.1.0Breaking changeView API →
/v1/kundli
FIXED

Mangal (Kuja) dosha includes Mars in the 1st house

The BPHS Kuja condition now counts Mars in the 1st, 4th, 7th, 8th or 12th from the Ascendant; the cancellations (a benefic aspecting or joining Mars; both partners) are unchanged.

Previously
Mars in the 1st house was never reported as Kuja dosha (the house set was 12, 4, 7, 8).
Now
Mars in the 1st with no benefic aspect or association is reported present. The Sanskrit verse is now returned in sources.kuja_bphs.
Why
The Sanskrit (Chaukhamba ed. Jha, Stri-jataka sl. 48, and the 97-chapter recension 80.47) includes the 1st; a translation had dropped it.
dosha-v1.3.0Backward compatibleView API →
/v1/dosha
NEW

Rashifal: daily, weekly, monthly and yearly Moon-sign readings, in English and Hindi

A Moon-sign reading built from the classical transit rule. For each graha it reports whether it stands in a house Phaladeepika XXVI calls benefic counted from your rashi, and whether the paired Vedha house obstructs it, with the sloka on every line. Weekly, monthly and yearly are the same per-day verdict reported over a date range. Available for one rashi or all twelve, in English or Hindi, with `today` and `tomorrow` resolved against Asia/Kolkata.

Previously
There was no Rashifal in the API. A caller wanting a Moon-sign reading had to compute transits themselves and decide which houses counted, with no way to show a customer where a verdict came from.
Now
Four routes, all PRO. `period_type` is daily, weekly, monthly or yearly; weeks run Monday to Sunday and months and years are calendar ones, so any date inside the period you want will do. Every response separates `calculation` from `content`, and every statement carries its basis: PRIMARY_TEXT_VERIFIED for a classical verdict, ARITHMETICALLY_DERIVED for grouping equal days into a stretch, PRODUCT_SYNTHESIS for anything TathaAstu chose to present. Responses are 11-180 KB; `detail=days` adds the exhaustive per-day block for daily and weekly only.
Why
Customers asked for a horoscope product. What the classical source supports is a per-graha transit verdict, so that is what is served -- and the parts that are ours are labelled as ours rather than dressed as scripture. There is deliberately no overall score, no percentage, no ranking, no lucky number and no career/money/love/health breakdown: Phaladeepika XXVI establishes none of them, and every response says so in `not_included`. Phaladeepika XXVI also contains no weekly, monthly or yearly horoscope; it gives a verdict for a transit, and a transit has a duration. Reporting that duration is arithmetic. Arranging those durations into a period reading is TathaAstu's arrangement and is marked as such.
rashifal-vedic-1 / rashifal-period-1 / rashifal-content-2Backward compatibleView API →
/v1/rashifal/vedic/v1/rashifal/vedic/all/v1/rashifal/vedic/{period_type}/v1/rashifal/vedic/{period_type}/all
MODIFIED

Rashifal daily: each graha now carries the Phaladeepika XXVI qualifiers

Every graha in the daily reading gains a `modifiers` block reporting the four verses that act on a transit verdict: XXVI.25 the portion of the sign in which a graha produces its effect, XXVI.30 nullification by aspect from a contrary-natured or inimical planet, XXVI.31 dignity rescuing a graha in an untoward bhava, and XXVI.32 debilitation, an inimical sign or eclipsure voiding a favourable one.

Previously
The reading reported the benefic-house verdict with Vedha applied, and nothing about the qualifiers the chapter states after it.
Now
The qualifiers are evaluated independently and returned as a set, never collapsed into one winner. The chapter states no precedence between them, so where two apply the response carries both and marks the conflict unresolved rather than choosing. `inimical` is likewise open: Phaladeepika II.21-23 establishes the relationship scheme but XXVI.30 does not say at which layer it is judged, so both the naisargika and the compound reading are returned and `sensitive_to_grade_reading` flags where they differ. Additive only -- no field was removed or renamed, and a request that omits `lang` gets exactly the response it got before.
Why
The qualifiers materially change a verdict and leaving them out understated what the source says. Where the text is silent the response says so instead of quietly picking an answer that would look sourced because everything around it is.
rashifal-vedic-1Backward compatibleView API →
/v1/rashifal/vedic/v1/rashifal/vedic/all
NEW

Government Holidays: civil holiday calendars with the notification behind each date

A separate civil dataset of Indian government holiday calendars, by ISO 3166-2 region and year. Every date names the notification it comes from -- issuing authority, notification number and date, gazette reference where there is one, and the URL it was read at. Office, bank, restricted, optional and local lists are kept apart, with the audience, district or sub-region and any per-employee limit the document states. Each response also reports how far that region's year is attested, so an incomplete year is never served as if it were complete.

Previously
There was no government holiday data in the API. A caller needing a state's civil calendar had to read each state's notification themselves.
Now
2026 is published as dataset version 2026.r2, covering 28 states, 8 union territories and the Central Government list. Coverage is returned per region: 24 subjects are COMPLETE and 13 are PARTIAL, because a verification item is still open against them or their list rests on a copy that is not on a government host. Rows resting on such a copy are provisional: they are withheld unless include=provisional is passed, and are flagged when returned. Amendments are kept rather than overwritten -- several states moved Id-ul-Zuha from 27 to 28 May 2026 -- and as_of reconstructs what a calendar said on a given day. A row carries both the government's own wording and a canonical class for filtering across states; where the evidence does not settle a class, the canonical class is null rather than a guess.
Why
Customers need the civil calendar with its provenance, separately from the religious calendar. This dataset is civil only: it does not decide, adjust or annotate any Panchang or festival result, and no festival endpoint reads it. Government holiday lists remain civil evidence to the Festival Engine, exactly as before (see panchang-authority-model).
government-holidays-2026.r2Backward compatibleView API →
/v1/government-holidays/v1/government-holidays/regions/v1/government-holidays/coverage/v1/government-holidays/sources
NEW

Regional festivals from the Tamil, Kerala, Marathi, Gujarati and Telugu calendars

Twenty-five festivals added and five state dates corrected, each for the state it belongs to and each matching published state almanacs for 2025, 2026 and 2027. Every festival now returns the reason for its date and the rule or text it follows with observatory=true, including Holi.

Previously
Pongal, Bhogi, Mattu Pongal, Puthandu, Chitra Pournami, Ayudha Puja and the Tamil Hanumath Jayanthi, Ganesh Jayanti and Champa Shashthi (Maharashtra), Jalaram Jayanti and Bol Choth (Gujarat), Nagula Chavithi, Atla Tadde and the Telugu Hanuman Jayanthi were not returned. Kerala got the North Indian Maha Navami and Vijayadashami a day early. Holi had no reason, and thirteen rules cited only 'standard almanac practice'.
Now
Those festivals are returned for their state (location_id or region). A state's own date replaces the pan-Indian one only there. Tamil solar-month festivals follow the Tamil rule: the month begins on the day of the Sun's ingress if it is before sunset, otherwise the next day. Every rule states its rule in words and the published dates it reproduces.
Why
A comparison of Drik Panchang's 2027 state calendars with the API found these missing. Rules were accepted only if they reproduced the published date in all three years.
festival-engine-rules-b16Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/calendar/month/v1/day-context/v1/day-context/range/v1/panchang/full
FIXED

Religious festival dates follow the Panchang; government holiday lists are civil evidence only

The regional Panchang or Panjika now decides a religious festival date. Government holiday notifications are reported as civil-calendar corroboration and never replace the Panchang result. provenance.date_basis (observatory=true) is REGIONAL_PANCHANG, PANCHANG, RULE_COMPUTED, INHERITED, SERIES_DERIVED or GOVERNMENT_HOLIDAY, and provenance.civil_calendar lists the government dates that agree or differ.

Previously
The previous release (festival-engine-rules-b18) fitted some Odisha, West Bengal and Tripura rules to government holiday lists: Odisha Mahasthami 2026-10-18, Gamha/Jhulana Purnima 2026-08-27, Rama Navami 2026-03-27 and Holi 2025-03-15, where the Odia Panchang gives 10-19, 08-28, 03-26 (Smarta) and 03-14. West Bengal and Tripura Holi used a rule that gives 2027-03-23 where the Panchang gives 2027-03-22.
Now
Those dates follow the regional Panchang again, and the government dates are shown as civil differences. Assam's Bihus are backed by the Assamese Panjika (1 Magh, 1 Bohag, 1 Kati), which also settles Kati Bihu 2027 (10-19). Festivals attested only by a holiday list (Nuakhai, Karam Puja, Kharchi Puja, Bahuda Yatra) say so.
Why
PO correction: for a religious festival the Panchang and the regional Panchang are the authority; a government holiday date is civil evidence and must never silently override the religious rule.
festival-engine-rules-b19Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/calendar/month/v1/day-context/v1/day-context/range/v1/panchang/full
FIXED

Holika Dahan is decided by the Dharmasindhu rule, with its clause, window and variants

Holika Dahan now applies the Dharmasindhu Holika-nirnaya clause by clause to the location's Panchang: Purnima at pradosha on either day, Bhadra and its mukha/puccha, the 3.5-yama test, Pratipada's growth and the lunar-eclipse clause. convention_note gives the deciding clause, the dahan window and any reckoning that picks another day (variants).

Previously
Holika Dahan used the generic pradosha-vyapini rule, with the Bhadra and eclipse clauses only described. 2023 came out 2023-03-06, and no dahan window was given.
Now
2023 is 2023-03-07 (Panchang and Dharmasindhu agree). 2026 stays 2026-03-02 by the eclipse clause, with the dahan in the Bhadra-puccha. The almanac date 2026-03-03, from judging Pratipada's growth by total length, is listed under variants, and the government's 2026-03-03 appears as a civil date. Other years from 2020 to 2032 are unchanged.
Why
PO decision: decide Holika Dahan from the Dharmashastra rule and the Panchang's astronomical inputs, not from government holiday notifications, and state any regional or school variation explicitly.
festival-engine-rules-b20Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/calendar/month/v1/day-context/v1/day-context/range
FIXED

Odisha and Assam no longer receive Bengal's festivals; their own festivals added

East India's festivals are now resolved per state. West Bengal and Tripura keep the Bengali panjika; Odisha and Assam get their own festivals and dates. A bare region=EAST_INDIA still answers with the Bengali tradition, as before.

Previously
Odisha (Puri, Bhubaneswar) was given Poila Boishakh, Bihu, Kali Puja and Jagaddhatri Puja, and Bengal's Vijayadashami (2027-10-10; the Odia Dasahara is 2027-10-09). Assam had only Bohag Bihu. Dol Purnima, Bengal's Nag Panchami and Rabindranath Jayanti were missing. North India's Vat Savitri 2025 came out as 2025-05-27 (published 2025-05-26).
Now
Odisha: Dasahara on the aparahna Dashami, Jamai Shashthi, Savitri Amabasya, Gamha Purnima, Pana and Raja Sankranti. Assam: Bohag, Magh and Kati Bihu, with Bengal's Durga Puja days. West Bengal: Dol Purnima, Nag Panchami (Manasa Puja) and Rabindranath Jayanti added. Vat Savitri is taken at madhyahna. Every date matches the published state almanac for 2025-2027.
Why
Every Bengal-specific rule sat in the EAST_INDIA pack, so every East Indian state inherited Bengal's calendar.
festival-engine-rules-b17Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/calendar/month/v1/day-context/v1/day-context/range/v1/panchang/full
FIXED

Odisha, West Bengal, Assam and Tripura dated by their governments' holiday lists; per-date provenance

East Indian festivals were re-checked against the state governments' own holiday notifications for 2025 and 2026. Odisha now follows its government list, and West Bengal and Tripura have their own Holi; Assam gains Dol Jatra, Kali Puja and Karam Puja. With observatory=true every festival carries provenance.date_basis: PUBLISHED_DATE (a cited source for the caller's state lists that date), RULE_COMPUTED, INHERITED (another state's calendar) or SERIES_DERIVED.

Previously
Odisha got Bengal's Durga Puja days: Mahasaptami 2026-10-18 and Mahanavami 2026-10-20 (the Government of Odisha lists 10-17 and 10-19), and Mahasthami 2026-10-19 (government 10-18). Odisha's Rama Navami was 2026-03-26 (government 03-27) and Holi 2026-03-03 (government 03-04); West Bengal and Tripura also had Holi 2026-03-03 (their governments list 03-04). Nuakhai, Dola Purnima, Jhulana and Rahas Purnima, Bahuda Yatra, Prathamasthami, Pahili Raja, Kharchi Puja and Karam Puja were missing.
Now
Every date listed in the Odisha, West Bengal, Assam and Tripura 2025/2026 government lists for these festivals is returned. Where the government and Drik Panchang differ, the government date is followed and the disagreement is recorded in the rule's authority.
Why
PO directive: government and state sources first, regional panjika second, Drik third; a computed or inherited date is never presented as a published one.
festival-engine-rules-b18Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/calendar/month/v1/day-context/v1/day-context/range/v1/panchang/full
FIXED

Sankranti on its punya-kala day; eleven festivals added; Purnima named by month

Sankranti is now dated from the moment the Sun enters the sign, at the caller's own location, by the Dharmasindhu punya-kala rule. Eleven festivals that published almanacs list were added. The monthly Purnima carries its month name. With observatory=true, every one of these returns the reason for its date and the text it follows.

Previously
A Sankranti was put on the first sunrise after the ingress, so every afternoon or evening ingress came out a day late: Makar Sankranti 15 Jan 2026 (ingress 14 Jan 15:07), Karka 17 Jul 2026, Tula 18 Oct 2026, Mesh 15 Apr 2027 and seven more in 2026-2027. Yamuna Chhath, Swaminarayan Jayanti, Narada Jayanti, Gayatri Jayanti, Vishwakarma Puja, Pitru Paksha begins, Saraswati Avahan, Saraswati Puja, Govatsa Dwadashi, Kali Chaudas and Kansa Vadh were not returned. Purnima was displayed as "Purnima".
Now
Ingress by day: that day. At night: before ardharatra (the middle of the night) the day that ended, after it the day that follows; Makara at night the following day unless within 3 ghatis of sunset; Karka at night the preceding day. Every Sankranti of 2024-2027 for New Delhi matches Drik Panchang except Vrishabha 2025 (ingress 00:12, ardharatra 00:17), where the reason field states both dates. The eleven festivals match Drik Panchang New Delhi in each of 2024, 2025, 2026 and 2027. Purnima display_name is "Pausha Purnima", "Adhika Jyeshtha Purnima" etc., also as purnima_name.
Why
Dharmasindhu, Sankranti-nirnaya: the festival is kept on the day of the punya-kala, not the day of the next sunrise. The missing festivals were found by comparing Drik Panchang's full New Delhi calendar for 2026 and 2027 with the API.
festival-engine-rules-b15Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/calendar/month/v1/day-context/v1/day-context/range/v1/panchang/full
FIXED

Festival dates checked against published almanacs for 2026-2027; about 75 festivals added

Every festival and vrat for 2026 and 2027 was compared with published almanac and government dates for North, South, East and West India, Nepal, Kashmir and Sri Lanka. Missing festivals were added with their regional scope, wrong dates were corrected, and the older festival list inside /v1/panchang/full now follows the same dates.

Previously
Rishi Panchami, Anant Chaturdashi, Nag Panchami, Radha Ashtami, the monthly Vinayaka Chaturthi and Masik Shivaratri and about seventy others were missing from /v1/festivals and the calendar. /v1/panchang/full put Rishi Panchami on 16 Sep 2026 (published 15 Sep), Ganesh Visarjan on 21 Sep 2026 (published 25 Sep) and Onam on 23 Sep 2026 in every region. Sankashti Chaturthi came out a day late on 6 May 2026 and 23 Jul 2027. Kali Puja 2027 was given as 29 Oct (published 28 Oct). Onam 2027 came out on two days. Ekadashi entries had no name.
Now
Those festivals are returned on their published dates, with state packs for Maharashtra, Gujarat, Tamil Nadu, Kerala, Karnataka, Telangana and Andhra Pradesh. Ekadashi entries carry ekadashi_name ("Aja Ekadashi"). Sri Lanka Vesak follows the gazette (19 May 2027). Where published almanacs disagree with each other, the rule's source_authority lists the dates it was checked against.
Why
The festival engine only knew the festivals it had rules for, and the older sunrise-tithi list filled the gaps with the wrong day for any festival kept at madhyahna, pradosha or nishita. Two evaluator defects were also found: a Chaturthi spanning three civil days skipped the middle day's moonrise, and a nakshatra covering two sunrises matched both days.
festival-engine-rules-b10-b11Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/calendar/month/v1/vrats/v1/panchang/v1/panchang/full
FIXED

Panchang for a named location reports that location's own region

location.region and location.subdivision follow the location_id asked for, as the festival rules already do, for the locations computed live as well as the precomputed ones.

Previously
For the twelve locations computed live the label came from coordinate rectangles: Puri (EAST_INDIA in /v1/locations) was labelled NORTH_INDIA and Jammu KASHMIR, and subdivision was null.
Now
Puri is EAST_INDIA and Jammu NORTH_INDIA, matching /v1/locations and the festival packs applied. Requests with coordinates only still take the region of the coordinates.
Why
A response must not name a different region from the rules it applied.
panchang-region-labelBackward compatibleView API →
/v1/panchang/v1/panchang/today/v1/panchang/tomorrow/v1/panchang/yesterday/v1/calendar/day
FIXED

Idle database connections are released when their worker thread ends

The API kept one database connection per worker thread and never released it when the thread retired, so idle connections accumulated until the database refused new ones.

Previously
On 2026-09-14 the API held all 151 connections the database allows, every one idle, the oldest almost eight hours old. New connections were refused with "Too many connections": some requests returned 500, and the website could not sign users in.
Now
A connection whose thread has ended is closed the next time a connection is opened. Forty short-lived threads now leave three to five connections open instead of forty.
Why
Worker threads are recycled: an idle one retires and another starts. The registry that lets shutdown close every connection kept a reference to the retired thread's connection, so its socket stayed open on the server.
database-thread-connection-reapingBackward compatibleView API →
FIXED

/v1/vrat returns vrats instead of an empty list for every date

/v1/vrat now resolves observances through the same canonical festival rules as /v1/festivals.

Previously
It joined a table that was never populated, so every date returned an empty vrats list with count 0. That included 6 Jul 2025, Devshayani Ekadashi, which /v1/festivals reported correctly.
Now
July 2025 returns 7 vrats: two Ekadashis, two Pradosh, Purnima, Sankashti and Amavasya. The code, category and name fields are unchanged; rule_code and confidence are added.
Why
One observance must not have different dates depending on which endpoint is called.
festivals-v2.1.1Backward compatibleView API →
/v1/vrat
NEW

Upagraha API: the five aprakasha grahas and the five kalavelas, with their verses

New Pro endpoint. POST /v1/upagraha returns Dhuma, Vyatipata, Parivesha, Indracapa and Upaketu, and Kala, Mrityu, Ardhaprahara, Yamaghantaka and Gulika, each with sign, degree and house, and the Sanskrit verses they come from.

Previously
No endpoint returned the upagrahas. /v1/kundli returned Gulika and Mandi only.
Now
The aprakasha grahas follow BPHS ch. 3 sl. 53-56 and reproduce the Pathak commentary's worked example to the arc-second. The kalavelas follow BPHS ch. 4 sl. 1-4 with the start and end of each part and their local times. Two verses damaged in the scan are returned as scanned and flagged, with the commentary's reading beside them.
Why
The dosha verses refer to Mandi, and the upagrahas are cited throughout BPHS. Sources are the Sanskrit text ed. G.D. Pathak and R. Santhanam's translation; a note in Santhanam's edition that contradicts his own translation is recorded, not followed.
upagraha-v1.0.0Backward compatibleView API →
/v1/upagraha
FIXED

Jaffna and Kandy receive Sri Lankan festivals, including Vesak

Locations 26 (Jaffna) and 27 (Kandy) are now treated as Sri Lanka and receive the SRI_LANKA rule pack.

Previously
Both carried region GLOBAL, which matches no rule pack, so they got only the universal rules. Colombo returned FESTIVAL_VESAK on 2025-05-12; Jaffna and Kandy did not.
Now
All three Sri Lankan locations return FESTIVAL_VESAK on the gazetted dates 2025-05-12, 2026-05-01 and 2027-05-20.
Why
Vesak is Sri Lanka's principal Buddhist observance and a national holiday. The same correction was applied to every database that holds locations.
festivals-v2.1.1Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/festivals/month/v1/festivals/year
FIXED

Skanda Shashthi moved off a Krishna Shashthi in the engine's festival table

The Panchang engine's internal festival table placed Skanda Shashthi on Ashwin Krishna 6 and omitted it from Kartik Shukla 6. It is now on Kartik Shukla 6, like every other month's.

Previously
Internally, 12 Oct 2025 (Krishna 6) carried Skanda Shashthi and an observance timing block, and 27 Oct 2025 did not carry the festival. No current response field exposed either: /v1/panchang/full lists Skanda Shashthi only as the monthly 'Skanda Shashthi Vrat', which was already on the correct Shukla 6 days.
Now
The internal table is consistent with the monthly vrat. Responses are unchanged today; the correction is made before the festival name is surfaced rather than after.
Why
A normalisation of the Kartik rows moved this one into the Krishna block. Checked across 2024-2028: the name moved on those five dates and nothing else in the engine output changed except the timing block that existed only because of it.
panchang-v2.1.2Backward compatibleView API →
/v1/panchang/full
NEW

Shraddha API: Mahalaya Paksha dates and the aparahna kala

Two new free endpoints. /v1/shraddha/mahalaya returns the fifteen tithis of Mahalaya (Pitru) Paksha with the civil day each shraddha falls on at your coordinates, Kutapa muhurta, Shastrahata Chaturdashi, the Bharani and Magha occasions and the Kanya-to-Vrischika extension. /v1/shraddha/kala returns aparahna, Kutapa, Rauhina and the tithis present in one day's aparahna.

Previously
No endpoint published shraddha timing. The Panchang engine computed a Pitru Paksha flag and a per-tithi table internally, and both were wrong: the flag ran for two months, and the table named classes of deceased for tithis where no source does.
Now
The day rule is the Dharmasindhu's, 'Paarvana Shraddha has to be of Aparaahna Praapti' (ch. 26), and every rule in the response carries its verbatim quotation, chapter and URL. Where a tithi touches the aparahna on two days the text gives no ruling, so observance_date is null with REQUIRES_SOURCE_CERTIFICATION, and the day of greater overlap is returned separately, labelled as convention.
Why
Checked against Drikpanchang's New Delhi lists for 2023-2025: every date the engine decides matches, and in all five two-day cases the almanac's date is the greater-overlap day. The API still does not promote that convention to a rule the source did not state.
shraddha-v1.0.0Backward compatibleView API →
/v1/shraddha/mahalaya/v1/shraddha/kala
FIXED

Coordinates in Uttar Pradesh, Bihar and Tamil Nadu are no longer labelled Nepal or Sri Lanka

The region inferred from coordinates asks the timezone boundary which country the point is in before the regional rectangles decide.

Previously
Lucknow, Ayodhya, Gorakhpur, Darbhanga and Siliguri were labelled NEPAL and Rameswaram SRI_LANKA, because the rectangles for those regions also cover Indian ground. Their times were already correct.
Now
They are labelled with their Indian region. Points in Nepal and Sri Lanka keep NEPAL and SRI_LANKA; every other point is labelled as before.
Why
A label must not name the wrong country; the clock was already derived the same way.
detect-region-polygonBackward compatibleView API →
/v1/panchang/v1/timings/v1/inauspicious/v1/sun/v1/festivals/muhurat
FIXED

Polar day and polar night return the panchang instead of an error or nulls

Above the polar circles around the solstices, coordinate requests now return tithi, nakshatra, yoga and karana, and say plainly that there is no sunrise or sunset that day.

Previously
Murmansk failed for about 99 days a year and McMurdo for about 243 with HTTP 500 (SwissEph file not found). After that was fixed, the same requests returned HTTP 200 with tithi, nakshatra, yoga and karana all null. Some days also reported a fabricated sunrise of 06:30 and sunset of 18:00.
Now
Longyearbyen and McMurdo on 21 Jun 2025 and Tromso on 21 Dec 2025 return all four limbs with their start and end times. Sunrise and sunset read 'N/A (midnight sun)' or 'N/A (polar night)', and /v1/panchang/full carries polar_state. Timings reckoned from sunrise, such as Rahu Kaal, Choghadiya and Hora, are not returned because they do not exist on those days. Ordinary high-latitude days, such as Helsinki or Reykjavik, are unchanged.
Why
Tithi, nakshatra, yoga and karana are defined by the Sun-Moon angle, so they are exact at any latitude. Where the Sun rises, answers were verified identical before and after, across 28 locations on six continents.
panchang-v2.1.3Backward compatibleView API →
/v1/panchang/v1/panchang/lite/v1/panchang/full
FIXED

Pitru Paksha no longer runs through Diwali; five observances back on their day

Krishna-paksha festival keys were a month out of step with the amanta month the engine computes. Pitru Paksha, Maha Shivaratri, Ekadashi names, Shani Jayanti, Hariyali Amavasya, Sakat Chauth, Mauni Amavasya, Ahoi Ashtami and Avidhava Navami are corrected.

Previously
Pitru Paksha was reported for 8-21 October 2025 as well as 8-21 September, marking the Diwali fortnight as a shraddha period. 21 September 2025 returned no Sarva Pitru Amavasya. Maha Shivaratri appeared twice a year; each krishna Ekadashi carried two names; Shani Jayanti, Hariyali Amavasya and Sakat Chauth fell a month late; Ahoi Ashtami appeared a second time on Kartik Shukla 8; Avidhava Navami fell on Shukla 9, before Pitru Paksha began.
Now
Pitru Paksha is amanta Bhadrapada Krishna only. Sarva Pitru Amavasya is 21 Sep 2025, Maha Shivaratri once a year in amanta Magha, one Ekadashi name per day, Shani Jayanti 27 May 2025, Hariyali Amavasya 24 Jul 2025, Sakat Chauth 17 Jan 2025, Avidhava Navami 15 Sep 2025. The pitru_paksha block now carries the Dharmasindhu's stated phala per tithi, and names a class of deceased only for Chaturdashi.
Why
Amanta month N krishna paksha is purnimanta month N+1. Most krishna rows were keyed by the purnimanta name after a partial migration. Every changed date was checked across 2024-2028.
panchang-v2.1.1Backward compatibleView API →
/v1/panchang/full
FIXED

Every location in /v1/locations is served; unknown location ids return 404

breaking

12 of the 27 advertised locations returned 404 from /v1/panchang. They are now computed from their stored coordinates. An unknown location_id is refused instead of being answered with another city's day.

Previously
Puri, Jammu, Jaipur, Lucknow, Bangalore, Kochi, Tirupati, Pune, Pokhara, Jaffna, Kandy and one Delhi id returned 404 'No pre-computed data'. location_id=0 returned 200 with Kolkata's panchang, under Kolkata's coordinates.
Now
All 27 ids return 200 with a real tithi on both endpoints. Unknown ids, such as 0, -1, 28 and 999, return 404 naming /v1/locations. Requests using lat and lon are unaffected.
Why
/v1/festivals already served all 27 ids by computing from coordinates. Answering an unknown id with a different city is a wrong answer that looks right.
panchang-v2.1.3Breaking changeView API →
/v1/panchang/v1/panchang/lite
FIXED

Gulika and Mandi for births between midnight and sunrise

Gulika and Mandi are now counted from the vara the birth belongs to, the day that began at the preceding sunrise, instead of the civil weekday.

Previously
A birth at 03:00 on a civil Wednesday in Delhi was treated as Wednesday night, so Saturn's part was taken as the seventh of the night. It belongs to Tuesday's vara, where Saturn's part is the first, and special_lagnas.gulika_mandi reported the wrong longitudes and weekday.
Now
gulika_mandi.weekday is the vara, and a new weekday_basis field says so. Day births and births between sunset and midnight are unchanged; every birth between midnight and sunrise can change.
Why
A vara runs sunrise to sunrise, and BPHS counts the eighth parts from its lord. Found while building /v1/upagraha and checked on Delhi births at 03:00, 05:30, 12:00 and 23:00.
kundli-special-lagna-fixBackward compatibleView API →
/v1/kundli
FIXED

Eclipse visibility accepts an IANA timezone

tz now takes an IANA zone (tz=Asia/Kolkata) as well as a number of hours.

Previously
tz accepted only a number, so tz=Asia/Kolkata was a 422 and the only working call returned local times and sutak in UTC.
Now
local_times and sutak are in the zone given, with the offset taken on the eclipse date; location.tz echoes the zone. Omitting tz still means UTC.
Why
Every other endpoint takes tz as an IANA zone.
eclipse-visibility-tzBackward compatibleView API →
/v1/eclipse/visibility
NEW

Dosha API: Mangal dosha and the curse yogas, each with its verse

New Pro endpoint. POST /v1/dosha returns Kuja (Mangal) dosha by BPHS 80.47-49 and Phaladeepika XI.3, with the partner rule of BPHS 80.49, and the eight serpent's-curse and eleven father's-curse combinations of BPHS ch. 83, each with its Sanskrit verse and condition-by-condition result. Kaal Sarp, and Sade Sati for a date, are returned separately as conventions.

Previously
Dosha results were only available inside other responses, without the verse behind them, and nothing separated doshas stated in the classical texts from later popular ones.
Now
The curse combinations are judged by the Sanskrit text (ed. G.D. Pathak). In six combinations R. Santhanam's English translation reads the verse differently; that reading is evaluated and returned beside the verdict as translation_variant. Conditions a chart cannot decide, such as a planet 'devoid of strength', come back null with the reason, never guessed. Kaal Sarp and Sade Sati are under conventions with classical_source null: neither appears in BPHS or Phaladeepika.
Why
Every rule is cited from a book, not a website. No Sanskrit mula was found for BPHS 80.47-49 in the Pathak edition, so the Mangal rule cites the translation and says so in sanskrit_status.
dosha-v1.1.0Backward compatibleView API →
/v1/dosha
NEW

Dosha API: the rest of BPHS ch. 83 and every remedy it prescribes

/v1/dosha adds the curses of the mother, brother, maternal uncle, a Brahmin, the wife and a departed spirit -- 55 combinations -- and a remedies block with each remedy's Sanskrit verse.

Previously
Only the serpent's and father's curses were returned, and the serpent-curse combination that names Mandi was always indeterminate.
Now
Every combination carries its Pathak verse, and R. Santhanam's reading where it differs (18 combinations). Mandi is now decided when Gulika and Mandi fall in the same house. Remedies are returned as what the verse prescribes, marked as text and not advice, with the chart's status for each curse beside it. Readings the text leaves open are marked, not guessed.
Why
Completes the chapter /v1/dosha already cited. BPHS ch. 84's graha-shanti text was not located in the Sanskrit edition and is not included.
dosha-v1.2.0Backward compatibleView API →
/v1/dosha
FIXED

Compatibility: the dasha domain is computed again instead of returning an error text

The dasha-sync domain of every compatibility result compares both people's running Mahadasha and Antardasha again.

Previously
The domain always scored 3/10 and its reason read "Dasha sync estimated — 'list' object has no attribute 'keys'"; the same text appeared in the long-term narrative.
Now
The reasons name both Mahadashas and Antardashas and when they end, and the score follows their relationship. Overall scores can move by up to a few points.
Why
An internal call used the wrong arguments and the error was swallowed into the response.
matchmaking-dasha-sync-fixBackward compatibleView API →
/v1/compatibility/v1/compatibility/report/v1/compatibility/score
FIXED

Calculators answer for all 27 advertised locations

The single-limb calculators, bulk Panchang and the calendar day view now compute a location's day from its own coordinates when no precomputed row exists, as /v1/panchang already did.

Previously
For Jaipur, Lucknow, Kochi, Tirupati, Puri, Pune, Pokhara, Jammu, Jaffna, Kandy and location ids 16 and 19, /v1/tithi, /v1/nakshatra, /v1/yoga, /v1/karana, /v1/ganda-mool and /v1/bhadra answered 404 "No data for <date>", /v1/bulk/panchang silently dropped the dates, and /v1/calendar/day returned 500.
Now
They answer 200 with the same values the precomputed rows give for the same coordinates (Delhi as location 1 and location 16 agree limb for limb). An unknown location_id is still a 404.
Why
Twelve of the locations /v1/locations advertises carry no precomputed rows.
calculators-live-fallbackBackward compatibleView API →
/v1/tithi/v1/nakshatra/v1/yoga/v1/karana/v1/ganda-mool/v1/bhadra/v1/bulk/panchang/v1/calendar/day
FIXED

Births outside India: the time of birth is read in the birth place's timezone

/v1/compatibility/report now uses each person's timezone field; /v1/compatibility/score gains optional bride_tz and groom_tz; /v1/kundli/teaser gains an optional tz; /v1/kundli/premium-report accepts an optional timezone. All default to Asia/Kolkata, so existing Indian requests are unchanged.

Previously
These endpoints read every time of birth as IST. A 06:10 birth in London was charted as 00:40 London time (Libra lagna instead of Sagittarius); Nepal births were 15 minutes off. The teaser also said "Your current Unknown-None period" for a birth date later than today.
Now
The chart is cast at the local time in the zone given (DST included); an unknown zone is a 422. A future birth date reports the dasha running at birth.
Why
The timezone was hard-coded where the rest of the API accepts one.
birth-timezone-fixBackward compatibleView API →
/v1/compatibility/report/v1/compatibility/score/v1/kundli/teaser/v1/kundli/premium-report
FIXED

Bhadra is reported on Vishti karana days

/v1/bhadra derives the karana type from the karana number, as /v1/karana does.

Previously
is_bhadra was false and karana_type_num null on every day for every location, because the stored karana type is empty.
Now
On a Vishti day (e.g. 2026-09-03, Delhi) is_bhadra is true and karana_type_num is 7.
Why
The endpoint compared an empty column with 7.
bhadra-karana-typeBackward compatibleView API →
/v1/bhadra
FIXED

Avastha: Rahu and Ketu dignity is null

planets.Rahu.dignity and planets.Ketu.dignity are null instead of the string "undefined".

Previously
The field held the string "undefined".
Now
The field is null; not_computed.nodes_dignity_avasthas explains why.
Why
BPHS ch. 3 gives the nodes no exaltation or moolatrikona, and a string looked like a client bug.
avastha-v1.0.0Backward compatibleView API →
/v1/avastha
NEW

Avastha API: the planetary states of BPHS ch. 45, with the verse behind each

New Pro endpoint. POST /v1/avastha returns the Baladi, Jagradadi, Deeptadi, Lajjitadi and Shayanadi avasthas of every graha, with Drishti / Cheshta / Vicheshta, and the natural, temporary and compound relationships of BPHS ch. 3 they depend on.

Previously
No endpoint returned graha avasthas or the five-fold planetary relationships.
Now
Every state carries its verse in Sanskrit. The natural relationships are computed from the verse's formula and match the table the Pathak edition prints. The Shayanadi arithmetic reproduces both worked examples (Pathak's and Santhanam's). Where the editions read a rule differently -- Jagradadi, the Deeptadi names, Kshobhita, the watery signs, elapsed or running ghati -- each reading is returned.
Why
The avasthas are classifications, so they can be computed exactly once the reading is fixed; the editions do not fix one, so none is chosen silently. Effect verses are returned as text, not as a prediction. Optional name_syllable_number (1-5) enables the Cheshta, because the syllable table is not legible in either edition.
avastha-v1.0.0Backward compatibleView API →
/v1/avastha
NEW

Ashubha Janma API: gandanta, Abhukta Mula, eclipse and the other inauspicious births of BPHS

New Pro endpoint. POST /v1/ashubha-janma checks a birth moment against BPHS ch. 85-96: Amavasya, the six parts of Krishna Chaturdashi, Vishti karana, Vyatipata yoga, a kshaya tithi, tithi, nakshatra and lagna gandanta, Abhukta Mula, sankranti and solar or lunar eclipse, each with its junction time and Sanskrit verse.

Previously
/v1/ganda-mool only reported whether the Moon's nakshatra was one of six, with no window, no junction time and no source.
Now
Gandanta is measured in ghatikas from the junction instant: two either side for tithi and nakshatra, half for lagna. Abhukta Mula is five ghatikas before and eight after the Jyeshtha-Mula junction, as both Sanskrit texts read; Santhanam's six is returned as a variant. An eclipse below the horizon, or only penumbral, is returned indeterminate. Family nakshatra and birth order are evaluated only when supplied. Yamaghanta, Dagdha yoga and Pata are listed as not computed because BPHS does not define them. /v1/ganda-mool is unchanged.
Why
The chapters were read in the Sanskrit of the 97-chapter recension and the Chaukhamba edition with Pt. Dev Chandra Jha's Sudha commentary; where they differ, both readings are returned. Remedies are reported as text, not advice.
ashubha-janma-v1.0.0Backward compatibleView API →
/v1/ashubha-janma
NEW

Ashtakavarga API: the point table decoded from the verses, with reductions and Pinda

New Pro endpoint. POST /v1/ashtakavarga returns the Bhinnashtakavarga of the seven grahas and the Lagna with the contributors of every point, the Samudaya with its bands, and Trikona and Ekadhipatya reduction with Rashi, Graha and Yoga Pinda.

Previously
No endpoint returned Ashtakavarga.
Now
The table is decoded from the karana verses of BPHS 66 and checked three ways: every house against its count verse, the fixed totals (48, 49, 39, 54, 56, 52, 39 and 49), and Santhanam's worked example, reproduced exactly. The editions read the Ekadhipatya rule differently, so all three readings are returned; the primary one is the verse's wording that reproduces the example. The Samudaya adds all eight vargas (386), with the seven-graha 337 as a variant.
Why
Ashtakavarga is pure arithmetic on the chart, so it can be verified completely. Chapters 70-71, which time a parent's death and derive longevity from the points, are not computed.
ashtakavarga-v1.0.0Backward compatibleView API →
/v1/ashtakavarga
NEW

World festivals: six Jewish dates corrected, seven traditions added

The Hebrew calendar is now computed exactly. The world calendar adds Buddhist, Jain, Baha'i, Zoroastrian, Shinto and East Asian festivals, and expands Orthodox and Jewish coverage.

Previously
A hand-entered correction moved Rosh Hashana 5786 off its real date, 2025-09-23, and a month-count approximation put six dates wrong across 2024 and 2025. The table covered five religions, 943 rows and 139 festivals; Orthodoxy had two rows.
Now
1,851 rows and 270 festivals across 11 traditions, 2024-2030. The Hebrew engine matches an independent implementation on all 900 dates tested. Fixed Orthodox feasts are listed for both Orthodox calendars.
Why
A world festival calendar missing most of the world's traditions was not one. Tibetan feasts are deliberately still absent, because dates that are quietly a day out would be worse than none.
world-festivals-v2.0.0Backward compatibleView API →
/v1/festivals/world/v1/festivals/world/religions/v1/festivals/world/upcoming
FIXED

World festivals: Advent on Sundays, Bandi Chhor on Diwali, unique Orthodox ids

An audit of the Christian, Sikh and Orthodox rows corrected three calendar defects and one id collision.

Previously
None of the 84 Advent rows fell on a Sunday. Bandi Chhor Divas was wrong in all seven years, a whole month late in 2025, 2027, 2028 and 2030. Hola Mohalla 2029 fell a month after Holi. Some Orthodox rows reused ids from the Western Christian calendar, so those ids returned two rows.
Now
All 84 Advent rows are Sundays. Sikh dates come from the lunisolar calendar, which skips intercalary (adhika) months. Orthodox ids use orthodox_<name>, and the long-standing orthodox_easter and orthodox_pentecost are unchanged. Islamic dates are deliberately untouched.
Why
Each defect came from approximating a calendar instead of computing it. Before deploying, the engines were confirmed to reproduce production exactly, so the changes are only the fixes.
world-festivals-v2.1.0Backward compatibleView API →
/v1/festivals/world/v1/festivals/world/religions/v1/festivals/world/upcoming
FIXED

Karva Chauth returns, and Sankashti Chaturthi occurs once a month

Moonrise-governed Chaturthi now follows all four branches of the Dharmasindhu Caturthi-nirnaya, not just the first.

Previously
Karva Chauth was absent for all of 2025. Sankashti Chaturthi appeared 11 to 14 times a year, sometimes on two consecutive days.
Now
Tithi at moonrise on one day: that day. At moonrise on both days: the earlier day, joined with Tritiya. At moonrise on neither: the later day. Karva Chauth 2025 is 10 October.
Why
Dharmasindhu, Caturthi-nirnaya (printed p.11). When the tithi touched moonrise on neither day, the old code returned nothing; when it touched both, it matched twice.
festivals-v2.1.0Backward compatibleView API →
/v1/festivals/v1/festivals/range/v1/festivals/month/v1/festivals/year/v1/vrat
NEW

Tara Asta & Tara Udaya API (PRO)

Two new PRO endpoints calculate Tara Asta (heliacal setting) and Tara Udaya (heliacal rising) for Shukra (Venus) and Guru (Jupiter), for the caller's own coordinates, with the exact event instant in UTC and local time.

Previously
The API had no Tara Asta/Udaya capability. The nearest thing was chart combustion in the birth-chart endpoints, which measures a different quantity — ecliptic longitude separation — and is the same everywhere on Earth.
Now
/v1/tara/events searches a bounded date range, up to 366 days, and returns every Asta/Udaya crossing with event_time_utc, event_time_local, astronomical_date and the observational bracket. /v1/tara/state answers whether a planet is Asta at one moment. Coordinates are required and drive the calculation; `tz` affects presentation only.
Why
Tara Asta is a local horizon phenomenon, so it cannot be served from a single national result. New Delhi and Lima differ by about a week for Shukra Asta 2026, and London's falls five weeks earlier still. Every response carries its Surya Siddhanta IX provenance, and astronomical_date is documented as the civil date containing the calculated instant rather than any almanac's published date.
tara-v1.0.0Backward compatibleView API →
/v1/tara/events/v1/tara/state
MODIFIED

Today is the caller's date, not the server's

These endpoints derive the reference date from the requested timezone, or from the coordinates when no `tz` is given.

Previously
The date came from the API host's clock, which runs Asia/Kolkata. A New York caller was handed tomorrow's panchang for the whole of their evening.
Now
Explicit `tz` decides the date; otherwise the coordinates do; otherwise the server clock still answers, so callers sending neither are unaffected.
Why
Today is a property of the caller, not of the server.
panchang-v2.1.0Backward compatibleView API →
/v1/today/v1/panchang/today/v1/panchang/tomorrow/v1/panchang/yesterday/v1/panchang/now
MODIFIED

Timezone abbreviations are refused

breaking

`tz` must be an Area/Location IANA name, or UTC.

Previously
`EST`, `MST` and `HST` were accepted. They exist in the timezone database as fixed-offset legacy entries that never apply daylight saving, so tz=EST returned -05:00 in July — an hour wrong for two thirds of the year, with nothing in the response saying so.
Now
Those names return 422 with an explanation. Use `America/New_York`, `Europe/Paris`, `Asia/Kolkata`.
Why
A silently wrong hour is worse than a rejected request.
panchang-v2.1.0Breaking changeView API →
/v1/panchang/v1/panchang/full/v1/festivals/v1/festivals/muhurat
NEW

Regional Panchang support

Coordinates now resolve their own IANA timezone, so a request carrying lat/lon is answered on that location's civil clock with daylight saving applied. An optional `tz` accepts an IANA zone name and overrides the lookup.

Previously
The UTC offset came from the `region` parameter and was +05:30 everywhere except Nepal. Locations outside South Asia were answered on an Indian clock, and Paris and New York could fail outright.
Now
Explicit `tz` wins; otherwise the zone is derived from lat/lon; otherwise the region default applies unchanged. Every response reports the zone used in `location.timezone`, including its UTC offset, abbreviation and whether DST was in force.
Why
Panchang is computed from the observer's sunrise, so a caller outside India was being given astronomically correct instants stamped on the wrong clock.
panchang-v2.1.0Backward compatibleView API →
/v1/panchang/v1/panchang/lite/v1/panchang/full/v1/panchang/today/v1/panchang/tomorrow/v1/panchang/yesterday/v1/panchang/now/v1/today/v1/festivals/v1/festivals/muhurat/v1/muhurat/day/v1/day-context/v1/rahukaal/v1/choghadiya/v1/timings/v1/astronomical/v1/hora
MODIFIED

Coordinate-only requests compute for the coordinates

A request carrying lat/lon without a location_id is now computed for those coordinates instead of being served the default precomputed location.

Previously
location_id fell back to 2 (Varanasi) before the dataset lookup, so any request with coordinates but no location_id returned Varanasi's row — while echoing the caller's own coordinates back, which made the wrong answer look like the right one.
Now
A named location_id (or a region implying one) reads its precomputed row; bare coordinates are computed for those coordinates; supplying neither keeps the historical default.
Why
Coordinates that are echoed but not used are worse than coordinates that are rejected: the response looks location-aware and is not.
panchang-v2.1.0Backward compatibleView API →
/v1/panchang/v1/panchang/lite/v1/panchang/today/v1/panchang/tomorrow/v1/panchang/yesterday/v1/panchang/now/v1/today
FIXED

An impossible location/zone pair returns 422, not 500

Coordinates sent with a zone far enough away to wrap their solar day are refused with an explanation instead of erroring.

Previously
Paris coordinates on Asia/Kolkata produced a day whose sunset preceded its sunrise, and the resulting error escaped as HTTP 500.
Now
422, naming the zone the coordinates actually sit in. Pairs that still describe an ordered day are answered normally, with the caller's zone honoured.
Why
A sunrise-to-sunrise day cannot be expressed across that gap, so there is no correct answer to return. An empty festival list would have been worse than an error, being indistinguishable from a genuine quiet day.
panchang-v2.1.0Backward compatibleView API →
/v1/festivals/v1/today
MODIFIED

Festival observances carry their authoritative key

Each entry in `festival_observances` now includes `festival_key`, the identifier /v1/festivals/muhurat accepts.

Previously
Observances carried a display name only, so a client wanting a muhurat had to keep its own name-to-key table.
Now
`festival_key` is supplied by the API. Names with no rule behind them return null rather than a guessed key, which is the signal that no muhurat can be requested for them.
Why
Festival identity belongs to the API, not to every client.
panchang-v2.1.0Backward compatibleView API →
/v1/panchang/full
chakra-apis-v1.0.0API
  • New Chakra Calculation APIs: Kota, Saptashalaka, Sarvatobhadra and Shula.
  • Every response carries rule-level provenance — each rule reports its own verification level rather than the chakra carrying a single badge.
  • Calculation only. The endpoints return the chakra structure and rule metadata, and make no predictive, medical or life-event claims.
  • Inputs are pre-resolved: callers supply an already-determined nakshatra, so the endpoints perform no astronomical calculation.
  • Available on the Free tier, within the existing Free-plan monthly quota.
  • Where sources disagree, both readings ship and the one used is named in the response.
festival-engine-v2.0.2Security
  • Credentials moved out of source and into environment configuration.
  • Administrative PIN rotated.
  • Test suite expanded to 152 tests; coverage re-measured honestly at 91%.
festival-engine-v2.0.0Engine
  • Festival determination moved to shastric kala-vyapini rules over real tithi intervals.
  • Nine evaluators with an auto-registering registry; TieBreakEngine with kshaya and vriddhi handling.
  • Rule versioning with a DRAFT to ARCHIVED lifecycle and shastric authority metadata.
  • Observatory mode and per-festival confidence scores.
  • Series resolution for the Diwali cluster, Navratri and Holi.
  • Corrected Diwali, Janmashtami, Ganesh Chaturthi, Vijayadashami, Maha Shivaratri and Holi.
  • Abhijit Muhurat is no longer suppressed by Rahu, Yamaganda or Gulika overlap.

Milestones

The longer arc

Verification frameworkExecution engine, comparison policies, adapter registry, external benchmark.
Security hardeningCredentials moved to environment, secrets rotated, 152 tests at 91% coverage.
Platform alignmentTier enforcement, webhook platform, plans and billing, analytics.
Festival Engine V2 — cutoverTier A/B/C validation, shadow mode, production cutover.
Festival Engine V2 — coreKalaCalculator, nine evaluators, TieBreakEngine, rule versioning, schema migration.
AstrologyBirth chart, Guna Milan compatibility, PDF reports, matchmaking engine.
Auth and usageJWT auth, API key management, plan-based rate limiting, usage tracking.
FoundationInitial API surface, panchang data import across 14 cities.