Vedic Astrology API Integration Guide for Developers
Complete guide to integrating Vedic astrology APIs in your application. Includes authentication, birth charts, panchang, dasha periods, and compatibility matching.
Vedic Astrology API Integration Guide for Developers
Integrating Vedic astrology calculations into your application requires accurate astronomical computations, proper timezone handling, and comprehensive astrological interpretations. This guide shows you how to integrate the RoxyAPI Vedic Astrology API into your Node.js, Python, or React applications with production-ready patterns.
By the end of this tutorial, you will have a complete API client with error handling, caching, and retry logic for all major Vedic astrology endpoints.
What We Will Build
Our integration covers all essential Vedic astrology features:
- Birth Chart Generation - Complete D1 Rashi chart with planetary positions
- Panchang Calculations - Tithi, Nakshatra, Yoga, Karana for any date
- Dasha Periods - Vimshottari Mahadasha, Antardasha, Pratyantardasha
- Compatibility Matching - Ashtakoot gun milan scoring
- Dosha Detection - Manglik and Kalsarpa dosha checking
- Navamsa Chart - D9 divisional chart for marriage analysis
Prerequisites
- Node.js 18+ or Python 3.9+
- RoxyAPI account with API key (sign up here)
- Basic understanding of Vedic astrology concepts
Step 1: Authentication Setup
Node.js/TypeScript
// lib/vedic-api-client.ts
import fetch from 'node-fetch';
interface VedicAPIConfig {
apiKey: string;
baseURL?: string;
timeout?: number;
}
class VedicAstrologyAPI {
private apiKey: string;
private baseURL: string;
private timeout: number;
constructor(config: VedicAPIConfig) {
this.apiKey = config.apiKey;
this.baseURL = config.baseURL || 'http://localhost:3001/api/v2/vedic-astrology';
this.timeout = config.timeout || 10000;
}
private async request<T>(
endpoint: string,
method: 'GET' | 'POST' = 'POST',
body?: any
): Promise<T> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
try {
const response = await fetch(`${this.baseURL}${endpoint}`, {
method,
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey,
},
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new VedicAPIError(
error.message || `API error: ${response.statusText}`,
response.status,
error
);
}
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
if (error instanceof VedicAPIError) throw error;
throw new VedicAPIError('Network error', 0, error);
}
}
}
class VedicAPIError extends Error {
constructor(
message: string,
public statusCode: number,
public details?: any
) {
super(message);
this.name = 'VedicAPIError';
}
}
export { VedicAstrologyAPI, VedicAPIError };
Python
# vedic_api_client.py
import requests
from typing import Dict, Any, Optional
import json
class VedicAPIError(Exception):
def __init__(self, message: str, status_code: int = 0, details: Any = None):
super().__init__(message)
self.status_code = status_code
self.details = details
class VedicAstrologyAPI:
def __init__(
self,
api_key: str,
base_url: str = "http://localhost:3001/api/v2/vedic-astrology",
timeout: int = 10
):
self.api_key = api_key
self.base_url = base_url
self.timeout = timeout
self.session = requests.Session()
self.session.headers.update({
'Content-Type': 'application/json',
'X-API-Key': api_key
})
def _request(
self,
endpoint: str,
method: str = 'POST',
data: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
url = f"{self.base_url}{endpoint}"
try:
if method == 'POST':
response = self.session.post(
url,
json=data,
timeout=self.timeout
)
else:
response = self.session.get(url, timeout=self.timeout)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
try:
error_data = e.response.json()
message = error_data.get('message', str(e))
except:
message = str(e)
raise VedicAPIError(message, e.response.status_code, error_data)
except requests.exceptions.RequestException as e:
raise VedicAPIError(f"Network error: {str(e)}", 0)
Step 2: Birth Chart Endpoint
The birth chart endpoint returns a complete D1 Rashi chart with all planetary positions, nakshatras, and house descriptions.
TypeScript Implementation
interface BirthChartParams {
year: number;
month: number; // 1-12
day: number; // 1-31
hour: number; // 0-23.99
latitude: number;
longitude: number;
}
interface Planet {
graha: string;
rashi: string;
longitude: number;
nakshatra: {
name: string;
pada: number;
key: string;
ratio: number;
};
isRetrograde: boolean;
}
interface BirthChartResponse {
rashis: {
[rashiName: string]: {
rashi: string;
planets: string[];
};
};
meta: {
[grahaName: string]: Planet;
};
houses: Array<{
house: number;
rashi: string;
lord: string;
description: string;
}>;
}
class VedicAstrologyAPI {
// ... previous code ...
async getBirthChart(params: BirthChartParams): Promise<BirthChartResponse> {
return this.request<BirthChartResponse>('/birth-chart', 'POST', params);
}
}
// Usage example
const api = new VedicAstrologyAPI({
apiKey: 'your_api_key_here',
});
const birthChart = await api.getBirthChart({
year: 1990,
month: 7,
day: 15,
hour: 14.5, // 14:30
latitude: 28.6139,
longitude: 77.209,
});
console.log('Lagna:', birthChart.meta.Lagna.rashi);
console.log('Sun:', birthChart.meta.Sun.rashi);
console.log('Moon Nakshatra:', birthChart.meta.Moon.nakshatra.name);
Python Implementation
from typing import TypedDict, List
class BirthChartParams(TypedDict):
year: int
month: int
day: int
hour: float
latitude: float
longitude: float
class VedicAstrologyAPI:
# ... previous code ...
def get_birth_chart(self, params: BirthChartParams) -> dict:
return self._request('/birth-chart', 'POST', params)
# Usage
api = VedicAstrologyAPI(api_key='your_api_key_here')
birth_chart = api.get_birth_chart({
'year': 1990,
'month': 7,
'day': 15,
'hour': 14.5,
'latitude': 28.6139,
'longitude': 77.209
})
print(f"Lagna: {birth_chart['meta']['Lagna']['rashi']}")
print(f"Sun: {birth_chart['meta']['Sun']['rashi']}")
print(f"Moon Nakshatra: {birth_chart['meta']['Moon']['nakshatra']['name']}")
Example Response
{
"rashis": {
"aries": {
"rashi": "Aries",
"planets": ["Mars"]
},
"gemini": {
"rashi": "Gemini",
"planets": ["Sun", "Jupiter", "Venus"]
},
"cancer": {
"rashi": "Cancer",
"planets": ["Mercury"]
},
"leo": {
"rashi": "Leo",
"planets": ["Rahu"]
},
"sagittarius": {
"rashi": "Sagittarius",
"planets": ["Saturn"]
},
"aquarius": {
"rashi": "Aquarius",
"planets": ["Lagna", "Ketu"]
},
"pisces": {
"rashi": "Pisces",
"planets": ["Moon"]
}
},
"meta": {
"Lagna": {
"graha": "Lagna",
"rashi": "Aquarius",
"longitude": 301.46,
"nakshatra": {
"name": "Dhanishta",
"pada": 3,
"key": "dhanishta",
"ratio": 0.543
},
"isRetrograde": false
},
"Sun": {
"graha": "Sun",
"rashi": "Gemini",
"longitude": 88.92,
"nakshatra": {
"name": "Punarvasu",
"pada": 3,
"key": "punarvasu",
"ratio": 0.218
},
"isRetrograde": false
},
"Moon": {
"graha": "Moon",
"rashi": "Pisces",
"longitude": 357.79,
"nakshatra": {
"name": "Revati",
"pada": 4,
"key": "revati",
"ratio": 0.947
},
"isRetrograde": true
}
},
"houses": [
{
"house": 1,
"rashi": "Aquarius",
"lord": "Saturn",
"description": "Self, personality, physical body, general health"
},
{
"house": 2,
"rashi": "Pisces",
"lord": "Jupiter",
"description": "Wealth, family, speech, food, early education"
}
]
}
Step 3: Panchang Endpoint
Calculate Tithi, Nakshatra, Yoga, and Karana for any date and location.
Implementation
interface PanchangParams {
year: number;
month: number;
day: number;
hour: number;
latitude: number;
longitude: number;
}
interface PanchangResponse {
tithi: {
number: number;
name: string;
paksha: string;
completion: number;
deity: string;
element: string;
characteristics: string;
};
nakshatra: {
number: number;
name: string;
lord: string;
deity: string;
symbol: string;
characteristics: string;
};
yoga: {
number: number;
name: string;
completion: number;
characteristics: string;
};
karana: {
number: number;
name: string;
type: string;
completion: number;
characteristics: string;
};
sunLongitude: number;
moonLongitude: number;
}
class VedicAstrologyAPI {
// ... previous code ...
async getPanchang(params: PanchangParams): Promise<PanchangResponse> {
return this.request<PanchangResponse>('/panchang/basic', 'POST', params);
}
}
// Usage
const panchang = await api.getPanchang({
year: 2026,
month: 7,
day: 15,
hour: 14.5,
latitude: 28.6139,
longitude: 77.209,
});
console.log('Tithi:', panchang.tithi.name);
console.log('Nakshatra:', panchang.nakshatra.name);
console.log('Yoga:', panchang.yoga.name);
console.log('Karana:', panchang.karana.name);
Example Response
{
"tithi": {
"number": 2,
"name": "Dvītiyā",
"paksha": "Shukla Paksha",
"completion": 38.94,
"deity": "Vidhāṭṛ",
"element": "Earth",
"characteristics": "Good for agriculture, ceremonies"
},
"nakshatra": {
"number": 8,
"name": "Pushya",
"lord": "Saturn",
"deity": "Brihaspati",
"symbol": "Cow's Udder",
"characteristics": "Most auspicious, disciplined, nurturing, protectors"
},
"yoga": {
"number": 15,
"name": "Vajra",
"completion": 58.91,
"characteristics": "Power Burst - wealthy, lascivious, changeable, forceful"
},
"karana": {
"number": 3,
"name": "Kaulav",
"type": "char",
"completion": 77.88,
"characteristics": "Very friendly, talents like love and caring"
},
"sunLongitude": 88.924,
"moonLongitude": 105.597
}
Step 4: Dasha Periods Endpoint
Get current Vimshottari Mahadasha, Antardasha, and Pratyantardasha.
Implementation
interface DashaParams {
year: number;
month: number;
day: number;
hour: number;
latitude: number;
longitude: number;
}
interface DashaPeriod {
planet: string;
startDate: string;
endDate: string;
durationYears: number;
remainingYears: number;
remainingMonths: number;
remainingDays: number;
}
interface DashaResponse {
birthMoonNakshatra: {
name: string;
lord: string;
};
mahadasha: DashaPeriod;
antardasha: DashaPeriod;
pratyantardasha: DashaPeriod;
}
class VedicAstrologyAPI {
// ... previous code ...
async getCurrentDasha(params: DashaParams): Promise<DashaResponse> {
return this.request<DashaResponse>('/dasha/current', 'POST', params);
}
}
// Usage
const dasha = await api.getCurrentDasha({
year: 1990,
month: 7,
day: 15,
hour: 14.5,
latitude: 28.6139,
longitude: 77.209,
});
console.log('Current Mahadasha:', dasha.mahadasha.planet);
console.log('Period:', dasha.mahadasha.startDate, 'to', dasha.mahadasha.endDate);
console.log('Remaining:', dasha.mahadasha.remainingYears, 'years');
Example Response
{
"birthMoonNakshatra": {
"name": "Ashwini",
"lord": "Ketu"
},
"mahadasha": {
"planet": "Moon",
"startDate": "2023-01-15T00:00:00Z",
"endDate": "2033-01-15T00:00:00Z",
"durationYears": 10,
"remainingYears": 6,
"remainingMonths": 11,
"remainingDays": 24
},
"antardasha": {
"planet": "Jupiter",
"startDate": "2025-12-15T00:00:00Z",
"endDate": "2027-04-15T00:00:00Z",
"durationYears": 1.33,
"remainingYears": 1,
"remainingMonths": 2,
"remainingDays": 10
},
"pratyantardasha": {
"planet": "Jupiter",
"startDate": "2025-12-15T00:00:00Z",
"endDate": "2026-02-20T00:00:00Z",
"durationYears": 0.178,
"remainingYears": 0,
"remainingMonths": 1,
"remainingDays": 12
}
}
Step 5: Compatibility Matching
Calculate Ashtakoot gun milan compatibility between two people.
Implementation
interface CompatibilityParams {
person1: BirthChartParams;
person2: BirthChartParams;
}
interface CompatibilityBreakdown {
category: string;
score: number;
description: string;
}
interface CompatibilityResponse {
total: number;
maxScore: number;
percentage: number;
isCompatible: boolean;
breakdown: CompatibilityBreakdown[];
}
class VedicAstrologyAPI {
// ... previous code ...
async calculateCompatibility(
params: CompatibilityParams
): Promise<CompatibilityResponse> {
return this.request<CompatibilityResponse>('/compatibility', 'POST', params);
}
}
// Usage
const compatibility = await api.calculateCompatibility({
person1: {
year: 1990,
month: 7,
day: 15,
hour: 14.5,
latitude: 28.6139,
longitude: 77.209,
},
person2: {
year: 1992,
month: 3,
day: 20,
hour: 10.0,
latitude: 19.076,
longitude: 72.8777,
},
});
console.log(`Compatibility: ${compatibility.total}/${compatibility.maxScore}`);
console.log(`Percentage: ${compatibility.percentage}%`);
console.log('Rating:', compatibility.isCompatible ? 'Compatible' : 'Not Compatible');
Example Response
{
"total": 18.5,
"maxScore": 36,
"percentage": 51.39,
"isCompatible": true,
"breakdown": [
{
"category": "Nakshatra (Varna)",
"score": 0,
"description": "Spiritual compatibility"
},
{
"category": "Gana",
"score": 0,
"description": "Temperament match"
},
{
"category": "Yoni",
"score": 0,
"description": "Physical/sexual compatibility"
},
{
"category": "Rashi Lord",
"score": 3,
"description": "Mutual affection"
},
{
"category": "Vasya",
"score": 1,
"description": "Magnetic control"
},
{
"category": "Tara",
"score": 1.5,
"description": "Birth star compatibility"
},
{
"category": "Nadi",
"score": 8,
"description": "Health and progeny"
},
{
"category": "Bhakoot",
"score": 5,
"description": "Love and prosperity"
}
]
}
Step 6: Error Handling
Implement robust error handling with retries:
class VedicAstrologyAPI {
// ... previous code ...
async requestWithRetry<T>(
endpoint: string,
method: 'GET' | 'POST',
body?: any,
maxRetries = 3
): Promise<T> {
let lastError: Error;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await this.request<T>(endpoint, method, body);
} catch (error) {
lastError = error as Error;
// Don't retry on client errors (4xx)
if (error instanceof VedicAPIError && error.statusCode >= 400 && error.statusCode < 500) {
throw error;
}
// Wait before retrying (exponential backoff)
if (attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
throw lastError!;
}
}
Python Error Handling
import time
class VedicAstrologyAPI:
# ... previous code ...
def _request_with_retry(
self,
endpoint: str,
method: str = 'POST',
data: Optional[Dict[str, Any]] = None,
max_retries: int = 3
) -> Dict[str, Any]:
last_error = None
for attempt in range(max_retries):
try:
return self._request(endpoint, method, data)
except VedicAPIError as e:
last_error = e
# Don't retry client errors
if 400 <= e.status_code < 500:
raise
# Wait before retrying (exponential backoff)
if attempt < max_retries - 1:
delay = 2 ** attempt
time.sleep(delay)
raise last_error
Step 7: Caching Strategy
Implement intelligent caching to reduce API calls:
import { createClient } from 'redis';
class CachedVedicAPI extends VedicAstrologyAPI {
private redis: ReturnType<typeof createClient>;
constructor(config: VedicAPIConfig) {
super(config);
this.redis = createClient({ url: process.env.REDIS_URL });
this.redis.connect();
}
async getBirthChartCached(params: BirthChartParams): Promise<BirthChartResponse> {
// Birth charts never change - cache indefinitely
const cacheKey = `chart:${params.year}:${params.month}:${params.day}:${params.hour}:${params.latitude}:${params.longitude}`;
const cached = await this.redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
const result = await this.getBirthChart(params);
await this.redis.set(cacheKey, JSON.stringify(result), {
EX: 86400 * 30, // 30 days
});
return result;
}
async getPanchangCached(params: PanchangParams): Promise<PanchangResponse> {
// Panchang changes daily - shorter cache
const cacheKey = `panchang:${params.year}:${params.month}:${params.day}:${params.latitude}:${params.longitude}`;
const cached = await this.redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
const result = await this.getPanchang(params);
await this.redis.set(cacheKey, JSON.stringify(result), {
EX: 86400, // 1 day
});
return result;
}
}
Step 8: Rate Limiting
Respect API rate limits with a queue:
class RateLimitedVedicAPI extends CachedVedicAPI {
private queue: Array<() => Promise<any>> = [];
private processing = false;
private requestsPerSecond = 10;
private async processQueue() {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
while (this.queue.length > 0) {
const request = this.queue.shift();
if (request) {
await request();
await new Promise((resolve) =>
setTimeout(resolve, 1000 / this.requestsPerSecond)
);
}
}
this.processing = false;
}
protected async request<T>(
endpoint: string,
method: 'GET' | 'POST',
body?: any
): Promise<T> {
return new Promise((resolve, reject) => {
this.queue.push(async () => {
try {
const result = await super.request<T>(endpoint, method, body);
resolve(result);
} catch (error) {
reject(error);
}
});
this.processQueue();
});
}
}
Step 9: Batch Operations
Process multiple charts efficiently:
class VedicAstrologyAPI {
// ... previous code ...
async getBirthChartsBatch(
profiles: BirthChartParams[]
): Promise<BirthChartResponse[]> {
// Process in parallel with concurrency limit
const batchSize = 5;
const results: BirthChartResponse[] = [];
for (let i = 0; i < profiles.length; i += batchSize) {
const batch = profiles.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map((profile) => this.getBirthChart(profile))
);
results.push(...batchResults);
}
return results;
}
}
Step 10: Complete Production Client
Here is the final production-ready client:
// vedic-api-client.ts
import fetch from 'node-fetch';
import { createClient } from 'redis';
export class VedicAstrologyClient {
private apiKey: string;
private baseURL: string;
private timeout: number;
private redis?: ReturnType<typeof createClient>;
private maxRetries: number;
constructor(config: {
apiKey: string;
baseURL?: string;
timeout?: number;
redisURL?: string;
maxRetries?: number;
}) {
this.apiKey = config.apiKey;
this.baseURL = config.baseURL || 'http://localhost:3001/api/v2/vedic-astrology';
this.timeout = config.timeout || 10000;
this.maxRetries = config.maxRetries || 3;
if (config.redisURL) {
this.redis = createClient({ url: config.redisURL });
this.redis.connect();
}
}
async getBirthChart(params: BirthChartParams): Promise<BirthChartResponse> {
const cacheKey = `chart:${JSON.stringify(params)}`;
return this.cachedRequest(cacheKey, '/birth-chart', params, 86400 * 30);
}
async getPanchang(params: PanchangParams): Promise<PanchangResponse> {
const cacheKey = `panchang:${JSON.stringify(params)}`;
return this.cachedRequest(cacheKey, '/panchang/basic', params, 86400);
}
async getCurrentDasha(params: DashaParams): Promise<DashaResponse> {
return this.requestWithRetry('/dasha/current', 'POST', params);
}
async calculateCompatibility(
params: CompatibilityParams
): Promise<CompatibilityResponse> {
const cacheKey = `compat:${JSON.stringify(params)}`;
return this.cachedRequest(cacheKey, '/compatibility', params, 86400 * 30);
}
private async cachedRequest<T>(
cacheKey: string,
endpoint: string,
params: any,
ttl: number
): Promise<T> {
if (this.redis) {
const cached = await this.redis.get(cacheKey);
if (cached) return JSON.parse(cached);
}
const result = await this.requestWithRetry<T>(endpoint, 'POST', params);
if (this.redis) {
await this.redis.set(cacheKey, JSON.stringify(result), { EX: ttl });
}
return result;
}
private async requestWithRetry<T>(
endpoint: string,
method: 'GET' | 'POST',
body?: any
): Promise<T> {
let lastError: Error;
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
try {
return await this.request<T>(endpoint, method, body);
} catch (error) {
lastError = error as Error;
if (error instanceof VedicAPIError && error.statusCode >= 400 && error.statusCode < 500) {
throw error;
}
if (attempt < this.maxRetries - 1) {
await new Promise((resolve) =>
setTimeout(resolve, Math.pow(2, attempt) * 1000)
);
}
}
}
throw lastError!;
}
private async request<T>(
endpoint: string,
method: 'GET' | 'POST',
body?: any
): Promise<T> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
try {
const response = await fetch(`${this.baseURL}${endpoint}`, {
method,
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey,
},
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new VedicAPIError(
error.message || `API error: ${response.statusText}`,
response.status,
error
);
}
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
if (error instanceof VedicAPIError) throw error;
throw new VedicAPIError('Network error', 0, error);
}
}
}
class VedicAPIError extends Error {
constructor(
message: string,
public statusCode: number,
public details?: any
) {
super(message);
this.name = 'VedicAPIError';
}
}
// Usage
const client = new VedicAstrologyClient({
apiKey: process.env.VEDIC_API_KEY!,
redisURL: process.env.REDIS_URL,
maxRetries: 3,
});
const chart = await client.getBirthChart({
year: 1990,
month: 7,
day: 15,
hour: 14.5,
latitude: 28.6139,
longitude: 77.209,
});
Best Practices
1. Input Validation
Always validate user inputs before making API calls:
function validateBirthData(params: BirthChartParams): void {
if (params.year < 1900 || params.year > 2100) {
throw new Error('Year must be between 1900 and 2100');
}
if (params.month < 1 || params.month > 12) {
throw new Error('Month must be between 1 and 12');
}
if (params.day < 1 || params.day > 31) {
throw new Error('Day must be between 1 and 31');
}
if (params.hour < 0 || params.hour >= 24) {
throw new Error('Hour must be between 0 and 23.99');
}
if (params.latitude < -90 || params.latitude > 90) {
throw new Error('Latitude must be between -90 and 90');
}
if (params.longitude < -180 || params.longitude > 180) {
throw new Error('Longitude must be between -180 and 180');
}
}
2. Timezone Handling
Convert local time to UTC before sending to API:
import { DateTime } from 'luxon';
function convertToUTC(
year: number,
month: number,
day: number,
hour: number,
timezone: string
): { year: number; month: number; day: number; hour: number } {
const localTime = DateTime.fromObject(
{ year, month, day, hour: Math.floor(hour), minute: (hour % 1) * 60 },
{ zone: timezone }
);
const utcTime = localTime.toUTC();
return {
year: utcTime.year,
month: utcTime.month,
day: utcTime.day,
hour: utcTime.hour + utcTime.minute / 60,
};
}
3. Monitoring and Logging
Track API usage and errors:
class MonitoredVedicAPI extends VedicAstrologyClient {
private logger: any; // Use your logging library
protected async request<T>(
endpoint: string,
method: 'GET' | 'POST',
body?: any
): Promise<T> {
const startTime = Date.now();
try {
const result = await super.request<T>(endpoint, method, body);
this.logger.info('API request successful', {
endpoint,
duration: Date.now() - startTime,
});
return result;
} catch (error) {
this.logger.error('API request failed', {
endpoint,
error: error instanceof Error ? error.message : 'Unknown error',
duration: Date.now() - startTime,
});
throw error;
}
}
}
Conclusion
You now have a production-ready Vedic astrology API client with proper error handling, caching, rate limiting, and retry logic. The RoxyAPI Vedic Astrology API handles all complex astronomical calculations and astrological interpretations, allowing you to focus on building great user experiences.
Key features implemented:
- Complete TypeScript and Python clients
- Birth chart, panchang, dasha, and compatibility endpoints
- Intelligent caching with Redis
- Exponential backoff retry logic
- Rate limiting and batch operations
- Comprehensive error handling
- Input validation and timezone conversion
Ready to integrate Vedic astrology into your app? Sign up for RoxyAPI and get your API key today. Full documentation at roxyapi.com/docs.