The most comprehensive Vedic astrology library for Go — 684 calculations, one context away.
Perfect for:
- 📱 Horoscope services - Get 200+ life predictions instantly
- 💑 Marriage matching backends - 16-factor Kuta compatibility analysis
- 📅 Daily panchanga APIs - Tithi, Nakshatra, Yoga, Karana
- 🔮 AI astrology chatbots - Natural language birth chart queries
- 📊 Astrological research - Batch process thousands of charts
- 🌟 Numerology calculators - Chaldean system with life aspect scores
Standard library only. The SDK has zero third-party dependencies, compiles into a single static binary, and ships typed constants for every enum — so calculators, planets, signs and ayanamsas autocomplete in your editor.
go get github.com/VedAstro/VedAstro.Go@v1.0.0Requires Go 1.26 or newer. Import the package as vedastro:
import vedastro "github.com/VedAstro/VedAstro.Go"No C toolchain, no ephemeris files, no generated protobufs. Calculations run on VedAstro's servers over HTTPS.
package main
import (
"context"
"fmt"
"log"
vedastro "github.com/VedAstro/VedAstro.Go"
)
func main() {
// 'FreeAPIUser' is the free-tier key; an empty key also uses the free tier.
client := vedastro.NewClient("FreeAPIUser")
// Time format: "HH:MM DD/MM/YYYY +TZ:TZ"
// GeoLocation takes (name, longitude, latitude) — longitude first.
birth, err := vedastro.NewTime("14:30 25/10/1992 +05:30",
vedastro.NewGeoLocation("Mumbai", 72.8777, 19.0760))
if err != nil {
log.Fatal(err)
}
// Every calculator takes a context first and returns (any, error).
result, err := client.PlanetRasiD1Sign(context.Background(), vedastro.PlanetSun, birth)
if err != nil {
log.Fatal(err)
}
sign := result.(map[string]any)
fmt.Println("Sun sign:", sign["Name"]) // Output: Libra
}That's it! You just made your first Vedic astrology calculation. 🎉
Results are dynamically typed. Calculators return
anybecause payloads vary — objects, arrays, scalars, or SVG strings. Checkerrfirst, then type-assert. See Decoded results.
Every snippet below is complete and runnable: each one builds the vedastro.Time it needs, then calls client, which comes from the Quick Start. This helper reads one property from an object payload without repeating type assertions:
// field reads one property from an object payload, or returns "" if absent.
func field(result any, key string) string {
if object, ok := result.(map[string]any); ok {
if value, ok := object[key].(string); ok {
return value
}
}
return ""
}Use Case: Display the Sun, Moon, and Ascendant signs
ctx := context.Background()
birth, err := vedastro.NewTime("14:30 25/10/1992 +05:30",
vedastro.NewGeoLocation("Mumbai", 72.8777, 19.0760))
if err != nil {
log.Fatal(err)
}
sun, err := client.PlanetRasiD1Sign(ctx, vedastro.PlanetSun, birth)
if err != nil {
log.Fatal(err)
}
moon, err := client.PlanetRasiD1Sign(ctx, vedastro.PlanetMoon, birth)
if err != nil {
log.Fatal(err)
}
// HouseSignName takes a typed house constant; it unwraps to a plain string.
rising, err := client.HouseSignName(ctx, vedastro.House1, birth)
if err != nil {
log.Fatal(err)
}
fmt.Println("Sun: ", field(sun, "Name")) // e.g. Libra
fmt.Println("Moon: ", field(moon, "Name")) // e.g. Scorpio
fmt.Println("Rising:", rising) // e.g. Capricorn👉 See full example: examples/birth_chart_basics
Use Case: Check if two people are compatible for marriage
person1, _ := vedastro.NewTime("23:40 31/12/1996 +09:00",
vedastro.NewGeoLocation("Tokyo", 139.83, 35.65))
person2, _ := vedastro.NewTime("14:30 15/06/1997 -05:00",
vedastro.NewGeoLocation("New York", -74.006, 40.7128))
report, err := client.MatchReport(context.Background(), person1, person2)
if err != nil {
log.Fatal(err)
}
match := report.(map[string]any)
fmt.Printf("Compatibility: %v/100\n", match["KutaScore"])
summary := match["Summary"].(map[string]any)
fmt.Println(summary["ScoreSummary"])
// Each Kuta factor carries a Nature of Good, Bad, or Neutral.
for _, item := range match["PredictionList"].([]any) {
kuta := item.(map[string]any)
fmt.Printf(" • %v: %v\n", kuta["Name"], kuta["Nature"])
}Output (shape and values depend on the two charts):
Compatibility: 65/100
Good match - Near perfect match, overall happiness
• Graha Maitram: Good
• Rajju: Good
• Nadi Kuta: Good
• Vasya Kuta: Bad
• Dina Kuta: Good
👉 See full example: examples/marriage_compatibility
Use Case: Get today's planetary positions for any location
mumbai := vedastro.NewGeoLocation("Mumbai", 72.8777, 19.0760)
// NewTimeFromDate keeps the supplied time's calendar fields and UTC offset.
now, err := vedastro.NewTimeFromDate(time.Now(), mumbai)
if err != nil {
log.Fatal(err)
}
planets := []vedastro.PlanetName{
vedastro.PlanetSun, vedastro.PlanetMoon, vedastro.PlanetMars,
vedastro.PlanetMercury, vedastro.PlanetJupiter, vedastro.PlanetVenus,
vedastro.PlanetSaturn, vedastro.PlanetRahu, vedastro.PlanetKetu,
}
fmt.Println("Current planetary positions:")
for _, planet := range planets {
sign, err := client.PlanetRasiD1Sign(context.Background(), planet, now)
if err != nil {
log.Printf("skipping %s: %v", planet, err)
continue
}
star, err := client.PlanetConstellation(context.Background(), planet, now)
if err != nil {
log.Printf("skipping %s: %v", planet, err)
continue
}
fmt.Printf(" %s: %s in %v\n", planet, field(sign, "Name"), star)
}PlanetName is a named string type, so %s prints it directly.
Output:
Current planetary positions:
Sun: Taurus in Krithika - 2
Moon: Sagittarius in Moola - 1
...
PlanetConstellation unwraps to a string that includes the pada, such as Chitta - 3.
Free-tier pacing: this loop makes two calls per planet. See Pacing requests.
👉 See full example: examples/current_planets
Use Case: Get today's Tithi, Nakshatra, Yoga, and Karana
mumbai := vedastro.NewGeoLocation("Mumbai", 72.8777, 19.0760)
today, err := vedastro.NewTimeFromDate(time.Now(), mumbai)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
tithi, err := client.LunarDay(ctx, today)
if err != nil {
log.Fatal(err)
}
nakshatra, err := client.MoonConstellation(ctx, today)
if err != nil {
log.Fatal(err)
}
yoga, err := client.NithyaYoga(ctx, today)
if err != nil {
log.Fatal(err)
}
karana, err := client.Karana(ctx, today)
if err != nil {
log.Fatal(err)
}
// Shapes differ: LunarDay and NithyaYoga return objects, the others unwrap to strings.
day := tithi.(map[string]any)
yogaInfo := yoga.(map[string]any)
fmt.Println("Tithi: ", day["Name"], "("+day["Paksha"].(string)+")") // e.g. Amavasya (Krishna)
fmt.Println("Nakshatra:", nakshatra) // e.g. Chitta - 3
fmt.Println("Yoga: ", yogaInfo["Name"]) // e.g. Vishkambha
fmt.Println("Karana: ", karana) // e.g. ChatushpadaOutput:
Tithi: Amavasya (Krishna)
Nakshatra: Chitta - 3
Yoga: Vishkambha
Karana: Chatushpada
Note: shapes vary per calculator — LunarDay (Name, Paksha, Date, Day, Phase) and NithyaYoga (Name, Description) decode to objects, while MoonConstellation and Karana unwrap to strings. Check a signature with go doc, and prefer the two-value type assertion while exploring.
Note: NewTimeFromDate preserves the time.Time's own offset. Pass a value in the target zone (time.Now().In(time.FixedZone("IST", 19800))) rather than relabelling a local time.
👉 See full example: examples/daily_panchanga
Use Case: Get planetary periods (Mahadasa → Bhukti → Antaram) over a range
mumbai := vedastro.NewGeoLocation("Mumbai", 72.8777, 19.0760)
birth, _ := vedastro.NewTime("14:30 25/10/1992 +05:30", mumbai)
start, _ := vedastro.NewTime("00:00 01/01/2020 +05:30", mumbai)
end, _ := vedastro.NewTime("23:59 31/12/2030 +05:30", mumbai)
// Optional arguments use a method-specific options struct with pointer fields.
// (DasaAtRangeOptions.Levels and .PrecisionHours are both *int.)
dasa, err := client.DasaAtRange(context.Background(), birth, start, end,
vedastro.DasaAtRangeOptions{
Levels: vedastro.Ptr(3),
PrecisionHours: vedastro.Ptr(100),
})
if err != nil {
log.Fatal(err)
}
// Dynamic payloads print cleanly with json.MarshalIndent.
data, err := json.MarshalIndent(dasa, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))👉 See full example: examples/vimshottari_dasa
Use Case: Get Chaldean numerology analysis for a name
name := "John Doe"
ctx := context.Background()
birthNumber, err := client.BirthNumber(ctx, birth)
if err != nil {
log.Fatal(err)
}
destinyNumber, err := client.DestinyNumber(ctx, birth)
if err != nil {
log.Fatal(err)
}
prediction, err := client.NameNumberPrediction(ctx, name)
if err != nil {
log.Fatal(err)
}
result := prediction.(map[string]any)
fmt.Println("Birth number: ", birthNumber)
fmt.Println("Destiny number:", destinyNumber)
fmt.Printf("%s: number %v (root %v, ruling planet %v)\n",
name, result["Number"], result["RootNumber"], result["Planet"])
// "Prediction" is HTML-formatted interpretation text; drop the tags for a terminal.
html, _ := result["Prediction"].(string)
fmt.Println(regexp.MustCompile(`<[^>]+>`).ReplaceAllString(html, ""))Output:
Birth number: 7
Destiny number: 2
John Doe: number 34 (root 7, ruling planet Ketu)
This number has the potential to be seen as lucky, ...
Prediction is HTML-formatted — strip the tags for terminal output (this snippet needs the regexp import), or render it in a browser.
👉 See full example: examples/numerology_calculator
Use Case: Ask a plain-English question and get the most relevant passages from classical Vedic books (BPHS, Phaladeepika, Hindu Predictive Astrology, …) — no exact keywords needed
ctx := context.Background()
texts, err := client.GetAvailableSourceTexts(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println("Searchable texts:", texts)
// Natural-language semantic search, narrowed to one book.
passages, err := client.SearchSourceText(ctx, "effects of Saturn in the 7th house",
vedastro.SearchSourceTextOptions{
TopK: vedastro.Ptr(3),
SourceName: vedastro.Ptr("Hindu-Predictive-Astrology"),
})
if err != nil {
log.Fatal(err)
}
for _, item := range passages.([]any) {
passage := item.(map[string]any)
// Lower score = closer match, so invert it into a relevance percentage.
score, _ := passage["score"].(float64)
// Some chunks carry no page number, so tolerate a nil.
page, _ := passage["pageNumber"].(float64)
fmt.Printf("%v p.%.0f (%.0f%%)\n", passage["sourceName"], page, (1-score)*100)
fmt.Printf(" %v\n\n", passage["text"])
}Output:
Searchable texts: [Brihat-Jataka Brihat-Parashara-Hora-Shastra Hindu-Predictive-Astrology Hora-Sara Jaimini-Sutras Phaladeepika Uttara-Kalamrita]
Brihat-Parashara-Hora-Shastra p.381 (28%)
-------+ In the above case, the 2nd lord is Saturn. ...
🤖 This is the same retrieval step that powers VedAstro's RAG/AI features — feed the returned passages into an LLM prompt to build a cited astrology chatbot.
👉 See full example: examples/rag_vedic_books
The Most Common Beginner Issue: Time Format
Format: "HH:MM DD/MM/YYYY +TZ:TZ" (24-hour, DD/MM/YYYY, explicit UTC offset — no timezone names)
| Location | Example | Timezone Offset |
|---|---|---|
| India | "14:30 25/10/1992 +05:30" |
IST = UTC+5:30 |
| USA (East) | "09:30 25/10/1992 -05:00" |
EST = UTC-5:00 |
| USA (West) | "06:30 25/10/1992 -08:00" |
PST = UTC-8:00 |
| Japan | "23:30 25/10/1992 +09:00" |
JST = UTC+9:00 |
| UK | "14:30 25/10/1992 +00:00" |
GMT = UTC+0:00 |
| Australia | "00:30 26/10/1992 +10:00" |
AEST = UTC+10:00 |
Two Ways to Create a Time:
mumbai := vedastro.NewGeoLocation("Mumbai", 72.8777, 19.0760)
// Method 1: API time string (validated immediately)
birth, err := vedastro.NewTime("14:30 25/10/1992 +05:30", mumbai)
// Method 2: from a Go time.Time, keeping its calendar fields and offset
birth, err = vedastro.NewTimeFromDate(time.Date(1992, 10, 25, 14, 30, 0, 0, ist), mumbai)Common Mistakes:
// ❌ Date order must be DD/MM/YYYY
vedastro.NewTime("14:30 1992-10-25 +05:30", mumbai)
// ❌ AM/PM is not supported (use 24-hour)
vedastro.NewTime("2:30 PM 25/10/1992 +05:30", mumbai)
// ❌ Missing UTC offset
vedastro.NewTime("14:30 25/10/1992", mumbai)
// ❌ Named zones are not accepted; use an offset
vedastro.NewTime("14:30 25/10/1992 IST", mumbai)
// ✅ Correct — NewTime returns an error you must handle
birth, err := vedastro.NewTime("14:30 25/10/1992 +05:30", mumbai)
NewGeoLocation(name, longitude, latitude)takes longitude first. Coordinates and the time string are validated when the value is serialized, so an invalidTimefails at call time with a clear error rather than producing a wrong chart.NewTimeitself validates eagerly.
What is Ayanamsa?
Ayanamsa is the difference between the tropical (Western) and sidereal (Vedic) zodiacs. Different systems shift positions by up to ~3°, so a planet near a sign boundary can change sign.
47 systems are available. Common choices:
| Constant | When to Use |
|---|---|
vedastro.AyanamsaLahiri |
Indian government standard, most widely used — the server default when none is set |
vedastro.AyanamsaRaman |
Popular in South India |
vedastro.AyanamsaKrishnamurti |
KP (Krishnamurti Paddhati) system |
vedastro.AyanamsaFaganBradley |
Western sidereal astrology |
vedastro.AyanamsaYukteshwar |
Sri Yukteswar's calculation |
| …42 more | Autocomplete vedastro.Ayanamsa in your editor |
Three ways to set it:
// 1. Per call, via context. Affects this call and its children only,
// so concurrent requests stay independent.
raman := vedastro.WithAyanamsa(context.Background(), vedastro.AyanamsaRaman)
degree, err := client.AyanamsaDegree(raman, birth)
// 2. Per client, as the default for every request from this client.
client := vedastro.NewClient(apiKey,
vedastro.WithDefaultAyanamsa(vedastro.AyanamsaKrishnamurti))
// 3. Unset: the server applies its own default, which measures as Lahiri.A context override wins over the client default, and an empty override value explicitly asks for the server default even when the client has one.
Recommendation:
- 🇮🇳 Indian astrology →
vedastro.AyanamsaLahiri - 🌏 Unsure → omit it (server default measures as Lahiri)
- 📐 KP system →
vedastro.AyanamsaKrishnamurti - 🌍 Western sidereal →
vedastro.AyanamsaFaganBradley
Understanding Kuta Score:
| Score Range | Compatibility | Recommendation |
|---|---|---|
| 33-36 points | Excellent | Highly compatible |
| 25-32 points | Good | Compatible, proceed with confidence |
| 18-24 points | Average | Requires careful consideration |
| Below 18 | Poor | Not recommended without other factors |
The 16 Kutas Explained:
- Graha Maitram (5 pts) - Mental compatibility, happiness
- Gana (6 pts) - Temperament match (Deva/Manushya/Rakshasa)
- Yoni (4 pts) - Sexual compatibility
- Nadi (8 pts) - Health & progeny (most important!)
- Varna (1 pt) - Spiritual/ego compatibility
- …and 11 more factors
Reading the Report:
report, err := client.MatchReport(ctx, person1, person2)
if err != nil {
log.Fatal(err)
}
match := report.(map[string]any)
fmt.Println(match["KutaScore"]) // normalised to 100
fmt.Println(match["Summary"].(map[string]any)["ScoreSummary"])
for _, item := range match["PredictionList"].([]any) {
kuta := item.(map[string]any)
fmt.Printf("%v: %v\n", kuta["Name"], kuta["Nature"]) // Good / Bad / Neutral
fmt.Printf(" Info: %v\n", kuta["Info"])
}Type assertions panic if the shape differs. For untrusted input, use the two-value form (
value, ok := x.(T)) or a type switch instead.
21 runnable programs live in examples/. Run any of them from the repository root:
go run ./examples/quick_start
go run ./examples/daily_panchanga| Example | Use Case | Skill Level |
|---|---|---|
quick_start |
First calculation and decoded result | Beginner |
birth_chart_basics |
Sun, Moon, ascendant, birth constellation | Beginner |
marriage_compatibility |
Compatibility calculation | Beginner |
match_checker |
Full match report | Beginner |
current_planets |
Positions at the current time | Beginner |
daily_panchanga |
Tithi, Nakshatra, Yoga, Karana | Beginner |
numerology_calculator |
Name and birth numerology | Beginner |
horoscope_prediction_names |
Prediction names | Beginner |
custom_ayanamsa |
Lahiri, Raman, Krishnamurti context overrides | Intermediate |
divisional_charts |
Divisional (varga) signs | Intermediate |
transit_analysis |
Planetary transits | Intermediate |
vimshottari_dasa |
Dasa over a date range | Intermediate |
all_planet_data |
Complete data for one planet | Intermediate |
all_astro_data |
Aggregate planet, house, zodiac data | Intermediate |
bhava_chart_data |
House chart | Intermediate |
code_from_api_builder |
API Builder-style call | Intermediate |
rag_vedic_books |
Available books and source-text search | Intermediate |
error_handling |
Cancellation and ordinary error handling | Intermediate |
all_astro_data_json_output |
Export JSON to astro_data.json |
Intermediate |
all_astro_data_csv |
Export planet results to CSV | Intermediate |
batch_processing |
Multiple birth charts | Advanced |
Examples call the live API. Except for the single-call quick start, the shared runner reads VEDASTRO_API_KEY, handles Ctrl+C, and spaces free-tier requests 13 seconds apart. Export examples create their files exclusively and fail if the file already exists — rename old exports before re-running.
The API's Payload is decoded into standard Go JSON values:
| JSON | Go |
|---|---|
| Object | map[string]any |
| Array | []any |
| Number | float64 |
| String / Boolean / null | string / bool / nil |
| SVG response | string |
As in Python, a payload object with exactly one property is unwrapped to that property's value. Zero, false, empty strings, empty collections, and nil are all valid results, so never treat a zero value as "missing" — check the error first, then assert the type.
result, err := client.PlanetNirayanaLongitude(ctx, vedastro.PlanetSun, birth)
if err != nil {
log.Fatal(err)
}
longitude, ok := result.(float64) // numbers decode as float64
if !ok {
log.Fatalf("unexpected type %T", result)
}
fmt.Println(longitude)Methods with optional parameters accept zero or one method-specific options struct. Nil fields are omitted, letting the server apply its defaults. Use vedastro.Ptr to send explicit zero, false, or empty values:
result, err := client.SearchSourceText(ctx, "Saturn",
vedastro.SearchSourceTextOptions{
TopK: vedastro.Ptr(3),
SourceName: vedastro.Ptr("Brihat-Parashara-Hora-Shastra"),
})Passing more than one options value returns an error without sending a request. Defaults are documented on generated fields and in api_manifest.json.
Use your own key via the environment:
client := vedastro.NewClient(os.Getenv("VEDASTRO_API_KEY"))An empty key leaves authentication to the service's free tier. Never embed paid keys in distributed source — Go binaries are trivially string-dumped.
Each client owns its settings and is safe for concurrent requests. Options are applied at construction:
client := vedastro.NewClient(apiKey,
vedastro.WithTimeout(30*time.Second),
vedastro.WithDefaultAyanamsa(vedastro.AyanamsaLahiri),
vedastro.WithBaseURL("https://vedastro.zaishi.net/api/Calculate"),
vedastro.WithHTTPClient(customClient),
)| Option | Effect |
|---|---|
WithTimeout(d) |
Calculation deadline including reading the body (default 120s; an earlier context deadline still wins) |
WithDefaultAyanamsa(v) |
Ayanamsa sent with this client's requests |
WithBaseURL(url) |
Point at a different Calculate service or a test server |
WithHTTPClient(c) |
Custom *http.Client; a shallow copy is retained |
Invalid configuration is reported by the first calculator call, not by NewClient — so a bad base URL surfaces as an error from your request rather than a panic at startup.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := client.PlanetRasiD1Sign(ctx, vedastro.PlanetSun, birth)
switch {
case err == nil:
// use result
case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
// caller cancelled, or the deadline expired
default:
// remote HTTP / API failure arrives as *vedastro.APIError
var apiErr *vedastro.APIError
if errors.As(err, &apiErr) {
fmt.Printf("API error on %s: HTTP %d\n", apiErr.Endpoint, apiErr.StatusCode)
} else {
fmt.Printf("transport failure: %v\n", err)
}
}Remote HTTP/API and malformed-response failures use *vedastro.APIError (with Endpoint, StatusCode, and Message), retrievable via errors.As. Transport errors omit request credentials, and API messages redact the configured key. The SDK never retries automatically — add your own backoff if you need it.
The free tier allows five requests per minute, counted across all clients in all processes on your key. Space requests at least 13 seconds apart. The SDK does not throttle or retry for you.
// A minimal pacer: at most one call every 13 seconds.
type pacer struct {
mu sync.Mutex
last time.Time
gap time.Duration
}
func (p *pacer) wait(ctx context.Context) error {
p.mu.Lock()
wait := p.gap - time.Since(p.last)
p.mu.Unlock()
if wait > 0 {
timer := time.NewTimer(wait)
defer timer.Stop()
select {
case <-timer.C:
case <-ctx.Done():
return ctx.Err()
}
}
p.mu.Lock()
p.last = time.Now()
p.mu.Unlock()
return nil
}See examples/batch_processing for a complete multi-chart version. Paid keys use the service's own (higher) limits.
NewClient prints the familiar one-line banner once per process. There is no network update check at startup. To check explicitly:
info, err := client.CheckForUpdate(ctx)
if err == nil && info.Available {
fmt.Println(info.UpdateCommand) // e.g. go get ...@v1.0.1
fmt.Println(info.RebuildInstructions)
}This queries Go's public module proxy, never sends your API key, and never modifies files. Update your dependency, rebuild, and restart — a running binary keeps its compiled version. To silence the banner entirely, see FAQ.
A: You asserted the wrong type. Result shapes vary by calculator.
// ❌ Object payloads are not strings — this panics at runtime
// name := result.(string)
// ✅ Assert the object, then read the field
object, ok := result.(map[string]any)
if !ok {
log.Fatalf("unexpected type %T", result)
}
name, _ := object["Name"].(string)HouseSignName returns an unwrapped string, while PlanetRasiD1Sign returns a map[string]any — a common source of this panic. Use go doc to check a signature, or a two-value assertion while exploring.
A: The time string failed validation. Use 24-hour time, DD/MM/YYYY order, and an explicit numeric UTC offset:
vedastro.NewTime("14:30 25/10/1992 +05:30", mumbai) // ✅
vedastro.NewTime("2:30 PM 25/10/1992 +05:30", mumbai) // ❌ AM/PM
vedastro.NewTime("14:30 1992-10-25 +05:30", mumbai) // ❌ ISO date
vedastro.NewTime("14:30 25/10/1992", mumbai) // ❌ no offsetA: Longitude must be within ±180 and latitude within ±90, and the name must be non-empty. Check the argument order — NewGeoLocation(name, longitude, latitude).
A: The free tier allows five requests per minute across all clients. Pace calls 13 seconds apart (see Pacing requests) or use a paid key. The error arrives as an *APIError whose Message contains the server's explanation.
A: vedastro.AyanamsaLahiri for Indian astrology, vedastro.AyanamsaKrishnamurti for KP, vedastro.AyanamsaFaganBradley for Western sidereal. Omit it entirely to accept the server default, which measures as Lahiri.
A: Yes. A *Client is safe for concurrent use and owns its settings, so one shared client is enough. Use vedastro.WithAyanamsa(ctx, …) for per-request ayanamsa overrides — it does not mutate shared state. Free-tier limits are per key, not per goroutine.
A: Yes. MIT licensed, and both the free and paid tiers permit commercial use.
A: All 684 calculations and all 47 ayanamsa systems in both. Only throughput differs:
| Feature | Free | Premium |
|---|---|---|
| All calculations | ✅ | ✅ |
| All 47 ayanamsa | ✅ | ✅ |
| Commercial use | ✅ | ✅ |
| Swiss Ephemeris | ✅ | ✅ |
| Rate limit | 5 req/min | Higher (service-set) |
| Cost | $0/month | $1/month |
Premium is quoted as 200 calls/minute by the API's own rate-limit error. Pricing and limits are set by the service — confirm current numbers at vedastro.org/API.html.
A:
- Go to vedastro.org/API.html
- Choose a plan: $1/month or ₹758/year (India)
- Pay via card, UPI, Google Pay, or PayPal
- Get your key instantly from vedastro.org/Account.html
client := vedastro.NewClient(os.Getenv("VEDASTRO_API_KEY"))| What You Get | VedAstro | Competitors |
|---|---|---|
| Monthly Cost | $1/month | $50-$200/month |
| Free Tier | ✅ 5 req/min | ❌ None or very limited |
| Calculations | 684 methods | 50-200 methods |
| Ayanamsa Systems | 47 systems | 3-10 systems |
| Setup Complexity | Zero setup | Complex (DLLs, ephemeris files) |
| Commercial Use | ✅ Both tiers | ❌ Enterprise only |
The Bottom Line: Get 10x more features at 1/50th the price. No credit card needed to start.
| Tier | Price | Rate Limit | Best For |
|---|---|---|---|
| Free | $0/month | 5 req/min | Learning, testing, personal projects |
| Premium | $1/month | Higher (service-set) | Production apps, commercial use |
Indian Developers: ₹79/month or ₹758/year (₹63/month, most popular)
All 684 calculations included in both tiers. The only difference is throughput.
Full API reference: vedastro.org/API.html · pkg.go.dev · go doc
Every calculator is a method on *Client, takes context.Context first, and returns (any, error).
PlanetRasiD1Sign, PlanetNirayanaLongitude, PlanetConstellation, PlanetsInSign, PlanetsInConjunction, IsPlanetRetrograde, IsPlanetExalted, IsPlanetDebilitated, HouseSignName, HouseRasiSign, LordOfHouse, AllPlanetData, AllHouseData, AllZodiacSignData, +211 more
AllHouseNavamshaSign (D9), AllHouseDrekkanaSign (D3), AllHouseChaturthamsaSign (D4), PlanetShashtyamshaD60Sign (D60), PlanetDivisionalLongitude, D1-D60 vargas
LunarDay, TithiNumber, NakshatraPada, NithyaYoga, Karana, RahuKala, GulikaKala, Durmuhurta, SunriseTime, SunsetTime, HoraTable, AyanamsaDegree, PlanetEphemerisLongitude, +51 more
PlanetShadbalaPinda, PlanetStrength, HouseStrength, PlanetIshtaScore, PlanetKashtaScore, AllPlanetOrderedByStrength, PickOutStrongestPlanet, PlanetDignity, IsPlanetVargottama, +53 more
NorthIndianChart, SouthIndianChart, SkyChart, PlanetAspectDegree, PlanetsAspectingPlanet, IsPlanetAspectedByPlanet, EventsAtTime, EventsAtRange, EventStartTime, HoroscopePredictions, SwissEphemeris, +44 more
Chapter5PrashnaMargaPredictions … Chapter30PrashnaMargaPredictions, SarvatobhadraChakra, KotaChakra, SudarsanaChakra, BirthYamaPanchaPakshi, CalculateAshtamangalaNumberFromShells, +few more
SarvashtakavargaChart, BhinnashtakavargaChart, PlanetAshtakvargaBindu, GocharaKakshas, AshtakavargaLongevity, PrastaraAshtakavarga, SodyaAshtakavarga, +13 more
DasaAtRange, DasaAtTime, DasaForNow, DasaForLife, MoolaDasa, NarayanaDasa, KalachakraDasa, TithiAshtottariDasa, +12 more
CalculateEarthquakeRiskScore, IsEarthquakeNearEclipse, IsEarthquakeJupiterSaturnConjunction, IsEarthquakePlanetsClusteredInNarrowArc, +16 more
DetailedAshtakavargaLongevity, MarriageByJupiter, ChildBirthByJupiter1, NativeDeathBySaturn, HasBalarishtaExceptions, MarakaPlanetList, +12 more
GulikaLongitude, MaandiLongitude, DhumaLongitude, UpaketuLongitude, KaalaLongitude, FortunaPoint, DestinyPoint, IsUpagraha, +7 more
PlanetSignTransit, TransitHouseFromLagna, TransitHouseFromMoon, IsGocharaOccurring, GetConstellationTransitStartTime, IsPlanetRetrograde, +7 more
KalaSarpaYoga, JHoraYogaList, IsPlanetInGandanta, KujaDosaScore, ClassifyForKartari, ShubKartariPlanets, PaapaKartariPlanets, +5 more
JaiminiRasiDrishti, JaiminiRasiStrength, TajakaVarshaphala, TajakaYogaList, TrueSiderealSolarReturn, ArudhaLagnaSign, +2 more
FindBirthTimeByMachineLearning, FindBirthTimeByMachineLearningTopK, FindBirthTimeByAnimal, SearchSourceText (RAG over classical texts), GetAvailableSourceTexts, HoroscopePredictionsForLargeAstrologyModelTrainingData, +1 more
BirthNumber, DestinyNumber, NameNumber, NameNumberPrediction, RootNumberFriendship, MainActivity
MatchReport, Tarabala, Chandrabala, YoniKutaAnimal
PredictMedicalHealthConditions, HouseNatureScore, PlanetNatureScore, GetActiveNccBodyRulesAtTime
- Install:
go get github.com/VedAstro/VedAstro.Go@v1.0.0(10 seconds) - Try the examples above: copy, paste, run! (5 minutes)
- Explore demos:
go run ./examples/birth_chart_basics(30 minutes) - Read the docs: pkg.go.dev or
go doc github.com/VedAstro/VedAstro.Go - Build something: your first horoscope service! (1-2 hours)
- Upgrade when ready: vedastro.org/API.html
"I was paying $150/month for a competing API. VedAstro is $1/month with more features and better docs. Absolute no-brainer." — Rahul, India
"Setup took 2 minutes. First calculation worked immediately. No configuration hell. This is how all APIs should be." — Sarah, USA
"684 calculations, 47 ayanamsas, Swiss Ephemeris accuracy, $1/month. I thought there was a catch. There isn't." — Yuki, Japan
"The free tier is generous enough for my personal app with 50 users. When I scale up, $1/month won't break the bank." — Carlos, Brazil
Your Go Code
v
vedastro package (this module, stdlib only)
v
REST API (vedastro.zaishi.net)
v
VedAstro Engine (Azure Cloud)
v
Swiss Ephemeris (NASA JPL data)
The SDK is a thin, typed client: it builds the request body, POSTs it, unwraps the standard { Status, Payload } envelope, and returns the inner payload. Calculations themselves run on VedAstro's servers.
Why this design?
- ✅ Zero third-party dependencies — standard library only
- ✅ Instant updates (684 calculations, always latest, no SDK release needed)
- ✅ Single static binary, no
cgo, no ephemeris downloads - ✅ Cross-platform (Windows/Mac/Linux)
calculate_generated.go, enums_generated.go, and api_manifest.json come from StaticTableGenerator Task 11 in the main VedAstro repository. Do not edit generated files. Coverage is derived from metadata, with first-overload selection matching the other SDKs.
# From the main repository
dotnet run --project StaticTableGenerator -- --task 11
# From this repository
gofmt -w .
go vet ./...
go build ./...
go test -timeout 90s ./...
go test -race -timeout 120s ./...
python scripts/check_python_parity.py ../VedAstro.Python-PUBLIC/vedastro/calculate.pyTask 11 output defaults to the sibling VedAstro.Go-PUBLIC folder; set VEDASTRO_GO_OUT to override it, and optionally VEDASTRO_GOFMT to the gofmt executable. It uses local metadata only (no API, Cosmos, or LLM calls) and writes deterministic, formatted output.
Race checks require a supported platform and a C toolchain. CI tests Go 1.26 and 1.27 on Windows and Linux, including Linux race checks. Tests use local HTTP servers; examples call the live API only when explicitly run.
Release with a new semantic version tag after validation. Never move or replace an existing tag — Go's proxy caches releases permanently. See Go's publishing guide.
Contributions are welcome — issues and PRs at VedAstro.Go.
Note: everything named
*_generated.gois auto-generated. Do not edit it directly; regenerate with Task 11 and re-run the checks above.scripts/check_python_parity.pyguards name and argument-order parity with the Python SDK.
MIT License - Use freely in commercial and personal projects.
VedAstro is non-profit and user-funded. If it saves you time and money:
- ⭐ Star on GitHub (helps others discover us)
- 💰 Subscribe $1/month at vedastro.org/API.html
- 🎁 Donate at vedastro.org/Donate
- 📢 Share with other developers
Every subscription helps keep VedAstro free and open-source! 🙏
- 📖 Full API Docs: vedastro.org/API.html
- 📘 Go package reference: pkg.go.dev/github.com/VedAstro/VedAstro.Go
- 🚀 Quick Start: QUICKSTART.md
- ❓ FAQ: FAQ.md
- 🧪 Runnable examples: examples/README.md
- 🐍 Python SDK: VedAstro.Python
- 🟨 Node.js SDK: VedAstro.NodeJS
- 💬 Telegram: t.me/vedastro_org
- 🐛 Issues: GitHub Issues
- 🌐 Website: vedastro.org
Made with ❤️ by users, for users
Website •
API Docs •
GitHub •
Telegram •
Donate
🪐 Empowering developers to build amazing astrology apps since 2020