DEV Community

Vedika Intelligence
Vedika Intelligence

Posted on

From Zero to Horoscope: Building a TypeScript Client for Vedic Astrology [2026-03]

When we talk about API integration in TypeScript, we rarely discuss the mystical. Usually, it’s CRUD operations, financial data, or weather forecasts. But sometimes, you want to build something a little more... esoteric.

Enter the Vedika API. It’s an AI-powered Vedic astrology service. It solves a specific problem: you feed it a question and a birth chart (date, time, location), and it generates an AI-driven insight.

For a TypeScript developer, integrating this isn't just about making a POST request. It's about rigorously defining the shape of the cosmos (and the data) before you actually ask it a question.

In this post, we’ll build a type-safe client from scratch. We’ll focus on how to structure your interfaces, handle async operations, and catch the edge cases that usually break production apps.

The Problem: The "Any" Trap

Before we write code, let’s look at the friction point. If you simply use any in TypeScript, you bypass the compiler's safety net.

// ❌ The dangerous way
async function getHoroscope(question: string) {
  const res = await fetch('...');
  const data = await res.json(); // TypeScript thinks data is any
  return data.prediction; // 💥 Runtime crash if the API changes
}
Enter fullscreen mode Exit fullscreen mode

If the API response structure shifts slightly (which happens often during AI model training), your app crashes.

The Solution: Strongly Typed Interfaces

The Vedika API has a single endpoint: POST /api/v1/astrology/query.

To make this robust, we need to define what the input looks like and what the output looks like.

1. Defining the Data Shapes

First, let's define the input structure. The API expects a question string and a birthDetails object containing date, latitude, and longitude.

// types.ts

/**
 * Represents the geographic location of birth.
 * Using strict number types for coordinates.
 */
interface BirthDetails {
  date: string; // ISO 8601 format: YYYY-MM-DD
  time: string; // ISO 8601 format: HH:mm:ss
  lat: number;
  lng: number;
}

/**
 * The request payload for the Vedika API.
 */
interface AstrologyQueryRequest {
  question: string;
  birthDetails: BirthDetails;
}

/**
 * The expected response structure from Vedika.
 * We use 'unknown' initially to force us to handle the data explicitly.
 */
interface AstrologyResponse {
  prediction: string;
  planetary_positions?: Record<string, string>;
  remedial_measures?: string[];
  error?: string;
}
Enter fullscreen mode Exit fullscreen mode

Notice we used string for dates. In JSON (which APIs communicate over), dates are rarely objects. They are serialized strings. If we tried to use a native Date object in the interface, we would have to deal with serialization logic manually every time we sent the request.

2. The Client Class

Now, let's wrap the fetch logic in a class. This encapsulates our configuration and error handling.

Top comments (0)