Birth Place & Timezone API. Included on every plan.
Every astrology form starts with the same field, and everything calculated afterwards depends on getting it right. Your user types a few letters, picks their place, and you get coordinates ready to pass straight into a chart plus the timezone that actually applied on their birth date — not today's. 5.7 million cities, towns and villages across 254 countries, ranked by population so the obvious answer comes first, on the same key as everything else. No Google Cloud account, no second key, no separate invoice.
Two calls. A place name in, a chart-ready location out.
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.
5.7 million 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.
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.
// 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.
Two endpoints. Three steps. Done.
Standard two-call pattern: autocomplete as the user types, then resolve the selected place to coordinates + timezone.
Place autocomplete
GET/include/suggest-location
Type-ahead search across cities, towns and villages worldwide. Send as the user types — minLength: 2 keeps the call count sensible.
curl -H "X-Api-Key: YOUR_KEY" \
"https://starsapi.com/include/suggest-location?term=mumbai"
[
{
"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.
Resolve to coordinates + timezone
GET/include/location-info
Take the locationid from step 1, get back chart-ready coordinates and timezone in one call.
curl -H "X-Api-Key: YOUR_KEY" \
"https://starsapi.com/include/location-info?id=1275339"
{
"latitude": 19.07283,
"longitude": 72.88261,
"timezone": "Asia/Kolkata",
"timezoneoffset": 5.5
}
Three fields go to the chart endpoints. Pass latitude, longitude and timezone and you are done — timezoneoffset comes along for display, not for sending. If you also want the traditional DMS components and hemisphere flags, to print 19°4′ N · 72°53′ E on a report, add &fields=full and they come back too.
| 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 | Only with fields=full. Display only — render DMS format (e.g. 19°4′ N) on reports. |
long_deg / long_min |
Integers | Only with fields=full. Display only — same for longitude (e.g. 72°53′ E). |
ns / ew |
Integer (1 or −1) | Only with fields=full. Hemisphere — 1 for North/East, −1 for South/West. Test with > 0, not for truthiness. |
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
};
// Add &fields=full to step 2 and you also get:
// lat_deg: 19, lat_min: 4, long_deg: 72, long_min: 53
// ns: 1, ew: 1 // 1 = North/East, -1 = South/West
// 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)"
// Note the > 0 — ns and ew are 1 or -1, and -1 is truthy in JavaScript.
const displayLine = `${loc.lat_deg}°${loc.lat_min}′ ${loc.ns > 0 ? 'N' : 'S'} · ` +
`${loc.long_deg}°${loc.long_min}′ ${loc.ew > 0 ? '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.
// 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'];
// Add fields=full to also get lat_deg, lat_min, ns, ew for display.
},
);
// 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);
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
// 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
×tamp=BIRTH_UNIX
&key=GOOGLE_KEY
// Three calls. Two billing meters.
// Time Zone API also requires the birth UNIX timestamp
// to handle historical DST correctly.
// 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
- Get your StarsAPI key. Any plan from $29/mo includes location lookups on the same credits as every other endpoint.
- Replace the autocomplete call. Change the URL to
/include/suggest-location, change auth from?key=toX-Api-Keyheader. Renamepredictions→ flat array,place_id→locationid,description→label. - Collapse Place Details + Time Zone into one call. Hit
/include/location-info?id={locationid}— get coords and IANA timezone in a single response. - Drop the timestamp logic. StarsAPI returns the IANA timezone identifier directly. Use it with
Intl.DateTimeFormatorpytz— they handle historical DST without needing a UNIX timestamp. - 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.)
Included on every plan. No second vendor.
Place Suggest and Place Details draw on the same endpoint credits as the rest of the API, so there is nothing extra to buy and nothing separate to meter. What you are not paying for is a second vendor — no Google Cloud account, no second key to protect, no invoice to reconcile at the end of the month.