FlutterApril 202612 min read

Vedic Astrology API for Flutter — Complete Dart Integration Guide

Build a production-ready Vedic astrology app with Flutter and the VedIntel™ AstroAPI. This guide covers dio setup, Dart model classes, FutureBuilder patterns, and complete screens for kundali chart, panchang widget, and dasha timeline — everything you need to publish on Play Store or App Store.

The VedIntel™ AstroAPI is a REST API with 110 endpoints — no native Flutter SDK required. Any Flutter app that can make HTTP calls can use it, which means it works with http, dio, or Dio + Retrofit.

1. Add Dependencies to pubspec.yaml

# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.3
  flutter_dotenv: ^5.1.0  # for API key management
  intl: ^0.19.0           # for date formatting

2. AstroService — Dio API Client in Dart

Create a service class that wraps all astrology API calls. Dio's BaseOptions automatically appends your API key to every request — no repetition needed:

// lib/services/astro_service.dart
import 'package:dio/dio.dart';

class AstroService {
  static const _base = 'https://vedintelastroapi.com/api/v1';
  static const _key  = 'YOUR_API_KEY'; // use flutter_dotenv in production

  final _dio = Dio(BaseOptions(
    baseUrl: _base,
    queryParameters: {'api_key': _key},
    connectTimeout: const Duration(seconds: 10),
    receiveTimeout: const Duration(seconds: 15),
  ));

  Future<Map<String, dynamic>> getPlanetDetails({
    required String dob,   // DD/MM/YYYY
    required String tob,   // HH:MM (24hr)
    required double lat,
    required double lon,
    required double tz,
  }) async {
    final response = await _dio.get('/horoscope/planet-details', queryParameters: {
      'dob': dob, 'tob': tob, 'lat': lat, 'lon': lon, 'tz': tz,
    });
    if (response.data['status'] != 200) {
      throw Exception(response.data['error'] ?? 'API error');
    }
    return response.data['response'] as Map<String, dynamic>;
  }

  Future<Map<String, dynamic>> getMahadasha({
    required String dob, required String tob,
    required double lat, required double lon, required double tz,
  }) async {
    final response = await _dio.get('/dashas/current-mahadasha', queryParameters: {
      'dob': dob, 'tob': tob, 'lat': lat, 'lon': lon, 'tz': tz,
    });
    return response.data['response'] as Map<String, dynamic>;
  }

  Future<Map<String, dynamic>> getPanchang({
    required String date,  // DD/MM/YYYY
    required double lat, required double lon, required double tz,
  }) async {
    final response = await _dio.get('/panchang/panchang', queryParameters: {
      'dob': date, 'tob': '06:00', 'lat': lat, 'lon': lon, 'tz': tz,
    });
    return response.data['response'] as Map<String, dynamic>;
  }

  Future<Map<String, dynamic>> getMatchingScore({
    required String mDob, required String mTob,
    required double mLat, required double mLon, required double mTz,
    required String fDob, required String fTob,
    required double fLat, required double fLon, required double fTz,
  }) async {
    final response = await _dio.get('/matching/south-match', queryParameters: {
      'm_dob': mDob, 'm_tob': mTob, 'm_lat': mLat, 'm_lon': mLon, 'm_tz': mTz,
      'f_dob': fDob, 'f_tob': fTob, 'f_lat': fLat, 'f_lon': fLon, 'f_tz': fTz,
    });
    return response.data['response'] as Map<String, dynamic>;
  }
}

3. Dart Model Class for Planet Data

Typed model classes keep your Flutter code clean and enable null safety throughout:

// lib/models/planet.dart
class Planet {
  final String name;
  final String sign;
  final int house;
  final double degree;
  final String nakshatra;
  final bool isRetrograde;

  Planet({
    required this.name,
    required this.sign,
    required this.house,
    required this.degree,
    required this.nakshatra,
    required this.isRetrograde,
  });

  factory Planet.fromJson(Map<String, dynamic> json) => Planet(
    name:        json['name']        as String,
    sign:        json['sign']        as String,
    house:       json['house']       as int,
    degree:      (json['degree'] as num).toDouble(),
    nakshatra:   json['nakshatra']   as String,
    isRetrograde: json['is_retro'] == true || json['is_retro'] == 'true',
  );
}

4. Kundali Screen with FutureBuilder

A complete Flutter screen that fetches and displays all 9 planetary positions. Styled in the dark Vedic theme — ready to customise with your brand colours:

// lib/screens/kundali_screen.dart
import 'package:flutter/material.dart';
import '../services/astro_service.dart';
import '../models/planet.dart';

class KundaliScreen extends StatefulWidget {
  final String dob, tob;
  final double lat, lon, tz;
  const KundaliScreen({
    super.key,
    required this.dob, required this.tob,
    required this.lat, required this.lon, required this.tz,
  });
  @override State<KundaliScreen> createState() => _KundaliScreenState();
}

class _KundaliScreenState extends State<KundaliScreen> {
  late Future<List<Planet>> _planetsFuture;

  @override
  void initState() {
    super.initState();
    _planetsFuture = AstroService().getPlanetDetails(
      dob: widget.dob, tob: widget.tob,
      lat: widget.lat, lon: widget.lon, tz: widget.tz,
    ).then((data) {
      final List rawPlanets = data['planets'] as List;
      return rawPlanets.map((p) => Planet.fromJson(p)).toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0A0F1E),
      appBar: AppBar(
        title: const Text('Your Kundali', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
        backgroundColor: const Color(0xFF0A0F1E),
        iconTheme: const IconThemeData(color: Colors.white),
      ),
      body: FutureBuilder<List<Planet>>(
        future: _planetsFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator(color: Color(0xFF4F46E5)));
          }
          if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}', style: const TextStyle(color: Colors.red)));
          }
          final planets = snapshot.data!;
          return ListView.builder(
            padding: const EdgeInsets.all(16),
            itemCount: planets.length,
            itemBuilder: (context, i) => PlanetCard(planet: planets[i]),
          );
        },
      ),
    );
  }
}

class PlanetCard extends StatelessWidget {
  final Planet planet;
  const PlanetCard({super.key, required this.planet});

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: const Color(0xFF1A1F35),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFF2D3250)),
      ),
      child: Row(children: [
        Container(
          width: 44, height: 44,
          decoration: const BoxDecoration(
            shape: BoxShape.circle,
            color: Color(0xFF4F46E5),
          ),
          child: Center(child: Text(planet.name[0], style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
        ),
        const SizedBox(width: 14),
        Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          Row(children: [
            Text(planet.name, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w700, fontSize: 15)),
            if (planet.isRetrograde) ...[
              const SizedBox(width: 6),
              Container(padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                decoration: BoxDecoration(color: Colors.amber.withOpacity(0.2), borderRadius: BorderRadius.circular(4)),
                child: const Text('℞', style: TextStyle(color: Colors.amber, fontSize: 11)),
              ),
            ],
          ]),
          const SizedBox(height: 4),
          Text('${planet.sign} • House ${planet.house} • ${planet.nakshatra}',
            style: const TextStyle(color: Color(0xFF8B92B8), fontSize: 13)),
        ])),
        Text('${planet.degree.toStringAsFixed(2)}°', style: const TextStyle(color: Color(0xFF6366F1), fontSize: 13, fontWeight: FontWeight.w600)),
      ]),
    );
  }
}

5. Date and Time Helper Functions

The API expects DD/MM/YYYY— different from Dart's ISO format. Use these helpers throughout your app:

// lib/utils/date_helpers.dart
import 'package:intl/intl.dart';

/// Converts DateTime to API format: DD/MM/YYYY
String toApiDate(DateTime dt) => DateFormat('dd/MM/yyyy').format(dt);

/// Converts TimeOfDay to API format: HH:MM
String toApiTime(TimeOfDay t) =>
  '${t.hour.toString().padLeft(2, '0')}:${t.minute.toString().padLeft(2, '0')}';

// Usage
// final dob = toApiDate(DateTime(1977, 10, 1)); // '01/10/1977'
// final tob = toApiTime(const TimeOfDay(hour: 11, minute: 40)); // '11:40'

What to Build Next in Your Flutter Astrology App

Daily Panchang Screen

/panchang/panchang

Tithi, Yoga, Nakshatra for today

Dasha Timeline

/dashas/mahadasha

Vimshottari period visualisation

Kundali Matching

/matching/south-match

Marriage compatibility score

AI Chart Reading

/ai/chat

Claude AI astrologer in your app

Mangal Dosha Check

/dosha/mangal-dosh

Dosha detection + remedies

Divisional Charts

/horoscope/divisional-charts

D9 Navamsa, D10 Dashamsha

Ready to ship your Flutter astrology app?

500 free API calls. Works on Android, iOS, and Flutter Web. No credit card required.

Get free API key →Full API Docs