Home / API Documentation

REST API · v1

KP Stellar Astro API

The same deterministic KP engine the website runs on, callable from your own software. JSON in, JSON out, no SDK required.

Quick start

  1. Sign in and open the developer portal.
  2. Subscribe to developer access (₹1,999 for 30 days).
  3. Press Create app. You are shown an App ID and an App Secret. Copy the secret now — it is never shown again.
  4. Confirm the keys work before writing any real payload:
# Base URL: https://kpstellarastro.com
curl https://kpstellarastro.com/api/v1/ping \
  -H "X-App-Id: kpsa_app_3c5b9502b9690bbb" \
  -H "X-App-Secret: kpsa_sk_YOUR_SECRET_HERE"
{ "ok": true,
  "app_id": "kpsa_app_3c5b9502b9690bbb",
  "expires_at": 1789181891.98 }

If that returns ok: true, your credentials are good and anything failing after this point is the payload, not the keys.

Prefer not to hand-roll the HTTP? Official free clients: Python and JavaScript/TypeScript — one method per endpoint, typed 401/402/429 errors. Details on the developer portal.

Authentication

Every /api/v1 request carries two headers. There is no OAuth flow, no token exchange, and no expiry on the credentials themselves — only on the subscription behind them.

HeaderValue
X-App-IdYour App ID, e.g. kpsa_app_3c5b9502b9690bbb
X-App-SecretYour App Secret, e.g. kpsa_sk_…
Content-Typeapplication/json on every POST
The secret is stored only as a hash. We cannot recover it or email it to you — if you lose it, rotate it in the portal, which issues a new secret and keeps the same App ID so your integration keeps its identity. Never ship the secret in browser JavaScript or a mobile binary; call the API from your own server.

Check credentials

GET/api/v1/ping

Costs nothing, computes nothing, and confirms the credentials plus how long access runs. Use it in your deploy healthcheck.

Response 200

{ "ok": true,
  "app_id": "kpsa_app_3c5b9502b9690bbb",
  "expires_at": 1789181891.98 // unix seconds }

Birth chart

POST/api/v1/birth-chart

A full natal reading: planetary positions with their full KP sub-chains, twelve house cusps, dasha periods, significators, and a verdict for every life domain.

Request body

FieldTypeNotes
birth_datestringrequiredYYYY-MM-DD
birth_timestringrequiredHH:MM, 24-hour, local to the birth place
latitudenumberrequiredDecimal degrees, north positive
longitudenumberrequiredDecimal degrees, east positive
placestringoptionalEchoed back; also resolves the historical time zone
namestringoptionalEchoed back for your own labelling

Request

curl -X POST https://kpstellarastro.com/api/v1/birth-chart \
  -H "X-App-Id: $APP_ID" \
  -H "X-App-Secret: $APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Asha",
    "birth_date": "1990-05-15",
    "birth_time": "10:30",
    "latitude": 13.0827,
    "longitude": 80.2707,
    "place": "Chennai, India"
  }'

Response 200 (abridged — real values)

{
  "name": "Asha",
  "place": "Chennai, India",
  "timezone": "Asia/Kolkata",
  "utc_offset_hours": 5.5,

  "positions": {
    "Sun": {
      "name": "Sun",
      "longitude": 30.485933,
      "speed": 0.96426,
      "retrograde": false,
      "sign": "Taurus",
      "sign_lord": "Venus",
      "nakshatra": "Krittika",
      "pada": 2,
      "star_lord": "Sun",
      "sub_lord": "Rahu",
      "sub_sub_lord": "Ketu"
    }, … 9 planets total
  },

  "cusps": [
    { "house": 1, "cusp": "06°58′",
      "sign_lord": "Moon", "star_lord": "Saturn",
      "sub_lord": "Mercury", "sub_sub_lord": "Jupiter" }
    , … 12 houses total
  ],

  "predictions": [
    {
      "event": "business",
      "title": "Business",
      "verdict": "WEAK_PROMISE",
      "confidence": "WEAK",
      "reasoning": "The CSL Mercury (sub lord of cusp 7) signifies
                    houses [3, 4, 9, 10, 11, 12], directly touching
                    [10, 11] the required houses [2, 7, 10, 11] …"
    }, … 18 life domains total
  ],

  "dasha": { /* Vimshottari periods */ },
  "significators": [ /* per-planet A/B/C/D houses */ ],
  "chart_layout": { /* wheel geometry, if you draw it */ },
  "planetary_positions_table": [ … ],
  "house_cusps_table": [ … ],
  "cuspal_promise_table": [ … ],
  "house_significators_abcd": [ … ],
  "planetary_aspects": [ … ],
  "vedic_details": { … },
  "vedic_bhava": {          /* classical Parashari graha-in-bhava */
    "ascendant_sign": "Leo",
    "house_system": "whole-sign (Parashari)",
    "differ_count": 1,   // grahas whose bhava != their KP house
    "readings": [
      {
        "graha": "Sun", "sign": "Gemini", "degree": 0.5,
        "bhava": 11,       // WHOLE-SIGN house — what the reading describes
        "kp_house": 10,    // Placidus house, for comparison only
        "houses_differ": true,
        "reading": "Gains through rank and influential connections …",
        "dignity": "neutral",  // exalted|debilitated|moolatrikona|own|neutral
        "house_nature": ["upachaya"],
        "modifiers": [ /* classical rules that apply, as sentences */ ],
        "karakatva": "the soul, the father, authority and vitality",
        "lords": [1],      // bhavas this graha RULES (depends on the lagna)
        "lordship": "Sun rules your 1st (…). Sitting in the 11th, it carries
                     those matters into gains, income, networks …",
        "node_agency": "",  // Rahu/Ketu only: whose lord it acts for
        "dasha": { "start": "1990-01-16", "end": "1996-01-17",
                    "active": false, "phase": "past" /* past|active|future */ },
        "ayanamsa_sensitive": false
      }, … one per graha
    ]
  },
  "doshas": {               /* Kaal Sarpa + Mangal, same whole-sign houses */
    "ascendant_sign": "Cancer",
    "house_system": "whole-sign (Parashari)",
    "mangal": {
      "present": true,      // decided by the LAGNA reference only — see below
      "cancelled": true,    // present AND at least one classical parihara applies
      "severity": "mild",  // none|mild|moderate
      "mars_sign": "Aquarius",
      "mars_bhava": 8,      // WHOLE-SIGN house — what decides the verdict
      "mars_kp_house": 8,   // Placidus house, for comparison only
      "houses_differ": false,
      "houses": { "lagna": 8, "Moon": 3, "Venus": 12 },
      "afflicting": ["lagna", "Venus"],  // references that agree
      "contested_only": false, // true = rests solely on the disputed 2nd house
      "reasons": [ /* why, as sentences */ ],
      "cancellations": [ /* classical parihara that apply, as sentences */ ]
    },
    "kaal_sarpa": {
      "present": false, "partial": false,
      "type_name": "Kulik",  // one of the twelve, from Rahu's bhava
      "rahu_bhava": 2, "ketu_bhava": 8,
      "inside": [ /* grahas hemmed within the Rahu→Ketu arc */ ],
      "outside": ["Moon", "Saturn"],
      "on_axis": [ /* within 1° of a node — the partial (Aanshik) case */ ],
      "reason": "Moon, Saturn fall outside the Rahu–Ketu arc …"
    },
    "remedies": [ /* only for a dosha actually found; [] otherwise */ ],
    "base_rates": { "mangal_pct": 52.2, "kaal_sarpa_pct": 4.0,  }
  }
}
vedic_bhava uses a different house system from the rest of this response. Every other house number here is a KP Placidus house. Classical Parashari graha-in-bhava is read by whole sign — the Ascendant's entire sign is the 1st bhava — and the two disagree for roughly 58% of placements (measured over 2,700). Each reading therefore carries its own bhava alongside the kp_house, and houses_differ tells you when they part company. Do not join these readings onto a KP house number: the sentence belongs to the whole-sign bhava. This block is traditional correspondence, not a computed verdict, and never affects any predictions entry.
doshas follows the same whole-sign rule, and two things about it are easy to get wrong. First, Mangal dosha is decided from the lagna alone. Counting the Moon and Venus references as independent triggers marks 88.7% of charts Manglik; the lagna rule alone marks 52.2% (measured over 800 charts), which is what six-of-twelve houses predicts. The other references are returned in houses/afflicting as corroboration — do not treat them as triggers. Second, never render present without cancellations and base_rates: about 67% of Manglik charts carry a classical cancellation, and a dosha shown without either is the frightening half of the tradition rather than a neutral subset of it. Like vedic_bhava, this is traditional correspondence and never affects any predictions entry.

Verdict values

The verdict field on each prediction is one of a fixed set. Treat it as an enum, not as prose:

ValueMeaning
STRONGLY_PROMISEDSignified, with strong supporting significators
PROMISEDThe cuspal sub-lord signifies the required houses
PROMISED_WITH_DELAYPromised, but retrograde or obstructed — arrives later
PROMISED_WITH_OBSTRUCTIONPromised against a competing signification
WEAK_PROMISEThinly signified; timing is indicative only
REQUIRES_FURTHER_TIMING_CONFIRMATIONPromise stands, timing is not yet decidable
DENIEDNot signified. The chart does not promise it
Polarity matters. DENIED is not automatically bad news — for a benefic topic it means the event is not promised, but for a topic the querent does not want, denial is the good outcome. Do not render the raw enum to end users without interpreting it against the question.

Horary (Prashna)

POST/api/v1/horary

Judges one question from the moment it is asked, using a number from 1 to 249. No birth details needed.

Request body

FieldTypeNotes
questionstringrequiredOne answerable question. Either/or questions are rejected
horary_numberintegerrequired1–249
judgment_datestringrequiredYYYY-MM-DD — the moment of asking
judgment_timestringrequiredHH:MM, local to the place below
latitudenumberrequiredWhere the question is asked
longitudenumberrequired
placestringoptionalResolves the time zone

Request

curl -X POST https://kpstellarastro.com/api/v1/horary \
  -H "X-App-Id: $APP_ID" \
  -H "X-App-Secret: $APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Will I get the job?",
    "horary_number": 137,
    "judgment_date": "2026-08-13",
    "judgment_time": "14:20",
    "latitude": 13.0827,
    "longitude": 80.2707,
    "place": "Chennai, India"
  }'

Response 200 (abridged)

{
  "question": "Will I get the job?",
  "horary_number": 137,
  "category": "Job / Employment",
  "event_id": "job",
  "primary_cusp": 6,
  "required_houses": [2, 6, 10, 11],
  "verdict": "PROMISED",
  "confidence": "STRONG",
  "reasoning": "…",
  "windows": [ { "start": "…", "end": "…" } ],
  "classification_confidence": "…",
  "timezone": "Asia/Kolkata",
  "positions": { … }, "cusps": [ … ], "significators": [ … ]
}
multi_question_notice is not an error. When the question contains more than one ask, the field is populated and you should surface it — the verdict then applies to the primary question only.

Panchang

POST/api/v1/panchang

The five limbs for a date and place, plus the inauspicious and auspicious windows.

Request

curl -X POST https://kpstellarastro.com/api/v1/panchang \
  -H "X-App-Id: $APP_ID" \
  -H "X-App-Secret: $APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2026-08-13",
    "latitude": 13.0827,
    "longitude": 80.2707,
    "place": "Chennai, India"
  }'

Response 200 (real values)

{
  "date": "2026-08-13",
  "place": "Chennai, India",
  "timezone": "Asia/Kolkata",
  "utc_offset_hours": 5.5,
  "vara": "Thursday",
  "sunrise": "05:56",
  "sunset": "18:29",
  "tithi":     { "index": 1, "name": "Pratipada", "paksha": "Shukla" },
  "nakshatra": { "name": "…", "lord": "…" },
  "yoga":      { "name": "…" },
  "karana":    { "name": "…" },
  "inauspicious": {
    "rahu_kalam":   { "start": "13:48", "end": "15:22" },
    "yamagandam":   { "start": "05:56", "end": "07:30" },
    "gulika_kalam": { "start": "09:04", "end": "10:39" }
  },
  "auspicious": { … }
}

Compatibility

POST/api/v1/compatibility

Ashtakoot Guna matching for two charts, scored out of 36, with each of the eight koots broken out separately.

Request body

FieldTypeNotes
boyobjectrequiredA birth object, same fields as birth-chart
girlobjectrequiredLikewise

Request

curl -X POST https://kpstellarastro.com/api/v1/compatibility \
  -H "X-App-Id: $APP_ID" -H "X-App-Secret: $APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "boy":  { "birth_date": "1990-05-15", "birth_time": "10:30",
              "latitude": 13.0827, "longitude": 80.2707, "place": "Chennai, India" },
    "girl": { "birth_date": "1992-08-02", "birth_time": "04:15",
              "latitude": 19.0760, "longitude": 72.8777, "place": "Mumbai, India" }
  }'
Read the per-koot breakdown, not only the total. A strong total can hide one weak koot that matters to the couple, and a middling total is often fine once you see where the points went. Rendering only the /36 figure throws away the part that is actually actionable.

Muhurta

GET/api/v1/muhurta/events

The event ids /api/v1/muhurta accepts. Call this rather than hard-coding the list — it is engine-defined and would rot silently the first time an event is added or renamed.

Response 200

{ "events": [
    { "id": "property", "label": "Property" },
    { "id": "vehicle",  "label": "Vehicle" }
    , … also: foreign_travel, marriage, business, education,
         higher_education, job, loan, surgery
] }
POST/api/v1/muhurta

Auspicious windows for a personal event, ranked, each carrying the reason it scored where it did.

FieldTypeNotes
birthobjectrequiredBirth object, as above
event_namestringrequiredAn id from /api/v1/muhurta/events
max_windowsintegeroptional1–20, default 8
from_date, to_datestringoptionalYYYY-MM-DD. Filters which qualifying windows come back
viewer_utc_offset_hoursnumberoptional−12 to 14. The UTC offset of the person reading the result. Defaults to the birth place's offset
No elected date is ever in the past. A muhurta that names a date already gone is useless, so today is an absolute floor — applied to the transit scan itself, not just its result, so a window that is currently RUNNING is kept and its best still-available day returned rather than the window being dropped. A from_date in the past does not reopen this. "Today" means the reader's calendar day: send viewer_utc_offset_hours if your user may be in a different time zone from the chart's birth place, or dates that are yesterday to them can appear as today.
A bounded range never lowers the bar. from_date/to_date filter windows that already qualify; they do not relax the promise, confidence or Moon-transit requirements to fill an empty range. An empty result means no window qualified — present it as such rather than widening the range until something appears.

TSP quick question

POST/api/v1/tsp

Theory of Short Prediction — a fast single-question read from its own 2193-segment number table. Deliberately narrower than horary, and not a substitute for it: no chart wheel is produced.

FieldTypeNotes
tsp_numberintegerrequired1–2193 — not the 1–249 horary number
judgment_datestringrequiredYYYY-MM-DD
judgment_timestringrequiredHH:MM
latitude, longitudenumberrequiredWhere the question is asked
querystringoptionalThe question text, echoed back for your own labelling
namestringoptionalEchoed back
placestringoptionalResolves the time zone
The verdict comes from the number, not the text. query is optional and is echoed back rather than parsed — unlike horary, where the question is classified to pick the cusp. Do not infer from a TSP response that the question text was read.
curl -X POST https://kpstellarastro.com/api/v1/tsp \
  -H "X-App-Id: $APP_ID" -H "X-App-Secret: $APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "tsp_number": 137,
    "query": "Will I get the job?",
    "judgment_date": "2026-08-13",
    "judgment_time": "14:20",
    "latitude": 13.0827,
    "longitude": 80.2707,
    "place": "Chennai, India"
  }'

Cuspal interlinks

POST/api/v1/cuspal-interlinks

Khullar's Cuspal Interlinks Theory — the star / sub / sub-sub chain linking a cusp to the houses that fulfil it. Same request body as birth-chart. This is the technique behind the "why" panel in the web app, exposed on its own.

Question cusp

POST/api/v1/question-cusp

Which house cusp a horary question is judged from, and which houses must be signified — the same classification horary runs internally, returned directly with no chart cast. Useful for previewing how a question will be judged before spending a horary number on it.

Request body

FieldTypeNotes
questionstringrequiredUp to 2000 characters.
in_indiabooleanoptionalDefault true. Disambiguates domestic vs. foreign travel questions only — has no other effect on classification.
curl -X POST https://kpstellarastro.com/api/v1/question-cusp \
  -H "X-App-Id: $APP_ID" -H "X-App-Secret: $APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"question": "will I win the lottery"}'

Response 200

{ "ok": true,
  "event_id": "lottery",
  "category": "Lottery / Prize Bond Win",
  "primary_cusp": 5,
  "required_houses": [5, 9, 10, 11],
  "multi_question_notice": null,
  "notice_kind": null,
  "doctrine": { "corroboration": "mixed", "note": "Classical texts admit more than one reading here" } }

A question that fails validation (gibberish, too short, not a real question) returns 200 with "ok": false and a message — not an error status, since asking "can this be judged?" isn't itself a failure.

Descriptive Indicators

POST/api/v1/descriptive

Table-lookup traits about whatever the question's cusp actually describes — a person, a place, or a matter — plus, where the event supports it, a facet reading: which of several recognised shapes (a court case settling vs. being appealed vs. a favorable judgment; a property matter being a purchase vs. a sale vs. a tenancy) the chart leans toward. Both are advisory evidence read off the cuspal sub-lord and its star lord — never a PROMISED/DENIED verdict, and never invented: a chart that shows nothing returns an empty list, which is a legitimate, common answer. Same calculation the website's own Descriptive Indicators panel uses, on the caller-supplied chart in this request rather than a signed-in account's saved one.

Request body

FieldTypeNotes
modestringoptionalDefault "BIRTH". "HORARY" uses the horary object below instead of birth.
questionstringrequired for BIRTH modeThe judged question — fixes which cusp is being described. For HORARY mode the question travels inside horary instead.
askstringoptionalA specific descriptive question ("what will their profession be") to filter to. Omit to get every indication the chart supports plus the list of questions that CAN be asked (can_ask).
birthobjectrequired for BIRTH modeSame shape as /api/v1/birth-chart's body.
horaryobjectrequired for HORARY modeSame shape as /api/v1/horary's body.
curl -X POST https://kpstellarastro.com/api/v1/descriptive \
  -H "X-App-Id: $APP_ID" -H "X-App-Secret: $APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"mode": "BIRTH", "question": "will there be a court case over the property?",
       "birth": {"name": "Test", "birth_date": "1990-06-15", "birth_time": "10:30",
                 "latitude": 12.9716, "longitude": 77.5946, "place": "Bengaluru"}}'

Response 200

{ "subject": "the opposing party",
  "cusp": 6,
  "is_person": false,
  "indications": [ ... ],
  "can_ask": [ { "kind": "work", "question": "What kind of matter is this?" }, ... ],
  "event": "Litigation",
  "facets": [
    { "id": "settlement", "label": "settlement / compromise",
      "agreement": 1, "because": "the 6th cuspal sub-lord Saturn and its star lord Sun between them signify house 7" }
  ] }

facets is empty for events with no defined facet table, or when the chart shows none of a facet's houses. It is a small, growing set — currently litigation, bail, property, health, foreign travel, loan, donation/charity, promotion, workplace trouble, vehicle, surgery, missing person, stock market, inheritance, gratuity/insurance, and lost property/theft recovery.

Unlike the signed-in web app, there is no Premium-plan gate here — the developer subscription is already the paywall, same as every other /api/v1 endpoint.

Financial astrology

Four endpoints for money questions — an entity chart from a founding moment, its key windows, a head-to-head comparison of two candidate moments, and the astronomical events in a range.

POST/api/v1/financial/chart

An entity chart: a company from its incorporation moment, a listing, a deal. Takes birth (the moment) and event_name.

POST/api/v1/financial/muhurta

Key time windows for a financial event. Same body, plus optional max_windows.

POST/api/v1/financial/compare

Rank two candidate moments against each other. Takes original, candidate (each wrapping a birth object) and event_categories.

Two full chart computations per call. Comparing a long shortlist pairwise multiplies quickly — budget for it against your daily limit rather than looping blindly.
GET/api/v1/financial/events

Astronomical events in a date range. Query parameters start_date and end_date, both YYYY-MM-DD.

curl "https://kpstellarastro.com/api/v1/financial/events?start_date=2026-08-01&end_date=2026-08-31" \
  -H "X-App-Id: $APP_ID" -H "X-App-Secret: $APP_SECRET"

Question classification (session auth)

Part of the same developer subscription as /api/v1 above, but authenticated differently: it does not take X-App-Id / X-App-Secret at all. It uses a signed-in session bearer token instead — the same token the website itself uses — so a standalone server integration authenticating purely by App-Id/Secret cannot call it; the caller must be a signed-in account with active developer access.

POST/api/question/cusp

Which house cusp a horary question is judged from, and which houses must be signified — the same classification /api/horary runs internally, returned directly with no chart cast. Useful for previewing how a question will be judged before spending a horary number on it.

Auth

HeaderValue
AuthorizationBearer <session token> — the same token a signed-in browser session uses, obtained via the site's own sign-in flow, not the developer portal.
Included in the same developer subscription as the /api/v1 endpoints above (₹1,999 / 30 days) — no separate charge. A signed-in account without active developer access gets 402; there is no free or unauthenticated tier for this endpoint.

Request body

FieldTypeNotes
questionstringrequiredUp to 2000 characters.
in_indiabooleanoptionalDefault true. Disambiguates domestic vs. foreign travel questions only — has no other effect on classification.
curl -X POST https://kpstellarastro.com/api/question/cusp \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"question": "will I win the lottery"}'

Response 200

{ "ok": true,
  "event_id": "lottery",
  "category": "Lottery / Prize Bond Win",
  "primary_cusp": 5,
  "required_houses": [5, 9, 10, 11],
  "multi_question_notice": null,
  "notice_kind": null,
  "doctrine": { "corroboration": "mixed", "note": "Classical texts admit more than one reading here" } }

A question that fails validation (gibberish, too short, not a real question) returns 200 with "ok": false and a message, the same shape /api/question/check uses — not an error status, since asking "can this be judged?" isn't itself a failure.

What is not on the API

Three things the web app does are deliberately absent, and will stay absent until each has an answer to its own problem rather than being bolted onto this subscription:

Not exposedWhy
Birth-time rectification (auto-search)By far the heaviest operation on the platform — seconds per request, scoring many candidate birth times, each a full chart plus significators plus dasha. In the web app it is signed-in only and already held to roughly 4 calls/minute per account with at most 3 running concurrently site-wide. The developer tier's 60/minute is an order of magnitude beyond that, and the concurrency cap means one integration looping it would starve real users. It needs its own pricing and its own limits, not this subscription's.
AI explanationCosts real money per call against a third-party model. It belongs on the credit system, not a flat monthly fee.
Saved charts, clients, tracked predictionsApp credentials authenticate an application, not one of its end users. Serving a specific person's stored data through them would make one developer key a master key to their whole user base — that needs a per-user authorization flow, which is separate work.

Errors

Errors are JSON with a detail string. The status code tells you which problem you have, and they are deliberately distinct — do not collapse them into one retry path.

StatusMeaningWhat to do
401Invalid App ID or App Secret, or the app was revokedCheck both headers. Rotate the secret if it may have leaked. Do not retry — it will not start working
402Developer access has expiredRenew in the portal. Your keys are still valid; only the subscription lapsed
422The payload failed validationRead field_errors — it names the exact field and problem
429Over the rate limitBack off and retry. See limits
503The endpoint is temporarily disabledRetry later; this is a server-side switch, not your request

A validation error, verbatim

{
  "detail": "Date is required.",
  "field_errors": [
    { "field": "judgment_date", "message": "Date is required." },
    { "field": "judgment_time", "message": "Time is required." }
  ]
}
401 does not distinguish a wrong secret from an unknown App ID. That is deliberate — a distinct answer would let anyone enumerate valid App IDs. When debugging, check both values.

Rate limits

 Public endpoints (no key)Developer API
AccessWebsite endpoints only — no /api/v1All /api/v1 endpoints
Per minute1060  6× more
Per day1001,000  10× more
Counted againstYour IP, shared with everyone on the same networkEach app separately, up to 5 apps

The per-app scope is often the bigger win: five apps at 1,000 calls each is 5,000 a day, and none of them is affected by other traffic from your network.

Limits are counted per app, not per IP, so several developers behind one office network do not throttle each other, and running your integration from a serverless platform with rotating addresses is fine. Create a separate app per environment (staging, production) to keep their budgets independent — you can have up to five.

Going over returns 429. Back off and retry; nothing is banned or charged extra.

Pricing

PlanPriceIncludes
Developer access₹1,999 / 30 daysAll /api/v1 endpoints, up to 5 apps, 1,000 calls per app per day

Billed as a one-off 30-day period, not an auto-renewing mandate — nothing recurs without you buying it again. Renewing before expiry adds to the time you have left rather than replacing it. When the period ends, calls answer 402 and your apps are not deleted: renew and the same credentials resume working.

Notes & guarantees

  • Same engine as the website. These endpoints are thin authenticated wrappers over the exact handlers the app itself calls, so the API cannot drift from what the site shows.
  • Deterministic. The same input returns the same verdict. No language model is involved in any figure or judgment.
  • Classification is deterministic here too. Deciding which matter a question is about (and therefore which cusp it judges from) runs on the keyword and grammar tiers only on /api/v1 — the website's language-model fallback for unusual phrasing is not applied to API calls. This keeps your results reproducible and your per-call latency predictable. A question whose wording matches no rule resolves to the general classification (11th cusp) rather than being guessed at. If you need a specific matter, name it: pass locked_event_id (for example "job_change", "property_sale") on /api/v1/horary and that classification is used directly, with no keyword matching involved. Call /api/v1/question-cusp first if you want to see what a question resolves to before casting a chart.
  • Nothing is stored from your API calls. Charts computed through /api/v1 are not saved to any account; we record only the call count and last-used time against your app.
  • Time zones are historical. Supplying place resolves the zone that was actually in force on that date, including past DST rules — this matters for a 1970s birth time.
  • Birth time precision. KP is minute-sensitive; the cuspal sub-lord can change within four minutes. If your users supply approximate times, present the results with that caveat.
  • Versioning. Breaking changes go to a new path prefix. /api/v1 keeps its response shape.