Location API. Included on every plan.

Drop-in replacement for Google Maps Places + Time Zone APIs, tuned for astrology. Place autocomplete, signed decimal coordinates, IANA timezone IDs, and historical offsets — unlimited calls, no separate Google bill.

12M+
Places indexed
2
Endpoints
IANA
Timezone IDs
INCL.
On every plan
Why use it

Built for astrology, not driving directions.

Astrology charts need two things from a location: an exact lat/lon and the timezone that was active at the moment of birth. Google's Places API gives you the first. Their Time Zone API gives you the second. They cost $17 and $5 per 1,000 calls respectively, and they're optimised for navigation, not chart math. We bundle both into one API — included on every StarsAPI plan, no separate metering.

Two calls, complete location data

Suggest endpoint returns place IDs as the user types. Details endpoint resolves an ID to coords + timezone in one round trip. That's it.

12M+ places, GeoNames-backed

Cities, towns, villages worldwide. Updated quarterly. Better small-town coverage than commercial geocoders for India and South Asia.

Historical timezone offsets

Returns the IANA timezone ID — not just the current offset. Built-in handling of DST transitions and historical timezone changes (e.g. India's pre-1947 offsets).

Signed decimal coordinates

Latitude and longitude as signed decimal numbers. Pass them directly to any StarsAPI chart endpoint — no deg/min/sec conversion needed.

Live demo

Type a place name. Get a chart-ready response.

This demo hits the live API with a public test key. Try any city worldwide — see exactly what your application would receive in production.

API Response Awaiting selection…
// Select a place from the dropdown above to see the response.

↳ Real integration sends the user's selected locationid to /include/location-info for the full chart payload. The demo above does that automatically when you click a result.

Integration in 5 minutes

Two endpoints. Three steps. Done.

Standard two-call pattern: autocomplete as the user types, then resolve the selected place to coordinates + timezone.

1

Place autocomplete

GET /include/suggest-location

Type-ahead search across 12M+ locations. Send as the user types — recommended minLength: 2.

Request
curl -H "X-Api-Key: YOUR_KEY" \
  "https://starsapi.com/include/suggest-location?term=mumbai"
Response — array of suggestions (verified)
[
  {
    "locationid": "1275339",
    "label": "Mumbai, Maharashtra, India"
  }
]

Note: the response is a flat array of {locationid, label} objects — no value field. Drop directly into jQuery UI Autocomplete, React downshift, or any select component that takes a label/value pair.

2

Resolve to coordinates + timezone

GET /include/location-info

Take the locationid from step 1, get back chart-ready coordinates and timezone in one call.

Request
curl -H "X-Api-Key: YOUR_KEY" \
  "https://starsapi.com/include/location-info?id=1275339"
Response (verified from production API)
{
  "latitude": 19.07283,
  "longitude": 72.88261,
  "ew": 1,
  "ns": 1,
  "long_deg": 72,
  "long_min": 53,
  "lat_deg": 19,
  "lat_min": 4,
  "timezone": "Asia/Kolkata",
  "timezoneoffset": 5.5
}

3 fields go to chart endpoints. The rest are for your UI. Most teams pass just latitude, longitude, and timezone to StarsAPI chart endpoints. The DMS components and direction flags are returned so you can show traditional formats like 19°4′ N · 72°53′ E on chart reports or PDF outputs.

Field Type Purpose
latitude Number (signed decimal) Required by chart endpoints. Negative for South.
longitude Number (signed decimal) Required by chart endpoints. Negative for West.
timezone String (IANA ID) Required by chart endpoints. Handles historical DST automatically.
timezoneoffset Number (hours) Current numeric offset. Useful for legacy systems or display ("UTC+5:30").
lat_deg / lat_min Integers Display only. Render traditional DMS format (e.g. 19°4′ N) on reports.
long_deg / long_min Integers Display only. Same as above for longitude (e.g. 72°53′ E).
ns / ew Integer (1 or 0) Display only. Direction flags — 1 for North/East, 0 for South/West.
3

Send only what chart endpoints actually need

StarsAPI chart endpoints accept exactly three location fields: latitude, longitude, and timezone. The rest of the Location API response is yours to use for display.

// Response from step 2:
const loc = {
  latitude:       19.07283,        // ✓ required by chart endpoints
  longitude:      72.88261,        // ✓ required by chart endpoints
  timezone:       "Asia/Kolkata",  // ✓ required by chart endpoints
  timezoneoffset: 5.5,             // ✗ display only
  lat_deg: 19, lat_min: 4,         // ✗ display only (DMS)
  long_deg: 72, long_min: 53,      // ✗ display only (DMS)
  ns: 1, ew: 1                     // ✗ display only (direction flags)
};

// What chart endpoints actually need — just three fields:
const birthInput = {
  datetime:  "1990-05-15T14:30:00",
  latitude:  loc.latitude,
  longitude: loc.longitude,
  timezone:  loc.timezone,
};

// Pass `birthInput` to any StarsAPI chart endpoint
// (Vedic kundli, Western natal, transits, etc).
// See each product's API reference for endpoint-specific extras.

// Meanwhile, use the display fields on your UI:
// "Birth Place: Mumbai (19°4′ N · 72°53′ E · UTC+5:30)"
const displayLine = `${loc.lat_deg}°${loc.lat_min}′ ${loc.ns ? 'N' : 'S'} · ` +
                    `${loc.long_deg}°${loc.long_min}′ ${loc.ew ? 'E' : 'W'} · ` +
                    `UTC${loc.timezoneoffset >= 0 ? '+' : ''}${loc.timezoneoffset}`;

Why the IANA timezone, not the offset? The IANA timezone string (e.g. Asia/Kolkata) handles historical DST transitions automatically. Numeric offsets describe only today's timezone — they break for births before a country's DST rules changed (e.g. India before 1947, the UK before 1972, Russia's 2014 shift, etc).

Drop-in client snippets

Pre-wired examples for the four most common integration patterns. Copy, swap your API key, ship.

Code example
// jQuery UI Autocomplete + StarsAPI Location
$('#birthplace').autocomplete({
  minLength: 2,
  source: function(req, res) {
    $.ajax({
      url: 'https://starsapi.com/include/suggest-location',
      headers: { 'X-Api-Key': 'YOUR_KEY' },
      data: { term: req.term },
      success: function(data) {
        res(data.map(d => ({
          label: d.label,
          value: d.locationid   // jQuery UI needs 'value'
        })));
      }
    });
  },
  select: function(event, ui) {
    $.ajax({
      url: 'https://starsapi.com/include/location-info',
      headers: { 'X-Api-Key': 'YOUR_KEY' },
      data: { id: ui.item.value },
      success: function(loc) {
        // Required for chart endpoints:
        $('#lat').val(loc.latitude);
        $('#lon').val(loc.longitude);
        $('#tz').val(loc.timezone);
        // Optional — for display on reports:
        $('#dms').val(
          loc.lat_deg + '°' + loc.lat_min + '′ ' + (loc.ns ? 'N' : 'S') + ' · ' +
          loc.long_deg + '°' + loc.long_min + '′ ' + (loc.ew ? 'E' : 'W')
        );
      }
    });
  }
});
// React hook — debounced autocomplete
import { useState, useEffect } from 'react';

const API_KEY = 'YOUR_KEY';
const BASE    = 'https://starsapi.com';

function BirthplaceInput({ onSelect }) {
  const [term, setTerm] = useState('');
  const [results, setResults] = useState([]);

  useEffect(() => {
    if (term.length < 2) return setResults([]);
    const t = setTimeout(async () => {
      const r = await fetch(
        `${BASE}/include/suggest-location?term=${encodeURIComponent(term)}`,
        { headers: { 'X-Api-Key': API_KEY } }
      );
      setResults(await r.json());
    }, 250);
    return () => clearTimeout(t);
  }, [term]);

  async function pick(loc) {
    const r = await fetch(
      `${BASE}/include/location-info?id=${loc.locationid}`,
      { headers: { 'X-Api-Key': API_KEY } }
    );
    const info = await r.json();
    // The 3 fields chart endpoints need:
    onSelect({
      latitude:  info.latitude,
      longitude: info.longitude,
      timezone:  info.timezone,
      // Optional — keep info around if you want to show DMS on a report
      _displayInfo: info,
    });
  }

  return (
    <div>
      <input value={term} onChange={e => setTerm(e.target.value)} />
      {results.map(r => (
        <div key={r.locationid} onClick={() => pick(r)}>{r.label}</div>
      ))}
    </div>
  );
}
// Flutter / Dart — using http package
import 'package:http/http.dart' as http;
import 'dart:convert';

const apiKey = 'YOUR_KEY';
const base = 'https://starsapi.com';

class StarsApiLocation {
  Future<List<Map<String, dynamic>>> suggest(String term) async {
    final r = await http.get(
      Uri.parse('$base/include/suggest-location?term=$term'),
      headers: { 'X-Api-Key': apiKey },
    );
    return List<Map<String, dynamic>>.from(jsonDecode(r.body));
  }

  Future<Map<String, dynamic>> details(String locationId) async {
    final r = await http.get(
      Uri.parse('$base/include/location-info?id=$locationId'),
      headers: { 'X-Api-Key': apiKey },
    );
    return jsonDecode(r.body);
  }
}

// Use with TypeAheadField (flutter_typeahead package)
TypeAheadField<Map<String, dynamic>>(
  suggestionsCallback: (q) => q.length >= 2
    ? StarsApiLocation().suggest(q)
    : Future.value([]),
  itemBuilder: (ctx, item) => ListTile(title: Text(item['label'])),
  onSelected: (item) async {
    final info = await StarsApiLocation().details(item['locationid']);
    // 3 fields go to chart endpoints:
    final lat = info['latitude'], lon = info['longitude'], tz = info['timezone'];
    // The rest of `info` is for display (lat_deg, lat_min, ns, ew, etc).
  },
);
// Node.js / Express — server-side proxy
// Useful if you want to keep your API key off the client.
import express from 'express';
import fetch from 'node-fetch';

const app = express();
const API_KEY = process.env.STARSAPI_KEY;
const BASE = 'https://starsapi.com';

app.get('/api/places/suggest', async (req, res) => {
  const r = await fetch(
    `${BASE}/include/suggest-location?term=${encodeURIComponent(req.query.term)}`,
    { headers: { 'X-Api-Key': API_KEY } }
  );
  res.json(await r.json());
});

app.get('/api/places/details/:id', async (req, res) => {
  const r = await fetch(
    `${BASE}/include/location-info?id=${req.params.id}`,
    { headers: { 'X-Api-Key': API_KEY } }
  );
  res.json(await r.json());
});

app.listen(3000);
Migration guide

Moving from Google Maps Places + Time Zone APIs.

Most teams are using places.googleapis.com/v1/places:autocomplete for autocomplete and maps.googleapis.com/maps/api/timezone for timezone — two calls to two products at $17 + $5 per 1k. Here's the line-by-line swap.

Cost comparison (typical chart-app traffic)

Daily volume Google Places + Time Zone StarsAPI Location Monthly savings
500 autocompletes / 500 timezone lookups $330 / month ($17×15 + $5×15) $0 / month (included) $330
2,000 / 2,000 $1,320 / month $0 / month $1,320
10,000 / 10,000 $6,600 / month $0 / month $6,600

↳ Google pricing reflects standard SKUs as of May 2026: Places Autocomplete $17/1k requests, Time Zone $5/1k requests. Your actual bill may include other Google products. Google pricing reference.

Side-by-side API swap

Before — Google Maps
// Two API products, two billing meters.

// 1) Autocomplete
GET https://places.googleapis.com/v1/places:autocomplete
?input=mumbai
&key=GOOGLE_KEY

// 2) Place Details (for coordinates)
GET https://places.googleapis.com/v1/places/PLACE_ID
?fields=location
&key=GOOGLE_KEY

// 3) Time Zone (separate API)
GET https://maps.googleapis.com/maps/api/timezone/json
?location=LAT,LNG
&timestamp=BIRTH_UNIX
&key=GOOGLE_KEY

// Three calls. Two billing meters.
// Time Zone API also requires the birth UNIX timestamp
// to handle historical DST correctly.
After — StarsAPI
// One API. Both calls included.

// 1) Autocomplete
GET https://starsapi.com/include/suggest-location
?term=mumbai
Header: X-Api-Key: YOUR_KEY

// 2) Details (coords + timezone in one call)
GET https://starsapi.com/include/location-info
?id=LOCATION_ID
Header: X-Api-Key: YOUR_KEY

// Two calls. Zero extra cost.
// Timezone returned as IANA identifier — handles
// historical DST natively, no UNIX timestamp needed.

Field mapping

What you need Google Maps field StarsAPI field
Place ID place_id (autocomplete predictions) locationid
Display label description or formatted_address label
Latitude location.latitude (Place Details) latitude (signed decimal)
Longitude location.longitude longitude (signed decimal)
Timezone (IANA) timeZoneId (Time Zone API) timezone
Timezone offset rawOffset + dstOffset (seconds) timezoneoffset (hours)

Migration steps

  1. Get your StarsAPI key. Any plan from $29/mo includes unlimited location calls.
  2. Replace the autocomplete call. Change the URL to /include/suggest-location, change auth from ?key= to X-Api-Key header. Rename predictions → flat array, place_idlocationid, descriptionlabel.
  3. Collapse Place Details + Time Zone into one call. Hit /include/location-info?id={locationid} — get coords and IANA timezone in a single response.
  4. Drop the timestamp logic. StarsAPI returns the IANA timezone identifier directly. Use it with Intl.DateTimeFormat or pytz — they handle historical DST without needing a UNIX timestamp.
  5. Cancel your Google Maps billing for Places Autocomplete and Time Zone API. (Leave any other Maps products you use — Directions, Distance Matrix, etc. — they're not affected.)
Get started

Included on every plan. No metering.

Location calls don't count toward your endpoint quota. Hit Place Suggest and Place Details as much as your app needs — autocomplete every keystroke if you want — your StarsAPI plan covers it.