🌍 Astrocartography API and ✋ Palmistry API are now live. Ship them in your app today.Get Started

Guides

Add Kundli matching to your app

This guide is for dating and matrimonial product developers. The ashtakoot matching endpoint scores the compatibility of two people from their birth details.

Call the API from a Next.js server route. Return the score to your app.

What ashtakoot matching is

Ashtakoot matching is a 36-point compatibility score computed from two birth charts. It is the guna milan system in Vedic astrology. The score comes from eight factors, called koots: varna, vashya, tara, yoni, maitri, gan, bhakut, and nadi.

Each koot has a maximum number of points and an achieved number of points. The eight maximums add up to 36. The API computes the points and returns a per-koot breakdown plus the total.

The endpoint

The endpoint is match_ashtakoot_points on the base URL https://json.astrologyapi.com/v1. The request is a POST with HTTP Basic auth: the user ID is the username and the API key is the password.

The host sends no CORS headers. Call the endpoint from a server, never from browser code. Keep the API key in a server-only environment variable.

The request takes two sets of birth details, one per person. The male fields use an m_ prefix and the female fields use an f_ prefix. All sixteen fields are required.

ParameterTypeDescription
m_dayintMale birth day, e.g. 10
m_monthintMale birth month, e.g. 5
m_yearintMale birth year, e.g. 1990
m_hourintMale birth hour, e.g. 19
m_minintMale birth minute, e.g. 55
m_latfloatMale birth latitude, e.g. 19.2056
m_lonfloatMale birth longitude, e.g. 25.2056
m_tzonefloatMale timezone offset, e.g. 5.5
f_dayintFemale birth day
f_monthintFemale birth month
f_yearintFemale birth year
f_hourintFemale birth hour
f_minintFemale birth minute
f_latfloatFemale birth latitude
f_lonfloatFemale birth longitude
f_tzonefloatFemale timezone offset

The response holds one object per koot, each with a total_points (the maximum for that koot) and a received_points (the score achieved).

The total object sums them, and conclusion carries a status flag and a written report.

{
  "varna": {
    "description": "Natural Refinement / Work",
    "male_koot_attribute": "Kshatriya",
    "female_koot_attribute": "Kshatriya",
    "total_points": 1,
    "received_points": 1
  },
  "vashya": {
    "description": "Innate Giving / Attraction towards each other",
    "male_koot_attribute": "Chatuspad",
    "female_koot_attribute": "Chatuspad",
    "total_points": 2,
    "received_points": 2
  },
  "tara": {
    "description": "Comfort - Prosperity - Health",
    "total_points": 3,
    "received_points": 0
  },
  "yoni": {
    "description": "Intimate Physical",
    "total_points": 4,
    "received_points": 0
  },
  "maitri": {
    "description": "Friendship",
    "male_koot_attribute": "Mars",
    "female_koot_attribute": "Mars",
    "total_points": 5,
    "received_points": 5
  },
  "gan": {
    "description": "Temperament",
    "male_koot_attribute": "",
    "female_koot_attribute": "",
    "total_points": 6,
    "received_points": 6
  },
  "bhakut": {
    "description": "Constructive Ability / Constructivism / Society and Couple",
    "male_koot_attribute": "Aries",
    "female_koot_attribute": "Aries",
    "total_points": 7,
    "received_points": 7
  },
  "nadi": {
    "description": "Progeny / Excess",
    "male_koot_attribute": "",
    "female_koot_attribute": "",
    "total_points": 8,
    "received_points": 0
  },
  "total": {
    "total_points": 36,
    "received_points": 21,
    "minimum_required": 18
  },
  "conclusion": {
    "status": true,
    "report": "Ashtakoota Matching between male and female is 21 points out of 36 points. This is a reasonably good score. Moreover, your rashi lords are friendly with each other thereby signifying mental compatibility and mutual affection between the two. Hence, this is a favourable Ashtakoota match."
  }
}

A more detailed report (optional)

The match_making_report endpoint rolls up more checks into one response. That endpoint takes the same m_ and f_ birth fields. The response returns the ashtakoota total plus manglik, rajju dosha, and vedha dosha status.

The report endpoint is a convenience superset. It does not replace the raw ashtakoot breakdown above.

{
  "ashtakoota": {
    "status": true,
    "received_points": 21
  },
  "manglik": {
    "status": true,
    "male_percentage": 27.5,
    "female_percentage": 28.25
  },
  "rajju_dosha": {
    "status": false
  },
  "vedha_dosha": {
    "status": false
  },
  "conclusion": {
    "match_report": "Marriage between the prospective bride and groom is highly recommended. The couple would have a long-lasting relationship, which would be filled with happiness and affluence."
  }
}

A Next.js API route example

Create pages/api/match-score.js. The route reads a male and a female object from the request body. The route maps each object onto the prefixed parameter names and calls the endpoint with Basic auth.

Store the credentials as ASTROLOGY_USER_ID and ASTROLOGY_API_KEY in a server-only file such as .env.local.

// pages/api/match-score.js
export default async function handler(req, res) {
  if (req.method !== 'POST') {
    res.status(405).json({ error: 'Method not allowed' })
    return
  }

  const { male, female } = req.body
  if (!male || !female) {
    res.status(400).json({ error: 'Both male and female profiles are required' })
    return
  }

  // Map each profile onto the m_* / f_* parameter names the endpoint expects.
  const body = {
    m_day: male.day,
    m_month: male.month,
    m_year: male.year,
    m_hour: male.hour,
    m_min: male.min,
    m_lat: male.lat,
    m_lon: male.lon,
    m_tzone: male.tzone,
    f_day: female.day,
    f_month: female.month,
    f_year: female.year,
    f_hour: female.hour,
    f_min: female.min,
    f_lat: female.lat,
    f_lon: female.lon,
    f_tzone: female.tzone,
  }

  const auth =
    'Basic ' +
    Buffer.from(
      `${process.env.ASTROLOGY_USER_ID}:${process.env.ASTROLOGY_API_KEY}`,
    ).toString('base64')

  try {
    const response = await fetch(
      'https://json.astrologyapi.com/v1/match_ashtakoot_points',
      {
        method: 'POST',
        headers: {
          Authorization: auth,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(body),
      },
    )
    if (!response.ok) {
      const text = await response.text()
      throw new Error(
        `match_ashtakoot_points failed (${response.status}): ${text}`,
      )
    }
    const data = await response.json()
    res.status(200).json(data)
  } catch (error) {
    res.status(502).json({ error: error.message })
  }
}

If you need to call the API from client code instead of a server route, use an access token as shown in the access token usage guide.

Interpreting the score

The API returns points and a written conclusion.report string. The API does not decide what counts as a good match for your product.

The minimum_required value of 18 in the response is astrological convention. The API does not enforce that threshold, and your product does not have to follow it.

The threshold you show is a product decision, not an API output. So is the wording around a low or high score. So is the choice to surface the raw number at all.

Your code makes those decisions, not the API. Decide how you want to present a score before you wire the score into a user-facing screen.

Manglik check (optional add-on)

The manglik endpoint checks a single chart for mangal dosha. That endpoint takes the same eight birth fields as a single person: day, month, year, hour, min, lat, lon, and tzone. The response reports whether the dosha is present, how strong the dosha is, and whether the dosha is cancelled.

{
  "manglik_present_rule": {
    "based_on_aspect": [
      "Your first house in birth chart is aspected by planet KETU.",
      "Seventh house of your birth chart is aspected by SATURN",
      "Fourth house of your birth chart is aspected by MARS",
      "Twelfth house of your birth chart is aspected by MARS."
    ],
    "based_on_house": [
      "Planet Sun is situated in EIGHTH house in your birth chart."
    ]
  },
  "is_mars_manglik_cancelled": false,
  "manglik_status": "EFFECTIVE",
  "percentage_manglik_present": 27.5,
  "percentage_manglik_after_cancellation": 27.5,
  "manglik_report": "Manglik dosha has been detected in your horoscope and the extent of mangal dosha present is effective and therefore needs due carefulness. You are manglik.",
  "is_present": true
}

This endpoint checks one person at a time. To check a couple, call the endpoint twice, once per profile. Compare the two results in your own code.

Where to go next

To compute and display an individual's chart data too, see the birth chart guide. That guide follows the same server-route pattern for a single-person chart.

Matrimonial forms often collect a birth time the user isn't sure of. If that applies to your product, see the unknown birth time guide before you design the intake form.

Before launch, work through Credits, errors, and going to production — matching calls are a natural place to add caching, since the same two birth records always produce the same score.