API reference / Western astrology
Western astrology
Tropical natal charts, transits, sun-sign forecasts and synastry.
32 endpoints. Every endpoint is POST with a JSON body and your key in the Authorization header. Request schemas and examples come from the OpenAPI document; each example response was captured from the live engine and its data fields are a guide to the shape, not a contract.
Western Natal Chart
POSTAvailable
https://api.96astro.com/v1/western/western-natal-chartTropical natal chart: Sun, Moon and rising signs, ascendant and midheaven, planets with sign and house, the house cusps, and aspects with orb and meaning.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
| Value | Meaning |
|---|---|
P | Placidus |
K | Koch |
W | Whole sign |
E | Equal |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringdate· stringtime· stringlat· numberlon· numbertz· numberjulian_day· numbersun_sign· stringmoon_sign· stringascendant_sign· stringbig_three· objectascendant· objectmidheaven· objectplanets· array of objecthouses· objectaspects· array of objectaspect_count· integerhouse_system· string
Example request
curl -X POST https://api.96astro.com/v1/western/western-natal-chart \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-natal-chart", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernNatalChart({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-natal-chart",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_natal_chart({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-natal-chart');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-natal-chart", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"date": "1990-10-18",
"time": "14:30:00",
"lat": 28.6139,
"lon": 77.209,
"tz": 5.5,
"julian_day": 2448182.875,
"sun_sign": "Libra",
"moon_sign": "Libra",
"ascendant_sign": "Aquarius",
"big_three": {
"sun": {
"sign": "Libra",
"symbol": "♎"
},
"moon": {
"sign": "Libra",
"symbol": "♎"
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Planet Details
POSTAvailable
https://api.96astro.com/v1/western/western-planet-detailsTropical longitude, sign, element, mode, ruler and house for each planet.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringplanets· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-planet-details \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-planet-details", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernPlanetDetails({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-planet-details",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_planet_details({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-planet-details');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-planet-details", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"planets": [
{
"planet": "Sun",
"name": "Sun",
"symbol": "☉",
"longitude": 204.7272,
"degree": "24°43'38\" Libra",
"degree_in_sign": 24.73,
"sign": "Libra",
"sign_symbol": "♎",
"element": "Air",
"mode": "Cardinal",
"ruler": "Venus",
"house": 8,
"house_signification": "Transformation, shared resources, death, sexuality, inheritance",
"available": true,
"retrograde": false,
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western House Cusps
POSTAvailable
https://api.96astro.com/v1/western/western-house-cuspsTwelve house cusps with sign, signification, ruler and the planets in each, plus the ascendant and midheaven.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
| Value | Meaning |
|---|---|
P | Placidus |
K | Koch |
W | Whole sign |
E | Equal |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringhouse_system· stringascendant· objectmidheaven· objecthouses· array of objectunplaced· array of stringcomplete· boolean
Example request
curl -X POST https://api.96astro.com/v1/western/western-house-cusps \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-house-cusps", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernHouseCusps({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-house-cusps",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_house_cusps({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-house-cusps');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-house-cusps", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"house_system": "P",
"ascendant": {
"longitude": 317.6256,
"dms": "17°37'32\" Aquarius",
"sign": "Aquarius",
"sign_symbol": "♒"
},
"midheaven": {
"longitude": 240.945,
"dms": "00°56'42\" Sagittarius",
"sign": "Sagittarius",
"sign_symbol": "♐"
},
"houses": [
{
"house": 1,
"cusp": 317.6256,
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Natal Aspects
POSTAvailable
https://api.96astro.com/v1/western/western-natal-aspectsAspects between natal planets with orb, nature and meaning, split into major and minor.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringtotal_aspects· integermajor_aspects· array of objectminor_aspects· array of objectall_aspects· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-natal-aspects \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-natal-aspects", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernNatalAspects({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-natal-aspects",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_natal_aspects({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-natal-aspects');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-natal-aspects", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"total_aspects": 23,
"major_aspects": [
{
"planet1": "Moon",
"planet1_symbol": "☽",
"planet2": "Mercury",
"planet2_symbol": "☿",
"aspect": "Conjunction",
"symbol": "☌",
"nature": "Intensifying",
"orb": 0.46,
"exact_angle": 0.46,
"meaning": "☽ Moon merges and intensifies ☿ Mercury — emotions, instincts, and inner needs conjunction with mind, communication, and perception."
},
{
"planet1": "Moon",
"planet1_symbol": "☽",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Natal Wheel
POSTAvailable
https://api.96astro.com/v1/western/western-natal-wheelThe natal wheel as an SVG drawing with real house cusps and aspect lines, plus the cusp, planet and aspect data drawn.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON, SVG
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
| Value | Meaning |
|---|---|
P | Placidus |
K | Koch |
W | Whole sign |
E | Equal |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
placidus· objecthouse_system· stringimages· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-natal-wheel \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-natal-wheel", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernNatalWheel({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-natal-wheel",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_natal_wheel({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-natal-wheel');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-natal-wheel", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"placidus": {
"cusps": [
317.6256380956435,
358.45149540760406,
33.37273415297357
],
"asc_long": 317.6256,
"mc_long": 240.945,
"planets": {
"Sun": {
"longitude": 204.7272,
"retrograde": false
},
"Moon": {
"longitude": 201.6087,
"retrograde": false
},
"Mercury": {
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Detailed Planet Report
POSTAvailable
https://api.96astro.com/v1/western/western-detailed-reportInterpretive report: each planet's sign, house, dignity and meaning, the houses, the dominant element and the key aspects, with a summary.
- Credits
- 10 credits
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response (JSON); PDF via /v1/jobs/pdf
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringhouse_system· stringsummary· stringsun_sign· stringmoon_sign· stringascendant· objectmidheaven· objectdominant_element· stringhouses· array of objectplanets· array of objectkey_aspects· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-detailed-report \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-detailed-report", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernDetailedReport({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-detailed-report",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_detailed_report({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-detailed-report');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-detailed-report", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"house_system": "placidus",
"summary": "Native has Sun in Libra, Moon in Libra, and Aquarius Rising. The chart contains 23 active aspects. Dominant element: Air.",
"sun_sign": "Libra",
"moon_sign": "Libra",
"ascendant": {
"longitude": 317.6256,
"sign": "Aquarius",
"degree_in_sign": 17.6256
},
"midheaven": {
"longitude": 240.945,
"sign": "Sagittarius",
"degree_in_sign": 0.945
},
"dominant_element": "Air",
"houses": [
{
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Lunar Node Report
POSTAvailable
https://api.96astro.com/v1/western/western-node-reportThe lunar node's sign, degree and house with the house meaning, its ruler's sign and house, and an interpretation.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
| Value | Meaning |
|---|---|
P | Placidus |
K | Koch |
W | Whole sign |
E | Equal |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringnode_considered· stringnode_current_zodiac· stringnode_degree· stringnode_current_house· integernode_house_meaning· stringnode_lord· stringnode_lord_zodiac· stringnode_lord_house· integernode_prediction· string
Example request
curl -X POST https://api.96astro.com/v1/western/western-node-report \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-node-report", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernNodeReport({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-node-report",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_node_report({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-node-report');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-node-report", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "",
"node_considered": "North Node",
"node_current_zodiac": "Aquarius",
"node_degree": "03°40'13\" Aquarius",
"node_current_house": 12,
"node_house_meaning": "Hidden matters, solitude, spirituality, karma, secret enemies",
"node_lord": "Uranus",
"node_lord_zodiac": "Capricorn",
"node_lord_house": 11,
"node_prediction": "Your north node sits in Aquarius in house 12, which points growth toward hidden matters, solitude, spirituality, karma, secret enemies through the qualities of Aquarius. Its ruler Uranus is in Capricorn in house 11, so progress here comes by way of rebellion, innovation, and sudden change."
},
"meta": {
"request_id": "req_00000000000000000000",
"api_version": "v1",
"credits_used": 0,
"warnings": [],
"language": "en"
}
}Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Ascendant Report
POSTAvailable
https://api.96astro.com/v1/western/western-ascendant-reportRising sign with degree, element and mode, the chart ruler's sign and house, and an interpretation.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
| Value | Meaning |
|---|---|
P | Placidus |
K | Koch |
W | Whole sign |
E | Equal |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringplanet_considered· stringascendant_current_zodiac· stringascendant_degree· stringascendant_element· stringascendant_mode· stringascendant_lord· stringascendant_lord_zodiac· stringascendant_lord_house· integerascendant_prediction· string
Example request
curl -X POST https://api.96astro.com/v1/western/western-ascendant-report \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-ascendant-report", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernAscendantReport({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-ascendant-report",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_ascendant_report({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-ascendant-report');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-ascendant-report", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "",
"planet_considered": "Ascendant",
"ascendant_current_zodiac": "Aquarius",
"ascendant_degree": "17°37'32\" Aquarius",
"ascendant_element": "Air",
"ascendant_mode": "Fixed",
"ascendant_lord": "Uranus",
"ascendant_lord_zodiac": "Capricorn",
"ascendant_lord_house": 11,
"ascendant_prediction": "You rise in Aquarius, a fixed air sign, so first impressions of you carry that quality before anything else does. The chart's ruler is Uranus, placed in Capricorn in house 11 -- so your outward manner is steered by friends, groups, hopes, dreams, social networks."
},
"meta": {
"request_id": "req_00000000000000000000",
"api_version": "v1",
"credits_used": 0,
"warnings": [],
"language": "en"
}
}Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Transit Chart
POSTAvailable
https://api.96astro.com/v1/western/western-transit-chartNatal and current transit planet positions, transit-to-natal aspects with orb, intensity and meaning, and the major transits.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringas_of· stringnatal_planets· array of objecttransit_planets· array of objecttransit_to_natal_aspects· array of objectdominant_element· stringmajor_transits· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-transit-chart \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-transit-chart", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernTransitChart({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-transit-chart",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_transit_chart({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-transit-chart');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-transit-chart", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"as_of": "2026-10-14",
"natal_planets": [
{
"planet": "Sun",
"name": "Sun",
"available": true,
"longitude": 204.7272,
"sign": "Libra",
"sign_symbol": "♎",
"degree": "24°43'38\" Libra",
"degree_in_sign": 24.73,
"retrograde": false,
"speed": 0.9932,
"symbol": "☉"
},
{
"planet": "Moon",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Transit Wheel
POSTAvailable
https://api.96astro.com/v1/western/western-transit-wheelThe natal wheel with the transiting planets drawn around it, as an SVG drawing, plus the transit-to-natal aspects and a table of both rings.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON, SVG
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringas_of· stringinner_ring· stringouter_ring· stringhouses_shown· stringtransit_to_natal_aspects· array of objecttable· objectimages· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-transit-wheel \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-transit-wheel", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernTransitWheel({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-transit-wheel",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_transit_wheel({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-transit-wheel');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-transit-wheel", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"as_of": "2026-10-14",
"inner_ring": "natal",
"outer_ring": "transit",
"houses_shown": "natal",
"transit_to_natal_aspects": [
{
"transit_planet": "Sun",
"transit_sign": "Libra",
"transit_retrograde": false,
"natal_planet": "Venus",
"natal_sign": "Libra",
"aspect": "Conjunction",
"symbol": "☌",
"nature": "Intensifying",
"orb": 0.06,
"intensity": "major",
"period": "Today",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Transit Dates
POSTAvailable
https://api.96astro.com/v1/western/western-transit-datesDates when transiting planets aspect natal points within a look-ahead window.
- Credits
- 3 credits
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
days_aheadintegerOptional | Look-ahead window in days. Default: Limits: minimum 1, maximum 1830 |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringdays_requested· integerdays_scanned· integerwindow_capped· booleanmax_days· integerevents_found· integerevents_returned· integerevents_truncated· booleantransit_events· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-transit-dates \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-transit-dates", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernTransitDates({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-transit-dates",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_transit_dates({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-transit-dates');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-transit-dates", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"days_requested": 90,
"days_scanned": 90,
"window_capped": false,
"max_days": 730,
"events_found": 9,
"events_returned": 9,
"events_truncated": false,
"transit_events": [
{
"date": "2026-10-15",
"exact_at": "2026-10-15T19:08:37Z",
"transit_planet": "Jupiter",
"transit_sign": "Leo",
"transit_retrograde": false,
"natal_planet": "Mercury",
"natal_sign": "Libra",
"aspect": "Sextile",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Daily Transit Prediction
POSTAvailable
https://api.96astro.com/v1/western/western-daily-transitA day's theme from transits to the natal chart, with the active and major transit-to-natal aspects and their meanings.
- Credits
- 1 credit
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
house_systemstringOptional | P Placidus, K Koch, W Whole sign, E Equal. Default: Allowed values: PKWE |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringdate· stringsun_sign· stringdaily_theme· stringdominant_element· stringactive_transits· array of objecttransit_count· integermajor_transits· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-daily-transit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}'const response = await fetch("https://api.96astro.com/v1/western/western-daily-transit", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernDailyTransit({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-daily-transit",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_daily_transit({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-daily-transit');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-daily-transit", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Native",
"date": "2026-10-14",
"sun_sign": "Libra",
"daily_theme": "Assert your desire for fairness and beauty",
"dominant_element": "Fire",
"active_transits": [
{
"transit_planet": "Sun",
"transit_sign": "Libra",
"transit_retrograde": false,
"natal_planet": "Venus",
"natal_sign": "Libra",
"aspect": "Conjunction",
"symbol": "☌",
"nature": "Intensifying",
"orb": 0.06,
"intensity": "major",
"period": "Today",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Yearly Forecast
POSTAvailable
https://api.96astro.com/v1/western/western-yearly-forecastYear ahead from the solar return: the return moment and chart, the year's main transit themes with exact dates, and a summary.
- Credits
- 10 credits
- Input
- Birth details
- Output
- JSON
- Delivery
- Direct response (JSON); PDF via /v1/jobs/pdf
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
ayanamshastringOptional | Default: |
languagestringOptional | Output language (ISO 639-1). The values listed are the ones this capability supports; any other is refused with 422 unsupported_language. Identifiers, enum values and numbers never change with language. Default: Allowed value: en |
namestringOptional | Name to print in readings. Default: Limits: at most 120 characters |
target_yearintegerRequired | Calendar year of the solar return, e.g. 2026. Limits: minimum 1800, maximum 2399 Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· nulltarget_year· integerhouse_system· stringsun_sign· stringsolar_return· objectreturn_year· objectdominant_element· stringreturn_chart· objectthemes· array of objectthemes_method· stringsummary· string
Example request
curl -X POST https://api.96astro.com/v1/western/western-yearly-forecast \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"target_year": 2026
}'const response = await fetch("https://api.96astro.com/v1/western/western-yearly-forecast", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"target_year": 2026
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernYearlyForecast({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"target_year": 2026
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-yearly-forecast",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"target_year": 2026,
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_yearly_forecast({
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"target_year": 2026,
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-yearly-forecast');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'target_year' => 2026,
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"target_year": 2026
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-yearly-forecast", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": null,
"target_year": 2026,
"house_system": "placidus",
"sun_sign": "Libra",
"solar_return": {
"utc": "2026-10-18T02:17:53Z",
"local": {
"datetime": "2026-10-18T07:47:53+05:30",
"timezone": "Asia/Kolkata"
},
"sun_longitude": 204.7272,
"location": {
"latitude": 28.6139,
"longitude": 77.209,
"basis": "birth_place"
}
},
"return_year": {
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Current Planet Positions (Tropical)
POSTAvailable
https://api.96astro.com/v1/western/western-transit-planetsCurrent tropical planet positions with sign, degree and retrograde flags, plus the dominant element.
- Credits
- 1 credit
- Input
- Name
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
namestringOptional | Name to print in the reading (optional). Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringas_of· stringplanets· array of objectdominant_element· stringretrograde_planets· array of stringretrograde_count· integer
Example request
curl -X POST https://api.96astro.com/v1/western/western-transit-planets \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": ""
}'const response = await fetch("https://api.96astro.com/v1/western/western-transit-planets", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": ""
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernTransitPlanets({
"name": ""
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-transit-planets",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"name": "",
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_transit_planets({
"name": "",
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-transit-planets');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => '',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"name": ""
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-transit-planets", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Seeker",
"as_of": "2026-10-14T08:30:17Z",
"planets": [
{
"planet": "Sun",
"symbol": "☉",
"sign": "Libra",
"sign_symbol": "♎",
"degree": "21°01'01\" Libra",
"retrograde": false,
"element": "Air"
},
{
"planet": "Moon",
"symbol": "☽",
"sign": "Sagittarius",
"sign_symbol": "♐",
"degree": "03°48'47\" Sagittarius",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
General Transits: Daily
POSTAvailable
https://api.96astro.com/v1/western/western-general-transits-dailyThe day's tropical planet positions and the aspects between them, not tied to a chart, with the dominant element and retrograde planets.
- Credits
- 1 credit
- Input
- Name
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
namestringOptional | Name to print in the reading (optional). Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringdate· stringplanet_positions· array of objectcurrent_aspects· array of objectdominant_element· stringretrograde_planets· array of string
Example request
curl -X POST https://api.96astro.com/v1/western/western-general-transits-daily \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": ""
}'const response = await fetch("https://api.96astro.com/v1/western/western-general-transits-daily", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": ""
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernGeneralTransitsDaily({
"name": ""
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-general-transits-daily",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"name": "",
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_general_transits_daily({
"name": "",
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-general-transits-daily');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => '',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"name": ""
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-general-transits-daily", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Seeker",
"date": "2026-10-14",
"planet_positions": [
{
"planet": "Sun",
"name": "Sun",
"available": true,
"longitude": 201.017,
"sign": "Libra",
"sign_symbol": "♎",
"degree": "21°01'01\" Libra",
"degree_in_sign": 21.02,
"retrograde": false,
"speed": 0.9907,
"symbol": "☉"
},
{
"planet": "Moon",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
General Transits: Weekly
POSTAvailable
https://api.96astro.com/v1/western/western-general-transits-weeklyDay by day for a week: key aspects, dominant element, retrograde planets and the Moon's sign, not tied to a chart.
- Credits
- 1 credit
- Input
- Name
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
namestringOptional | Name to print in the reading (optional). Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringweek· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-general-transits-weekly \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": ""
}'const response = await fetch("https://api.96astro.com/v1/western/western-general-transits-weekly", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": ""
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernGeneralTransitsWeekly({
"name": ""
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-general-transits-weekly",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"name": "",
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_general_transits_weekly({
"name": "",
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-general-transits-weekly');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => '',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"name": ""
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-general-transits-weekly", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Seeker",
"week": [
{
"date": "2026-10-14",
"day_of_week": "Wednesday",
"key_aspects": [
{
"planet1": "Moon",
"planet1_symbol": "☽",
"planet2": "Uranus",
"planet2_symbol": "♅",
"aspect": "Opposition",
"symbol": "☍",
"nature": "Polarizing",
"orb": 0.35,
"exact_angle": 179.65,
"meaning": "☽ Moon polarizes and confronts ♅ Uranus — emotions, instincts, and inner needs opposition with rebellion, innovation, and sudden change."
},
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
General Transits: Monthly
POSTAvailable
https://api.96astro.com/v1/western/western-general-transits-monthlyWeek by week for a month: key aspects, dominant element, retrograde planets and the Moon's sign, not tied to a chart.
- Credits
- 1 credit
- Input
- Name
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
namestringOptional | Name to print in the reading (optional). Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringweeks· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-general-transits-monthly \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": ""
}'const response = await fetch("https://api.96astro.com/v1/western/western-general-transits-monthly", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": ""
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernGeneralTransitsMonthly({
"name": ""
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-general-transits-monthly",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"name": "",
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_general_transits_monthly({
"name": "",
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-general-transits-monthly');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => '',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"name": ""
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-general-transits-monthly", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Seeker",
"weeks": [
{
"week_starting": "2026-10-14",
"key_aspects": [
{
"planet1": "Moon",
"planet1_symbol": "☽",
"planet2": "Uranus",
"planet2_symbol": "♅",
"aspect": "Opposition",
"symbol": "☍",
"nature": "Polarizing",
"orb": 0.35,
"exact_angle": 179.65,
"meaning": "☽ Moon polarizes and confronts ♅ Uranus — emotions, instincts, and inner needs opposition with rebellion, innovation, and sudden change."
},
{
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Sun-Sign Daily Forecast
POSTAvailable
https://api.96astro.com/v1/western/western-sun-dailyA day's forecast for a sun sign: theme, the Moon's sign and phase, aspects to the sign's ruler and the major sky aspects.
- Credits
- 1 credit
- Input
- Specific input
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
sun_signstringRequired | Tropical sun sign, e.g. Leo. Allowed values: AriesTaurusGeminiCancerLeoVirgoLibraScorpioSagittariusCapricornAquariusPisces Example: |
namestringOptional | Default: Limits: at most 120 characters |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
| Value | Meaning |
|---|---|
aries | Aries |
taurus | Taurus |
gemini | Gemini |
cancer | Cancer |
leo | Leo |
virgo | Virgo |
libra | Libra |
scorpio | Scorpio |
sagittarius | Sagittarius |
capricorn | Capricorn |
aquarius | Aquarius |
pisces | Pisces |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringsun_sign· stringdate· stringdaily_theme· stringdominant_element· stringmoon_sign_today· stringmoon_phase_note· stringlucky_element· stringmode· stringruling_planet· stringruler_aspects· array of objectmajor_sky_aspects· array of objecttransiting_venus_sign· stringtransiting_mars_sign· stringtransiting_mercury_sign· stringretrograde_planets· array of string
Example request
curl -X POST https://api.96astro.com/v1/western/western-sun-daily \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sun_sign": "Leo"
}'const response = await fetch("https://api.96astro.com/v1/western/western-sun-daily", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"sun_sign": "Leo"
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernSunDaily({
"sun_sign": "Leo"
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-sun-daily",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"sun_sign": "Leo",
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_sun_daily({
"sun_sign": "Leo",
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-sun-daily');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'sun_sign' => 'Leo',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"sun_sign": "Leo"
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-sun-daily", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Leo",
"sun_sign": "Leo",
"date": "2026-10-14",
"daily_theme": "Shine brilliantly — creative and romantic day Your ruling planet Sun creates underlying stress with Uranus today (Sesquiquadrate, orb 0.78°) — minor stress energy shapes your focus. The sky's strongest aspect: Neptune ⚹ Pluto (Sextile, orb 0.57°) — harmonious influence on everyone. The Moon in Sagittarius (Fire) shapes the emotional tone. Mercury in Scorpio influences communication. Venus in Scorpio and Mars in Leo colour love and action. Retrograde planets today: Venus, Saturn, Uranus, Neptune, Pluto, North Node — review and reflect rather than launch.",
"dominant_element": "Fire",
"moon_sign_today": "Sagittarius",
"moon_phase_note": "Moon in Sagittarius (Fire) — Emotionally freedom-seeking; optimistic and adventure-hungry",
"lucky_element": "Fire",
"mode": "Fixed",
"ruling_planet": "Sun",
"ruler_aspects": [
{
"planet1": "Sun",
"planet1_symbol": "☉",
"planet2": "Uranus",
"planet2_symbol": "♅",
"aspect": "Sesquiquadrate",
"symbol": "⚼",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Sun-Sign Weekly Forecast
POSTAvailable
https://api.96astro.com/v1/western/western-sun-weeklyDay by day for a week for a sun sign: theme, Moon sign, key aspects and aspects to the sign's ruler.
- Credits
- 1 credit
- Input
- Specific input
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
sun_signstringRequired | Tropical sun sign, e.g. Leo. Allowed values: AriesTaurusGeminiCancerLeoVirgoLibraScorpioSagittariusCapricornAquariusPisces Example: |
namestringOptional | Default: Limits: at most 120 characters |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
| Value | Meaning |
|---|---|
aries | Aries |
taurus | Taurus |
gemini | Gemini |
cancer | Cancer |
leo | Leo |
virgo | Virgo |
libra | Libra |
scorpio | Scorpio |
sagittarius | Sagittarius |
capricorn | Capricorn |
aquarius | Aquarius |
pisces | Pisces |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringsun_sign· stringruling_planet· stringweek· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/western-sun-weekly \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sun_sign": "Leo"
}'const response = await fetch("https://api.96astro.com/v1/western/western-sun-weekly", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"sun_sign": "Leo"
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernSunWeekly({
"sun_sign": "Leo"
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-sun-weekly",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"sun_sign": "Leo",
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_sun_weekly({
"sun_sign": "Leo",
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-sun-weekly');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'sun_sign' => 'Leo',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"sun_sign": "Leo"
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-sun-weekly", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "Leo",
"sun_sign": "Leo",
"ruling_planet": "Sun",
"week": [
{
"date": "2026-10-14",
"day_of_week": "Wednesday",
"theme": "Shine brilliantly — creative and romantic day Sun semi-square Moon (orb 0.58°): minor friction. Key aspect: Moon ☍ Uranus.",
"dominant_element": "Fire",
"moon_sign": "Sagittarius",
"key_aspects": [
{
"planet1": "Moon",
"planet1_symbol": "☽",
"planet2": "Uranus",
"planet2_symbol": "♅",
"aspect": "Opposition",
"symbol": "☍",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Sun-Sign Match
POSTAvailable
https://api.96astro.com/v1/western/western-sun-sign-matchCompatibility from two sun signs alone: their elements, a score out of a maximum, a verdict and a summary.
- Credits
- 1 credit
- Input
- Specific input
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
sign_astringRequired | Allowed values: AriesTaurusGeminiCancerLeoVirgoLibraScorpioSagittariusCapricornAquariusPisces Example: |
sign_bstringRequired | Allowed values: AriesTaurusGeminiCancerLeoVirgoLibraScorpioSagittariusCapricornAquariusPisces Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
sign_a· stringsign_b· stringelement_a· stringelement_b· stringscore· integermaximum· integerverdict· stringsummary· string
Example request
curl -X POST https://api.96astro.com/v1/western/western-sun-sign-match \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sign_a": "Leo",
"sign_b": "Aquarius"
}'const response = await fetch("https://api.96astro.com/v1/western/western-sun-sign-match", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"sign_a": "Leo",
"sign_b": "Aquarius"
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.westernSunSignMatch({
"sign_a": "Leo",
"sign_b": "Aquarius"
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/western-sun-sign-match",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"sign_a": "Leo",
"sign_b": "Aquarius",
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.western_sun_sign_match({
"sign_a": "Leo",
"sign_b": "Aquarius",
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/western-sun-sign-match');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'sign_a' => 'Leo',
'sign_b' => 'Aquarius',
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"sign_a": "Leo",
"sign_b": "Aquarius"
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/western-sun-sign-match", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"sign_a": "Leo",
"sign_b": "Aquarius",
"element_a": "Fire",
"element_b": "Air",
"score": 90,
"maximum": 100,
"verdict": "Highly compatible — Air feeds Fire's enthusiasm with ideas and mental connection",
"summary": "Leo and Aquarius pair fire with air: Highly compatible — Air feeds Fire's enthusiasm with ideas and mental connection. On sun signs alone this scores 90 out of 100. A full synastry reading needs both birth times and places."
},
"meta": {
"request_id": "req_00000000000000000000",
"api_version": "v1",
"credits_used": 0,
"warnings": [],
"language": "en"
}
}Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry Chart
POSTAvailable
https://api.96astro.com/v1/western/synastry-chartBoth people's positions, the aspects between their charts, and a compatibility block with score, Sun and Moon compatibility and a verdict.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
person_a· objectperson_b· objectinter_aspects· array of objectcompatibility· object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-chart \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-chart", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryChart({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-chart",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_chart({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-chart');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-chart", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"person_a": {
"name": "A",
"sun": "Libra",
"moon": "Libra",
"asc": "Aquarius",
"planets": [
{
"planet": "Sun",
"name": "Sun",
"available": true,
"longitude": 204.7272,
"sign": "Libra",
"sign_symbol": "♎",
"degree": "24°43'38\" Libra",
"degree_in_sign": 24.73,
"retrograde": false,
"speed": 0.9932,
"symbol": "☉"
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry Wheel
POSTAvailable
https://api.96astro.com/v1/western/synastry-wheelPerson A's wheel with person B's planets drawn around it, as an SVG drawing, plus the inter-chart aspects and a table of both rings.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON, SVG
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
inner_ring· stringouter_ring· stringhouses_shown· stringinter_aspects· array of objecttable· objectimages· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-wheel \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-wheel", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryWheel({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-wheel",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_wheel({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-wheel');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-wheel", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"inner_ring": "A",
"outer_ring": "B",
"houses_shown": "A",
"inter_aspects": [
{
"person_a_planet": "Pluto",
"person_b_planet": "Uranus",
"aspect": "Sextile",
"symbol": "⚹",
"nature": "Harmonious",
"orb": 0.15,
"meaning": "Person A's Pluto harmoniously supports Person B's Uranus — transformation, power, death, and rebirth sextile with rebellion, innovation, and sudden change."
},
{
"person_a_planet": "Neptune",
"person_b_planet": "Sun",
"aspect": "Sextile",
"symbol": "⚹",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry Aspects
POSTAvailable
https://api.96astro.com/v1/western/synastry-aspectsInter-chart aspects between two people, split into harmonious and challenging, with orb and meaning.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
person_a· stringperson_b· stringtotal_inter_aspects· integerharmonious_aspects· array of objectchallenging_aspects· array of objectall_aspects· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-aspects \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-aspects", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryAspects({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-aspects",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_aspects({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-aspects');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-aspects", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"person_a": "A",
"person_b": "B",
"total_inter_aspects": 58,
"harmonious_aspects": [
{
"person_a_planet": "Pluto",
"person_b_planet": "Uranus",
"aspect": "Sextile",
"symbol": "⚹",
"nature": "Harmonious",
"orb": 0.15,
"meaning": "Person A's Pluto harmoniously supports Person B's Uranus — transformation, power, death, and rebirth sextile with rebellion, innovation, and sudden change."
},
{
"person_a_planet": "Neptune",
"person_b_planet": "Sun",
"aspect": "Sextile",
"symbol": "⚹",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry Predictions
POSTAvailable
https://api.96astro.com/v1/western/synastry-predictionsA compatibility score and verdict with the love, passion, emotional and identity aspects between two charts and their meanings.
- Credits
- 10 credits
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response (JSON); PDF via /v1/jobs/pdf
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
person_a· stringperson_b· stringcompatibility· objectlove_aspects· array of objectpassion_aspects· array of objectemotional_aspects· array of objectidentity_aspects· array of objectnotes· array of string
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-predictions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-predictions", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryPredictions({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-predictions",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_predictions({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-predictions');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-predictions", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"person_a": "A",
"person_b": "B",
"compatibility": {
"score": 68,
"maximum": 100,
"verdict": "Good compatibility with some areas needing conscious effort.",
"sun": {
"sign_a": "Libra",
"sign_b": "Pisces",
"element_a": "Air",
"element_b": "Water",
"reading": "Complex — Air's detachment conflicts with Water's emotional intensity"
},
"moon": {
"sign_a": "Libra",
"sign_b": "Aquarius",
"reading": "Intellectually vibrant — great communication but may lack emotional depth"
},
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry Compatibility Score
POSTAvailable
https://api.96astro.com/v1/western/synastry-compatibilityA synastry compatibility score with Sun and Moon compatibility, aspect counts and a verdict.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
person_a· stringperson_b· stringcompatibility· object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-compatibility \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-compatibility", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryCompatibility({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-compatibility",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_compatibility({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-compatibility');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-compatibility", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"person_a": "A",
"person_b": "B",
"compatibility": {
"available": true,
"score": 68,
"sun_compatibility": "Complex — Air's detachment conflicts with Water's emotional intensity",
"moon_compatibility": "Intellectually vibrant — great communication but may lack emotional depth",
"sun_element_a": "Air",
"sun_element_b": "Water",
"sun_sign_a": "Libra",
"sun_sign_b": "Pisces",
"moon_sign_a": "Libra",
"moon_sign_b": "Aquarius",
"harmonious_aspects": 25,
"challenging_aspects": 18,
"total_inter_aspects": 58,
"verdict": "Good compatibility with some areas needing conscious effort."
}
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry: Career
POSTAvailable
https://api.96astro.com/v1/western/synastry-careerCareer compatibility from synastry: a score and band, a summary and narrative, the significators used and the supportive and testing inter-chart aspects.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
domain· stringdomain_label· stringperson_a· stringperson_b· stringscore· integerband· stringsummary· stringnarrative· stringsignificators· array of stringsupportive_aspects· array of objecttesting_aspects· array of objectcounts· object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-career \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-career", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryCareer({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-career",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_career({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-career');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-career", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"domain": "career",
"domain_label": "Career & shared ambition",
"person_a": "A",
"person_b": "B",
"score": 68,
"band": "Supportive",
"summary": "On how you build, decide and take responsibility together, A and B score 68 out of 100 -- more helpful than not. This reads 11 supportive and 12 testing contacts between the planets that govern this area (Sun, Saturn, Jupiter, Mars, Mercury).",
"narrative": "The strongest support comes from A's Neptune sextile B's Sun (harmonious, orb 0.3 degrees), which eases dreams, illusion, spirituality, and dissolution here. The main friction is A's Jupiter opposition B's Mars (polarizing, orb 0.9 degrees), which strains expansion, wisdom, luck, and growth here. Support and friction are close to balanced here, which usually reads as an area that works well when both of you are attending to it and drifts when neither is.",
"significators": [
"Sun",
"Saturn",
"Jupiter"
],
"supportive_aspects": [
{
"person_a_planet": "Neptune",
"person_b_planet": "Sun",
"aspect": "Sextile",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry: Finance
POSTAvailable
https://api.96astro.com/v1/western/synastry-financeFinance compatibility from synastry: a score and band, a summary and narrative, the significators used and the supportive and testing inter-chart aspects.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
domain· stringdomain_label· stringperson_a· stringperson_b· stringscore· integerband· stringsummary· stringnarrative· stringsignificators· array of stringsupportive_aspects· array of objecttesting_aspects· array of objectcounts· object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-finance \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-finance", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryFinance({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-finance",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_finance({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-finance');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-finance", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"domain": "finance",
"domain_label": "Money & material security",
"person_a": "A",
"person_b": "B",
"score": 66,
"band": "Supportive",
"summary": "On how you value, spend and secure what you share, A and B score 66 out of 100 -- more helpful than not. This reads 14 supportive and 13 testing contacts between the planets that govern this area (Venus, Jupiter, Saturn, Moon, Pluto).",
"narrative": "The strongest support comes from A's Pluto sextile B's Uranus (harmonious, orb 0.1 degrees), which eases transformation, power, death, and rebirth here. The main friction is A's Jupiter opposition B's Mars (polarizing, orb 0.9 degrees), which strains expansion, wisdom, luck, and growth here. Support and friction are close to balanced here, which usually reads as an area that works well when both of you are attending to it and drifts when neither is.",
"significators": [
"Venus",
"Jupiter",
"Saturn"
],
"supportive_aspects": [
{
"person_a_planet": "Pluto",
"person_b_planet": "Uranus",
"aspect": "Sextile",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry: Intimacy
POSTAvailable
https://api.96astro.com/v1/western/synastry-intimacyIntimacy compatibility from synastry: a score and band, a summary and narrative, the significators used and the supportive and testing inter-chart aspects.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
domain· stringdomain_label· stringperson_a· stringperson_b· stringscore· integerband· stringsummary· stringnarrative· stringsignificators· array of stringsupportive_aspects· array of objecttesting_aspects· array of objectcounts· object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-intimacy \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-intimacy", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryIntimacy({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-intimacy",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_intimacy({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-intimacy');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-intimacy", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"domain": "intimacy",
"domain_label": "Attraction & intimacy",
"person_a": "A",
"person_b": "B",
"score": 60,
"band": "Mixed",
"summary": "On desire, physical rapport and the pull between you, A and B score 60 out of 100 -- workable, with genuine friction. This reads 13 supportive and 13 testing contacts between the planets that govern this area (Venus, Mars, Pluto, Moon).",
"narrative": "The strongest support comes from A's Pluto sextile B's Uranus (harmonious, orb 0.1 degrees), which eases transformation, power, death, and rebirth here. The main friction is A's Jupiter opposition B's Mars (polarizing, orb 0.9 degrees), which strains expansion, wisdom, luck, and growth here. Support and friction are close to balanced here, which usually reads as an area that works well when both of you are attending to it and drifts when neither is.",
"significators": [
"Venus",
"Mars",
"Pluto"
],
"supportive_aspects": [
{
"person_a_planet": "Pluto",
"person_b_planet": "Uranus",
"aspect": "Sextile",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry: Spirituality
POSTAvailable
https://api.96astro.com/v1/western/synastry-spiritualitySpirituality compatibility from synastry: a score and band, a summary and narrative, the significators used and the supportive and testing inter-chart aspects.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
domain· stringdomain_label· stringperson_a· stringperson_b· stringscore· integerband· stringsummary· stringnarrative· stringsignificators· array of stringsupportive_aspects· array of objecttesting_aspects· array of objectcounts· object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-spirituality \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-spirituality", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastrySpirituality({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-spirituality",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_spirituality({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-spirituality');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-spirituality", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"domain": "spirituality",
"domain_label": "Meaning & shared belief",
"person_a": "A",
"person_b": "B",
"score": 47,
"band": "Mixed",
"summary": "On faith, growth and the search for meaning together, A and B score 47 out of 100 -- workable, with genuine friction. This reads 7 supportive and 14 testing contacts between the planets that govern this area (Jupiter, Neptune, Uranus, Sun).",
"narrative": "The strongest support comes from A's Pluto sextile B's Uranus (harmonious, orb 0.1 degrees), which eases transformation, power, death, and rebirth here. The main friction is A's Jupiter opposition B's Mars (polarizing, orb 0.9 degrees), which strains expansion, wisdom, luck, and growth here. The testing contacts outweigh the supportive ones, so this area repays being talked about early rather than left to settle itself.",
"significators": [
"Jupiter",
"Neptune",
"Uranus"
],
"supportive_aspects": [
{
"person_a_planet": "Pluto",
"person_b_planet": "Uranus",
"aspect": "Sextile",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry: Emotion
POSTAvailable
https://api.96astro.com/v1/western/synastry-emotionEmotion compatibility from synastry: a score and band, a summary and narrative, the significators used and the supportive and testing inter-chart aspects.
- Credits
- 1 credit
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
domain· stringdomain_label· stringperson_a· stringperson_b· stringscore· integerband· stringsummary· stringnarrative· stringsignificators· array of stringsupportive_aspects· array of objecttesting_aspects· array of objectcounts· object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-emotion \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-emotion", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryEmotion({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-emotion",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_emotion({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-emotion');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-emotion", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"domain": "emotion",
"domain_label": "Emotional life",
"person_a": "A",
"person_b": "B",
"score": 58,
"band": "Mixed",
"summary": "On safety, expression and how feeling is exchanged, A and B score 58 out of 100 -- workable, with genuine friction. This reads 10 supportive and 11 testing contacts between the planets that govern this area (Moon, Venus, Neptune, Mercury).",
"narrative": "The strongest support comes from A's Neptune sextile B's Sun (harmonious, orb 0.3 degrees), which eases dreams, illusion, spirituality, and dissolution here. The main friction is A's Pluto square B's Venus (challenging, orb 1.6 degrees), which strains transformation, power, death, and rebirth here. Support and friction are close to balanced here, which usually reads as an area that works well when both of you are attending to it and drifts when neither is.",
"significators": [
"Moon",
"Venus",
"Neptune"
],
"supportive_aspects": [
{
"person_a_planet": "Neptune",
"person_b_planet": "Sun",
"aspect": "Sextile",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Synastry: Everything
POSTAvailable
https://api.96astro.com/v1/western/synastry-fullCompatibility, all five domain readings ranked (career, finance, intimacy, spirituality, emotion) and the sun-sign match, in one call.
- Credits
- 10 credits
- Input
- Two people's birth details
- Output
- JSON
- Delivery
- Direct response (JSON); PDF via /v1/jobs/pdf
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
person_aobjectRequired | |
person_a.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_a.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_a.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_a.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_a.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_a.ayanamshastringOptional | Default: |
person_a.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_a.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
person_bobjectRequired | |
person_b.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person_b.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person_b.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person_b.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person_b.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person_b.ayanamshastringOptional | Default: |
person_b.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person_b.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
person_a· stringperson_b· stringcompatibility· objectsun_sign_match· objectdomains· array of objectaspect_count· integer
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-full \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-full", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryFull({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-full",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_full({
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-full');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person_a' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'person_b' => [
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person_a": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"person_b": {
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-full", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"person_a": "A",
"person_b": "B",
"compatibility": {
"score": 68,
"maximum": 100,
"verdict": "Good compatibility with some areas needing conscious effort.",
"sun": {
"sign_a": "Libra",
"sign_b": "Pisces",
"element_a": "Air",
"element_b": "Water",
"reading": "Complex — Air's detachment conflicts with Water's emotional intensity"
},
"moon": {
"sign_a": "Libra",
"sign_b": "Aquarius",
"reading": "Intellectually vibrant — great communication but may lack emotional depth"
},
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.
Western Bulk Match
POSTAvailable
https://api.96astro.com/v1/western/synastry-bulkOne person scored against many candidates, paged: score, verdict and aspect counts per candidate; candidates without a birth time are marked approximate.
- Credits
- 3 credits
- Input
- Specific input
- Output
- JSON
- Delivery
- Direct response
- Languages
- English; translated term names with
labels
| Header | Value and description |
|---|---|
AuthorizationRequired | Bearer YOUR_API_KEYYour sandbox (sk_test_...) or live (sk_live_...) key. X-API-Key: <key> is accepted instead. |
Content-TypeRequired | application/jsonThe body is JSON. |
Idempotency-KeyOptional | <unique string>Makes retries safe: a repeated key with the same body replays the stored response and is never charged twice. (1 to 200 characters) |
| Field | Description |
|---|---|
personobjectRequired | |
person.datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
person.timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
person.utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
person.latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
person.longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
person.ayanamshastringOptional | Default: |
person.languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
person.namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
candidatesarray of objectsRequired | Up to 50 candidates. Limits: 1 to 50 items |
candidates[].datetimestringRequired | Local date and time, ISO 8601 without offset, e.g. 1990-10-18T14:30:00 Limits: format local-date-time, pattern ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$ Example: |
candidates[].timezonestring | nullOptional | IANA time zone, e.g. Asia/Kolkata Default: Example: |
candidates[].utc_offsetstring | nullOptional | Fixed offset such as +05:30, if no IANA zone is known Default: |
candidates[].latitudenumberRequired | Limits: minimum -90, maximum 90 Example: |
candidates[].longitudenumberRequired | Limits: minimum -180, maximum 180 Example: |
candidates[].ayanamshastringOptional | Default: |
candidates[].languagestringOptional | Output language (ISO 639-1). Each capability lists the languages it supports. Default: |
candidates[].namestringOptional | Name to print in readings. Default: Limits: at most 120 characters Example: |
labelsstringOptional | Optional. Adds `meta.labels`: translated display names for the identifiers in the answer. `data` is unchanged. Free. Any other code is refused with 422 unsupported_language. Allowed values: asbndeesfrguhiitknkomlmrnenlorpaplptrusitatetrur |
Response · fields in data
Inferred from the example response: a guide to the shape, not a contract.
name· stringcandidates_submitted· integerscored· integerfailed· integererrors· arraypage· integerpage_size· integerpages· integerhas_more· booleanapproximate_rows· integerresults· array of object
Example request
curl -X POST https://api.96astro.com/v1/western/synastry-bulk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"person": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"candidates": [
{
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
]
}'const response = await fetch("https://api.96astro.com/v1/western/synastry-bulk", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"person": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"candidates": [
{
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
]
}),
});
const { data, meta } = await response.json();
console.log(data);import { Astro96Client } from "@96astro/api";
const astro = new Astro96Client({ apiKey: "YOUR_API_KEY" });
const { data, meta } = await astro.western.synastryBulk({
"person": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"candidates": [
{
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
]
});
console.log(data);import requests
response = requests.post(
"https://api.96astro.com/v1/western/synastry-bulk",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"person": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"candidates": [
{
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
],
},
timeout=60,
)
response.raise_for_status()
data = response.json()["data"]
print(data)from astro96_api import Astro96Client
astro = Astro96Client(api_key="YOUR_API_KEY")
res = astro.western.synastry_bulk({
"person": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A",
},
"candidates": [
{
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B",
},
],
})
print(res.data)<?php
$ch = curl_init('https://api.96astro.com/v1/western/synastry-bulk');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'person' => [
'datetime' => '1990-10-18T14:30:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 28.6139,
'longitude' => 77.209,
'name' => 'A',
],
'candidates' => [
[
'datetime' => '1992-03-02T05:47:00',
'timezone' => 'Asia/Kolkata',
'latitude' => 19.0767,
'longitude' => 72.8767,
'name' => 'B',
],
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{
"person": {
"datetime": "1990-10-18T14:30:00",
"timezone": "Asia/Kolkata",
"latitude": 28.6139,
"longitude": 77.209,
"name": "A"
},
"candidates": [
{
"datetime": "1992-03-02T05:47:00",
"timezone": "Asia/Kolkata",
"latitude": 19.0767,
"longitude": 72.8767,
"name": "B"
}
]
}`)
req, err := http.NewRequest("POST", "https://api.96astro.com/v1/western/synastry-bulk", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Example response
{
"data": {
"name": "A",
"candidates_submitted": 1,
"scored": 1,
"failed": 0,
"errors": [],
"page": 1,
"page_size": 1,
"pages": 1,
"has_more": false,
"approximate_rows": 0,
"results": [
{
"index": 0,
"name": "B",
"ok": true,
"score": 68,
"verdict": "Good compatibility with some areas needing conscious effort.",
"sun": "Pisces",
…Captured from the live engine with a sandbox key (so credits_used is 0) and trimmed: long arrays keep their first items.
Error responses
- 400invalid_request
- 401invalid_key, expired_key
- 402payment_required
- 403account_suspended
- 404not_found
- 409idempotency_conflict
- 413payload_too_large
- 422invalid_request, unsupported_language
- 429rate_limited, quota_exhausted, spend_cap_reached, project_budget_exceeded
- 500computation_failed
- 502unavailable
- 503unavailable
- 504deadline_exceeded
Errors are never charged. What each status means and what to do: errors.