Synastry API
Relationship compatibility analysis API
Calculate complete synastry (relationship compatibility) between two natal charts using Western tropical astrology. Analyzes inter-chart aspects between all planets to determine romantic, friendship, and karmic compatibility. Returns compatibility score (0-100), detailed inter-aspects with strength ratings, harmonious vs challenging aspect counts, and relationship dynamics analysis. Perfect for dating apps, matrimonial sites, relationship counseling tools, and astrology compatibility features. Based on professional astrological techniques.
Location first, chart second
The Synastry API needs latitude, longitude, and timezone. Never ask users to type coordinates. Resolve a city with the Location endpoint first, then feed the result into the request. Timezone accepts a decimal offset or an IANA name.
1 Resolve the location
curl "https://roxyapi.com/api/v2/location/search?q=New York" \
-H "X-API-Key: YOUR_KEY"
# -> cities[0]: { latitude, longitude, timezone: "America/New_York" }2 Call the Synastry endpoint
# feed latitude, longitude and timezone from step 1
POST https://roxyapi.com/api/v2/astrology/synastryRequest
POST /api/v2/astrology/synastry
Parameters
| Parameter | Type | Description |
|---|---|---|
| langquery | string enum | Response language (ISO 639-1). Supported: en, tr, de, es, hi, pt, fr, ru. Defaults to en. Languages without translations yet return English. Default en. |
Request body
| Field | Type | Description |
|---|---|---|
| person1* | object | |
| person1.date* | string (date) | Birth date in YYYY-MM-DD format. Determines planetary positions for the specific calendar day. |
| person1.time* | string (time) | Birth time in 24-hour HH:MM:SS format. Determines the Ascendant (rising sign) and house cusps. Use 12:00:00 if unknown. |
| person1.latitude* | number | Birth location latitude in decimal degrees (-90 to 90). Positive = North, negative = South. |
| person1.longitude* | number | Birth location longitude in decimal degrees (-180 to 180). Positive = East, negative = West. |
| person1.timezone* | number or string | Timezone: IANA name (e.g. "America/New_York", "Europe/London") OR decimal hours from UTC (e.g. -5 for EST, 1 for CET). IANA strings are resolved to the DST-correct offset for the given date, so you can pass `cities[0].timezone` from /location/search directly. |
| person1.nodeType | string enum | Lunar node convention. "mean" is the smoothed average node, which always moves retrograde; "true" is the osculating node, which tracks the real perturbed node, oscillates up to about 1.5 degrees either side of the mean on a 173-day cycle, and can briefly turn direct. Neither is more correct and they almost always fall in the same sign. Applies to the North and South Node. True is what most Western software reports (Astrolabe, Cafe Astrology, TimePassages), which is why it is the default here; astro-seek and the Steven Forrest evolutionary school use mean, so pass "mean" to match those. Nothing else in the chart changes, and the two agree on the sign except when the node sits within about 1.8 degrees of a cusp. Defaults to "true". |
| person1.name | string | Optional display name for this person. Included in the response for easy identification. |
| person2* | object | |
| person2.date* | string (date) | Birth date in YYYY-MM-DD format. Determines planetary positions for the specific calendar day. |
| person2.time* | string (time) | Birth time in 24-hour HH:MM:SS format. Determines the Ascendant (rising sign) and house cusps. Use 12:00:00 if unknown. |
| person2.latitude* | number | Birth location latitude in decimal degrees (-90 to 90). Positive = North, negative = South. |
| person2.longitude* | number | Birth location longitude in decimal degrees (-180 to 180). Positive = East, negative = West. |
| person2.timezone* | number or string | Timezone: IANA name (e.g. "America/New_York", "Europe/London") OR decimal hours from UTC (e.g. -5 for EST, 1 for CET). IANA strings are resolved to the DST-correct offset for the given date, so you can pass `cities[0].timezone` from /location/search directly. |
Show all fieldsShow fewer fields
| Field | Type | Description |
|---|---|---|
| person2.nodeType | string enum | Lunar node convention. "mean" is the smoothed average node, which always moves retrograde; "true" is the osculating node, which tracks the real perturbed node, oscillates up to about 1.5 degrees either side of the mean on a 173-day cycle, and can briefly turn direct. Neither is more correct and they almost always fall in the same sign. Applies to the North and South Node. True is what most Western software reports (Astrolabe, Cafe Astrology, TimePassages), which is why it is the default here; astro-seek and the Steven Forrest evolutionary school use mean, so pass "mean" to match those. Nothing else in the chart changes, and the two agree on the sign except when the node sits within about 1.8 degrees of a cusp. Defaults to "true". |
| person2.name | string | Optional display name for this person. Included in the response for easy identification. |
| houseSystem | string enum | House system for both natal charts. Placidus (default), Whole Sign, Equal, or Koch. |
Example request
{
"person1": {
"date": "1990-07-15",
"time": "14:30:00",
"latitude": 40.7128,
"longitude": -74.006,
"timezone": -5
},
"person2": {
"date": "1990-07-15",
"time": "14:30:00",
"latitude": 40.7128,
"longitude": -74.006,
"timezone": -5
}
}Response
Structured JSON with documented fields, covered by 6,991 automated tests per deploy, 1,527 of them gold-standard tests verified against NASA JPL Horizons. Not hallucinated text.
{
"person1": {
"ascendant": {
"sign": "Taurus",
"degree": 15.32
},
"sunSign": "Cancer",
"moonSign": "Pisces",
"planets": [
{
"name": "Sun",
"longitude": 114.52,
"sign": "Cancer",
"degree": 24.52,
"house": 3,
"isRetrograde": false
}
]
},
"person2": {
"ascendant": {
"sign": "Virgo",
"degree": 22.18
},
"sunSign": "Pisces",
"moonSign": "Scorpio",
"planets": [
{
"name": "Sun",
"longitude": 114.52,
"sign": "Cancer",
"degree": 24.52,
"house": 3,
"isRetrograde": false
}
]
},
"compatibilityScore": 78,
"interAspects": [
{
"planet1": "Venus",
"planet2": "Mars",
"type": "TRINE",
"angle": 120,
"orb": 2.5,
"strength": 75,
"interpretation": "harmonious"
}
],
"summary": {
"total": 24,
"harmonious": 12,
"challenging": 8,
"neutral": 4,
"byType": {
"TRINE": 5,
"SEXTILE": 7,
"SQUARE": 6,
"OPPOSITION": 2
}
},
"analysis": {
"overall": "This relationship shows strong compatibility with genuine potential for lasting partnership. Most interactions feel natural and supportive, with a healthy mix of comfort and growth. Where challenges arise, both partners have the tools to work through them constructively.",
"strengths": [
"More harmonious aspects than challenging ones create a supportive foundation.",
"Harmonious Moon aspects indicate emotional understanding and nurturing.",
"Favorable Venus aspects bring affection, appreciation, and romantic chemistry."
],
"challenges": [
"Challenging Sun aspects may create ego conflicts or competing life directions.",
"Challenging Mars aspects may bring tension, arguments, or competing desires."
]
}
}Response fields
| Field | Type | Description |
|---|---|---|
| person1* | object | Person 1 chart highlights: Ascendant, Sun sign, Moon sign, and plotting positions. |
| person1.name | string | Display name if provided in the request. |
| person1.ascendant* | object | Ascendant position for person 1. Determines first house cusp and outward personality. |
| person1.ascendant.sign* | string | Ascendant (rising sign) of this person. Always English, whatever the lang parameter says. Use signLocalized for anything a reader sees. |
| person1.ascendant.signLocalized | string | Ascendant sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person1.ascendant.degree* | number | Degree within the Ascendant sign (0-29.999). |
| person1.sunSign* | string | Sun sign (zodiac sign) of this person. Core identity and ego expression. Always English, whatever the lang parameter says. Use sunSignLocalized for anything a reader sees. |
| person1.sunSignLocalized | string | Sun sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person1.moonSign* | string | Moon sign of this person. Emotional nature and inner needs. Always English, whatever the lang parameter says. Use moonSignLocalized for anything a reader sees. |
| person1.moonSignLocalized | string | Moon sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person1.planets* | array of object | Planet positions for person 1, enough to render this side of a dual wheel without a second request. Per-planet interpretations are not repeated here; call the natal chart endpoint for an individual reading. |
| person1.planets[].name* | string | Planet or point name. Matches the names used in interAspects. Always English, whatever the lang parameter says. Use nameLocalized for anything a reader sees. |
| person1.planets[].nameLocalized | string | Planet or point name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person1.planets[].longitude* | number | Ecliptic longitude in degrees (0-360) measured from 0 Aries. This is the value a wheel plots. |
Show all fieldsShow fewer fields
| Field | Type | Description |
|---|---|---|
| person1.planets[].sign* | string | Zodiac sign containing the planet. Always English, whatever the lang parameter says. Use signLocalized for anything a reader sees. |
| person1.planets[].signLocalized | string | Zodiac sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person1.planets[].degree* | number | Degree within the sign (0-29.999). |
| person1.planets[].house* | number | House this planet occupies in the person 1 chart (1-12). |
| person1.planets[].isRetrograde* | boolean | True when the planet is retrograde at this moment. |
| person2* | object | Person 2 chart highlights: Ascendant, Sun sign, Moon sign, and plotting positions. |
| person2.name | string | Display name if provided in the request. |
| person2.ascendant* | object | Ascendant position for person 2. Determines first house cusp and outward personality. |
| person2.ascendant.sign* | string | Ascendant (rising sign) of this person. Always English, whatever the lang parameter says. Use signLocalized for anything a reader sees. |
| person2.ascendant.signLocalized | string | Ascendant sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person2.ascendant.degree* | number | Degree within the Ascendant sign (0-29.999). |
| person2.sunSign* | string | Sun sign (zodiac sign) of this person. Core identity and ego expression. Always English, whatever the lang parameter says. Use sunSignLocalized for anything a reader sees. |
| person2.sunSignLocalized | string | Sun sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person2.moonSign* | string | Moon sign of this person. Emotional nature and inner needs. Always English, whatever the lang parameter says. Use moonSignLocalized for anything a reader sees. |
| person2.moonSignLocalized | string | Moon sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person2.planets* | array of object | Planet positions for person 2, enough to render this side of a dual wheel without a second request. Per-planet interpretations are not repeated here; call the natal chart endpoint for an individual reading. |
| person2.planets[].name* | string | Planet or point name. Matches the names used in interAspects. Always English, whatever the lang parameter says. Use nameLocalized for anything a reader sees. |
| person2.planets[].nameLocalized | string | Planet or point name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person2.planets[].longitude* | number | Ecliptic longitude in degrees (0-360) measured from 0 Aries. This is the value a wheel plots. |
| person2.planets[].sign* | string | Zodiac sign containing the planet. Always English, whatever the lang parameter says. Use signLocalized for anything a reader sees. |
| person2.planets[].signLocalized | string | Zodiac sign name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| person2.planets[].degree* | number | Degree within the sign (0-29.999). |
| person2.planets[].house* | number | House this planet occupies in the person 2 chart (1-12). |
| person2.planets[].isRetrograde* | boolean | True when the planet is retrograde at this moment. |
| compatibilityScore* | number | Overall compatibility score (0-100). Calculated from the balance of harmonious vs challenging inter-chart aspects weighted by planet importance. |
| interAspects* | array of object | All inter-chart (synastry) aspects between person 1 and person 2 planets. Each aspect reveals a specific dynamic in the relationship. |
| interAspects[].planet1* | string | Planet from person 1 chart. Always English, whatever the lang parameter says. Use planet1Localized for anything a reader sees. |
| interAspects[].planet1Localized | string | Person 1 planet name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| interAspects[].planet2* | string | Planet from person 2 chart. Always English, whatever the lang parameter says. Use planet2Localized for anything a reader sees. |
| interAspects[].planet2Localized | string | Person 2 planet name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| interAspects[].type* | string | Aspect type (CONJUNCTION, OPPOSITION, TRINE, SQUARE, SEXTILE, etc.). Always English, whatever the lang parameter says. Use typeLocalized for anything a reader sees. |
| interAspects[].typeLocalized | string | Aspect type name in the requested language, for display only. Present only when lang is set to a language other than English, since in English it would repeat its canonical partner field exactly. Never compare against this value, compare against the canonical field beside it. |
| interAspects[].angle* | number | Exact angle of this aspect type in degrees. |
| interAspects[].orb* | number | Distance from exact aspect in degrees. Tighter orb means stronger influence. |
| interAspects[].strength* | number | Aspect strength percentage (0-100) based on orb tightness. |
| interAspects[].interpretation* | string | Aspect nature: harmonious, challenging, or neutral. |
| interAspects[].meaning | object | Aspect meaning with relationship-specific context for this planet pair. |
| interAspects[].meaning.name* | string | Aspect display name. |
| interAspects[].meaning.description* | object | Aspect meaning in short and long form. |
| interAspects[].meaning.description.short* | string | Brief aspect description. |
| interAspects[].meaning.description.long* | string | Detailed aspect description. |
| interAspects[].meaning.keywords* | array of string | Keywords associated with this aspect type. |
| interAspects[].meaning.nature* | string | How this aspect type is characterised in its reference card, in the requested language, exactly like the name, description and keywords beside it. Branch on the aspect-level interpretation field instead, which is always English. |
| interAspects[].meaning.relationshipContext* | string | How this specific planetary pair aspect manifests in relationships. |
| summary* | object | Synastry aspect summary showing the balance of harmonious vs challenging inter-chart connections. |
| summary.total* | number | Total number of inter-chart aspects found. |
| summary.harmonious* | number | Count of harmonious aspects (trine, sextile). Natural ease and flow. |
| summary.challenging* | number | Count of challenging aspects (square, opposition). Dynamic tension and growth. |
| summary.neutral* | number | Count of neutral aspects (conjunction). Outcome depends on planets involved. |
| summary.byType* | object | Aspect count grouped by type. Shows which aspect patterns dominate the relationship. |
| analysis* | object | Relationship analysis with strengths, challenges, and overall assessment. |
| analysis.overall* | string | Overall relationship analysis narrative based on aspect patterns. |
| analysis.strengths* | array of string | Areas where the relationship naturally thrives based on harmonious aspects. |
| analysis.challenges* | array of string | Potential friction points and growth opportunities from challenging aspects. |
Supported options
lang
houseSystem
Call it in your language in seconds.
Every snippet is generated from the live OpenAPI spec, so method names, parameters, and fields always match production.
import { createRoxy } from '@roxyapi/sdk'
const roxy = createRoxy(process.env.ROXY_API_KEY!)
const { data } = await roxy.astrology.calculateSynastry({ body: { person1: { date: '1990-07-15', time: '14:30:00', latitude: 40.7128, longitude: -74.006, timezone: -5 }, person2: { date: '1990-07-15', time: '14:30:00', latitude: 40.7128, longitude: -74.006, timezone: -5 } } })from roxy_sdk import create_roxy
roxy = create_roxy("YOUR_API_KEY")
result = roxy.astrology.calculate_synastry(person1={'date': '1990-07-15', 'time': '14:30:00', 'latitude': 40.7128, 'longitude': -74.006, 'timezone': -5}, person2={'date': '1990-07-15', 'time': '14:30:00', 'latitude': 40.7128, 'longitude': -74.006, 'timezone': -5})use function RoxyAPI\Sdk\createRoxy;
$roxy = createRoxy(getenv('ROXY_API_KEY'));
$result = $roxy->astrology->calculateSynastry(person1: ['date' => '1990-07-15', 'time' => '14:30:00', 'latitude' => 40.7128, 'longitude' => -74.006, 'timezone' => -5], person2: ['date' => '1990-07-15', 'time' => '14:30:00', 'latitude' => 40.7128, 'longitude' => -74.006, 'timezone' => -5]);using RoxyApi;
var roxy = new RoxyClient(Environment.GetEnvironmentVariable("ROXY_API_KEY")!);
var result = await roxy.Astrology.Synastry.PostAsync(new() { /* request fields above */ });import roxyapi "github.com/RoxyAPI/sdk-go"
roxy, _ := roxyapi.NewRoxy(os.Getenv("ROXY_API_KEY"))
resp, _ := roxy.Astrology.CalculateSynastry(ctx, nil, roxyapi.CalculateSynastryJSONRequestBody{ /* request fields above */ })curl -X POST "https://roxyapi.com/api/v2/astrology/synastry" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"person1":{"date":"1990-07-15","time":"14:30:00","latitude":40.7128,"longitude":-74.006,"timezone":-5},"person2":{"date":"1990-07-15","time":"14:30:00","latitude":40.7128,"longitude":-74.006,"timezone":-5}}'Prefer to try before you write code? Run this Western Astrology endpoint live in the API playground and inspect a real production response.
More Synastry endpoints
The Synastry API bundles these related endpoints under one key.
Compatibility Score. Relationship compatibility analysis with category breakdown
Calculate a detailed compatibility score between two birth charts using Western synastry (inter-chart aspects). Returns overall score (0-100) plus category breakdowns for romantic, emotional, intellectual, physical, and spiritual compatibility. Each category analyzes specific planetary pairs: Venus-Mars for romance, Moon-Moon for emotions, Mercury-Mercury for intellect. Includes Sun, Moon, Venus, and Mars sign compatibility narratives, element balance analysis, relationship archetype classification, and the most significant inter-chart aspects with relationship-specific interpretations.
Try it liveRemote MCP for AI agents
Every Western Astrology endpoint is a callable tool on the Remote MCP server over Streamable HTTP. No local setup, no Docker. Claude, ChatGPT, Cursor, and any MCP client auto-discover the tools and ground their answers in verified data.
claude mcp add --transport http \
roxy-astrology https://roxyapi.com/mcp/astrology \
--header "X-API-Key: YOUR_KEY"Tool name for POST /astrology/synastry: post_astrology_synastry. Full MCP setup guide
What you can build
Launch natal chart apps with professional-grade accuracy: birth charts, planet positions, house placements, aspects, and element analysis ready for your UI in days
Add zodiac compatibility scoring to dating apps: synastry analysis, composite charts, and compatibility scores with detailed relationship dynamics
Ship personalized horoscope platforms: publisher-grade daily, weekly, and monthly forecasts with unique content per sign, active transit metadata, Moon phase data, and date scheduling for editorial pre-publishing
Build AI astrology chatbots with MCP: your OpenAI, Claude, or Gemini agent auto-discovers and calls every astrology endpoint with zero integration code
Power wellness and lifestyle apps with real-time transits, moon phase calendars, solar returns, and planetary movement alerts for self-discovery features
Create astrology content engines: automated zodiac content with house-based uniqueness per sign, horoscope newsletters with real lunar event dates, transit alerts, and seasonal forecasts at scale
Drop-in UI components & widgets
Render Synastry API responses without building charts yourself. Install the npm package and drop these into Next.js, React, Vue, Svelte, Angular, or plain HTML, or embed the very same component on Squarespace, Wix, or WordPress by pasting one snippet, with no backend and no build step. They belong to one library that covers the entire spiritual stack rather than astrology alone, MIT licensed and included in every plan at no extra cost, never a separate product and never an upsell. The Synastry API calculations, the interface that renders them, and the Remote MCP your agent calls, all behind one key, end to end.
Compatibility card widget snippet
The complete UI libraryExplore Roxy UIShow all Synastry UI componentsShow fewer Synastry UI components
| Element | Renders |
|---|---|
| <roxy-synastry-chart> | Dual-wheel synastry with inter-aspects table |
| <roxy-compatibility-card> | Score card with category breakdown |
Related capabilities
Synastry API FAQ
What does the Synastry API return?
Calculate complete synastry (relationship compatibility) between two natal charts using Western tropical astrology. Every response is structured JSON with documented fields, not free text, so you map it straight into your product.
How do I authenticate with the Synastry API?
Pass your key in the X-API-Key header on every request. Keys are delivered instantly at checkout with no approval queue. Use a secret sk key server side, or mint a publishable pk key locked to your origins for browser and no-code use.
Does the Synastry API support multiple languages?
Yes. Append the lang query parameter to any endpoint for responses in English, German, Spanish, French, Hindi, Portuguese, Russian and Turkish. The translated payload includes the full interpretation text, not just field labels.
Do I need coordinates to call the Synastry API?
No. Call GET /location/search with a city name first, then pass latitude, longitude, and timezone from the first result into the request. Never ask users to type coordinates. Timezone accepts a decimal offset or an IANA name.
Is the Synastry API available over Remote MCP for AI agents?
Yes. Every endpoint is exposed as a callable tool on the Remote MCP server at https://roxyapi.com/mcp/astrology over Streamable HTTP, so Claude, ChatGPT, Cursor, and any MCP client auto-discover it with no local setup or Docker.
How is the Synastry API billed?
Flat pricing: 1 request equals 1 quota unit, REST and MCP identical, with no credit weighting or per-token markup. Every plan includes all 12 domains, so the Synastry API is included at no extra cost.
What lang values does the Synastry API accept?
The lang parameter accepts en, tr, de, es, hi, pt, fr, ru. Case-insensitive where it is a path value.
Start using Synastry API today.
Ship your astrology app this weekend. Not this quarter.
All 12 domains included with every plan. Every endpoint, MCP server, SDK, and starters.
Plans from $39/mo, starting at $2.70 per domain on annual billing. No credit card required for testing.
View Pricing & Get API Key
