Foundations10 MIN READ13 / 43

Data examples

The lessons explain the ideas; these sketches explore how to carry them in data. Read a record as a set of related facts, then connect its fields back to the sky, chart or time technique that gives them meaning.

These JSON blocks are illustrative sketches, not generated schemas or the implemented API contract. For actual requests and supported values, consult the adapter contract. References such as birth-data.json name conceptual shapes, not files included here.

Data shape — birth data

A person may remember a local clock time and a place name. A calculation needs an instant and coordinates. This sketch keeps both: the resolved UTC instant and the original local time and timezone, so the entered information can be understood later.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.app/schemas/birth-data.json",
  "title": "BirthData",
  "type": "object",
  "required": ["instant", "location"],
  "properties": {
    "instant": { "type": "string", "format": "date-time", "description": "UTC" },
    "localTime": { "type": "string", "description": "Wall clock as entered" },
    "tz": { "type": "string", "description": "IANA zone, e.g. Asia/Kolkata" },
    "location": { "$ref": "#/$defs/GeoPoint" },
    "julianDay": { "type": "number", "description": "Derived Julian date; declare its time scale separately" },
    "uncertaintyMinutes": { "type": "integer", "minimum": 0, "default": 0 }
  },
  "$defs": {
    "GeoPoint": {
      "type": "object",
      "required": ["lat", "lon"],
      "properties": {
        "lat": { "type": "number", "minimum": -90, "maximum": 90 },
        "lon": { "type": "number", "minimum": -180, "maximum": 180 },
        "elevationM": { "type": "number", "default": 0 },
        "placeName": { "type": "string" }
      }
    }
  }
}

The fields tell a small story. instant is the resolved reference; localTime and tz preserve how it was entered. elevationM matters for topocentric and sunrise-related work. julianDay is derived from the instant under a declared time scale, rather than becoming a second independent source of time.

uncertaintyMinutes represents an interval around the stated birth time. If that interval straddles a house or nakshatra boundary, the resulting placement can be uncertain too. A precise-looking output should not erase uncertain input.

Data shape — zodiac configuration

The same sky direction can receive different longitudes in different zodiacs. The mode identifies the frame, while the ayanamsa identifies the offset used for a sidereal result. Keeping these beside the positions makes the labels explainable.

{
  "$id": "https://example.app/schemas/zodiac.json",
  "title": "ZodiacConfig",
  "type": "object",
  "required": ["mode"],
  "properties": {
    "mode": { "enum": ["tropical", "sidereal"] },
    "ayanamsa": {
      "type": "object",
      "required": ["id", "degrees"],
      "properties": {
        "id": {
          "enum": ["lahiri", "raman", "krishnamurti", "fagan_bradley",
                   "yukteshwar", "true_chitra", "custom"]
        },
        "degrees": { "type": "number", "minimum": 0, "maximum": 30 },
        "computedAt": { "type": "string", "format": "date-time" }
      }
    }
  },
  "allOf": [
    {
      "if": { "properties": { "mode": { "const": "sidereal" } } },
      "then": { "required": ["ayanamsa"] }
    }
  ]
}

The conditional at the end ties the choices together: a sidereal mode requires ayanamsa information. The identifier names the convention, the degrees give its value, and the date establishes when that value applies.

A saved offset alone cannot stand for every date. Ayanamsa changes with time; keep its convention and relevant epoch when reproducing a calculation.

Data shape — house frame

A house frame carries both the cusp list and the chart angles. Those belong in separate fields because, as the house lesson shows, an angle is not always a house boundary.

{
  "$id": "https://example.app/schemas/house-frame.json",
  "title": "HouseFrame",
  "type": "object",
  "required": ["system", "cusps", "angles"],
  "properties": {
    "system": {
      "enum": ["placidus", "whole_sign", "equal", "koch", "porphyry",
               "regiomontanus", "campanus", "meridian", "morinus",
               "alcabitius", "polich_page", "krishnamurti", "gauquelin",
               "azimuthal", "pullen_sd"]
    },
    "cusps": {
      "type": "array", "minItems": 12, "maxItems": 12,
      "items": { "type": "number", "minimum": 0, "exclusiveMaximum": 360 },
      "description": "Index 0 = 1st house cusp"
    },
    "angles": {
      "type": "object",
      "required": ["asc", "mc"],
      "properties": {
        "asc": { "type": "number" },
        "mc":  { "type": "number" },
        "dsc": { "type": "number" },
        "ic":  { "type": "number" }
      }
    }
  }
}

The first cusp occupies array index 0; the last occupies index 11. A longitude-based placement compares a body with the intervals between these ordered boundaries, remembering the wrap through zero. Some spatial methods also use the body’s latitude.

The system should name the method that actually produced the result. If a polar calculation falls back to another method, keep that change visible rather than returning substituted cusps under the requested system’s name.

Data shape — body position

Start with what the engine supplies: longitude, latitude and speed. Then add the labels derived from them, such as sign and retrograde state. This makes the relationship between geometry and chart meaning visible in one record.

{
  "$id": "https://example.app/schemas/body-position.json",
  "title": "BodyPosition",
  "type": "object",
  "required": ["body", "lon", "lat", "speed"],
  "properties": {
    "body": { "type": "string", "description": "Canonical id: sun, moon, mars, rahu, chiron, ceres…" },
    "lon": { "type": "number", "minimum": 0, "exclusiveMaximum": 360 },
    "lat": { "type": "number", "minimum": -90, "maximum": 90 },
    "distanceAu": { "type": "number" },
    "speed": { "type": "number", "description": "deg/day; negative = retrograde" },
    "retrograde": { "type": "boolean" },
    "stationary": { "enum": ["none", "station_retrograde", "station_direct"] },
    "sign": { "type": "string" },
    "signDegree": { "type": "number", "minimum": 0, "exclusiveMaximum": 30 },
    "house": { "type": "integer", "minimum": 1, "maximum": 12 },
    "dignity": {
      "type": "object",
      "properties": {
        "ruler": { "type": "boolean" },
        "exalted": { "type": "boolean" },
        "detriment": { "type": "boolean" },
        "fall": { "type": "boolean" }
      }
    }
  }
}

A negative longitude speed indicates retrograde motion in this coordinate convention. The sign and sign-degree follow from the longitude and chosen zodiac; the house additionally needs its frame. Dignity adds a traditional lookup against the selected rule tables.

Mean node, true node, mean Lilith and osculating Lilith identify different models. Their identifiers should preserve that choice. An unqualified label makes later comparisons unnecessarily ambiguous.

The optional station field would also need a policy for what counts as being near a station. An exact turning time is normally found through an event search.

Data shape — aspect

A pair may be separated by 118° while being classified as a 120° trine. The record therefore keeps the target angle, actual separation, orb distance and maximum permitted orb as distinct quantities.

{
  "$id": "https://example.app/schemas/aspect.json",
  "title": "Aspect",
  "type": "object",
  "required": ["from", "to", "type", "angle", "orb"],
  "properties": {
    "from": { "type": "string" },
    "to": { "type": "string" },
    "type": {
      "enum": ["conjunction", "sextile", "square", "trine", "opposition",
               "semi_sextile", "semi_square", "sesquiquadrate", "quincunx",
               "quintile", "biquintile", "parallel", "contra_parallel"]
    },
    "angle": { "type": "number", "description": "Exact angle of the aspect" },
    "exactAngle": { "type": "number", "description": "Actual separation" },
    "orb": { "type": "number", "description": "Absolute distance from the target angle; degrees" },
    "maxOrb": { "type": "number" },
    "applying": { "type": "boolean" },
    "drishti": { "type": "boolean", "default": false },
    "pattern": { "type": ["string", "null"] }
  }
}

The field name exactAngle in this teaching sketch means the measured separation, while angle means the named aspect’s target. The descriptions matter more than the apparent precision of the names. Declination parallels need their own coordinate context rather than being treated as longitude angles.

Data shape — chart request and chart

Different chart techniques reuse birth information but ask for different comparisons. A transit adds a target instant; synastry adds another person; a harmonic chart adds a multiplier. kind identifies the technique that gives those other fields their role.

{
  "$id": "https://example.app/schemas/chart.json",
  "title": "ChartRequest",
  "type": "object",
  "required": ["kind", "subject", "zodiac", "houseSystem"],
  "properties": {
    "kind": {
      "enum": ["natal", "transit", "secondary_progression", "solar_arc",
               "tertiary_progression", "minor_progression", "solar_return",
               "lunar_return", "lunar_phase_return", "planetary_return",
               "synastry", "composite", "davison", "relocation",
               "horary", "electional", "harmonic", "antiscia", "eclipse"]
    },
    "subject": { "$ref": "birth-data.json" },
    "partner": { "$ref": "birth-data.json" },
    "target": { "$ref": "birth-data.json", "description": "Transit/election instant" },
    "zodiac": { "$ref": "zodiac.json" },
    "houseSystem": { "type": "string", "default": "placidus" },
    "harmonic": { "type": "integer", "minimum": 2 },
    "options": {
      "type": "object",
      "properties": {
        "bodies": { "type": "array", "items": { "type": "string" } },
        "aspects": { "type": "array", "items": { "type": "string" } },
        "orbs": { "type": "object", "additionalProperties": { "type": "number" } },
        "includeFixedStars": { "type": "boolean", "default": false }
      }
    }
  }
}

A result can keep its inputs alongside bodies, houses, aspects and meta. That lets a reader trace a displayed chart back to the selected technique, settings and calculation evidence. The sketch shows possible fields; a complete API would also validate which combinations belong to each chart kind.

Data shape — Vedic outputs

A divisional placement, a period tree and a daily calendar answer different questions. This sketch groups them under vargas, dashas and panchang while leaving their structures distinct.

{
  "$id": "https://example.app/schemas/vedic.json",
  "title": "VedicSnapshot",
  "type": "object",
  "required": ["vargas", "dashas", "panchang"],
  "properties": {
    "vargas": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["division", "positions"],
        "properties": {
          "division": { "type": "integer", "enum": [1,2,3,4,7,9,10,12,16,20,24,27,30,40,45,60] },
          "name": { "type": "string" },
          "ascSign": { "type": "string" },
          "positions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "body": { "type": "string" },
                "sign": { "type": "string" },
                "degree": { "type": "number" }
              }
            }
          }
        }
      }
    },
    "dashas": {
      "type": "object",
      "required": ["system", "tree"],
      "properties": {
        "system": { "enum": ["vimshottari", "ashtottari", "yogini", "kalachakra", "chara"] },
        "tree": { "$ref": "#/$defs/DashaNode" }
      }
    },
    "panchang": {
      "type": "object",
      "required": ["tithi", "nakshatra", "yoga", "karana", "vara"],
      "properties": {
        "tithi": { "type": "string" },
        "nakshatra": { "type": "string" },
        "yoga": { "type": "string" },
        "karana": { "type": "string" },
        "vara": { "type": "string" },
        "sunrise": { "type": "string", "format": "date-time" },
        "sunset": { "type": "string", "format": "date-time" },
        "rahukalam": { "type": "object" }
      }
    }
  },
  "$defs": {
    "DashaNode": {
      "type": "object",
      "required": ["lord", "level", "start", "end"],
      "properties": {
        "lord": { "type": "string" },
        "level": { "enum": ["maha", "antar", "pratyantar", "sookshma", "prana"] },
        "start": { "type": "string", "format": "date-time" },
        "end": { "type": "string", "format": "date-time" },
        "children": { "type": "array", "items": { "$ref": "#/$defs/DashaNode" } }
      }
    }
  }
}

A dasha node can contain its own subperiods, which is why the example uses a recursive DashaNode. Panchang fields name the conditions, while sunrise provides part of their local-day context.

A daily panchang can contain changes of tithi, nakshatra, yoga or karana. A single snapshot needs a stated instant; a full-day account also needs boundary times. The small shape here is not a complete daily almanac.

Data shape — render options

Once the chart exists, render options choose its presentation: output format, wheel style, size, theme and visible layers. Hiding a line changes the drawing; it does not remove the underlying angular relationship.

{
  "$id": "https://example.app/schemas/render.json",
  "title": "RenderOptions",
  "type": "object",
  "properties": {
    "format": { "enum": ["svg", "png", "pdf"], "default": "svg" },
    "wheelStyle": { "enum": ["western", "vedic_north", "vedic_south", "grid"] },
    "sizePx": { "type": "integer", "minimum": 200, "maximum": 4000, "default": 800 },
    "theme": { "enum": ["light", "dark", "print"], "default": "light" },
    "show": {
      "type": "object",
      "properties": {
        "signs": { "type": "boolean", "default": true },
        "houses": { "type": "boolean", "default": true },
        "degrees": { "type": "boolean", "default": true },
        "aspects": { "type": "boolean", "default": true },
        "minorAspects": { "type": "boolean", "default": false },
        "fixedStars": { "type": "boolean", "default": false }
      }
    },
    "language": { "type": "string", "default": "en" }
  }
}

Keep presentation choices separate from calculation settings. Changing a colour or image size should not silently change the zodiac, house system or aspect tolerance used to produce the chart.

The canonical payload

Here the separate pieces meet: inputs establish the context, houses and bodies carry positions, aspects connect pairs, and the Vedic section groups its own derived outputs. Read it from the request outward to see how the ideas fit together.

This is a synthetic teaching example, not a verified chart for the listed birth data or the implemented API contract. The values illustrate the shape of a result and should not be reused as an astronomical test case.

{
  "meta": {
    "engine": "swiss-ephemeris",
    "engineVersion": "2.10.03",
    "computedAt": "2026-10-24T08:00:00Z"
  },
  "request": {
    "kind": "natal",
    "subject": {
      "instant": "1994-08-17T04:35:00Z",
      "tz": "Asia/Kolkata",
      "location": { "lat": 22.5726, "lon": 88.3639, "placeName": "Kolkata" }
    },
    "zodiac": {
      "mode": "sidereal",
      "ayanamsa": { "id": "lahiri", "degrees": 23.86 }
    },
    "houseSystem": "whole_sign"
  },
  "houses": {
    "system": "whole_sign",
    "cusps": [150.0, 180.0, 210.0, 240.0, 270.0, 300.0,
              330.0, 0.0, 30.0, 60.0, 90.0, 120.0],
    "angles": { "asc": 150.0, "mc": 60.0 }
  },
  "bodies": [
    {
      "body": "sun", "lon": 133.42, "lat": 0.0, "speed": 0.96,
      "retrograde": false, "sign": "leo", "signDegree": 13.42, "house": 12
    },
    {
      "body": "moon", "lon": 13.33, "lat": 4.1, "speed": 13.2,
      "retrograde": false, "sign": "aries", "signDegree": 13.33, "house": 8
    }
  ],
  "aspects": [
    {
      "from": "sun", "to": "moon", "type": "trine",
      "angle": 120, "exactAngle": 120.09, "orb": 0.09,
      "maxOrb": 8, "applying": false
    }
  ],
  "vedic": {
    "vargas": [{ "division": 1, "name": "rasi", "ascSign": "virgo", "positions": [] }],
    "dashas": {
      "system": "vimshottari",
      "tree": {
        "lord": "venus", "level": "maha",
        "start": "1994-08-17T04:35:00Z", "end": "2014-08-17T04:35:00Z"
      }
    },
    "panchang": {
      "tithi": "shukla ekadashi",
      "nakshatra": "bharani",
      "yoga": "vishkambha",
      "karana": "vanija",
      "vara": "wednesday"
    }
  }
}

The common thread is context. A longitude becomes readable with its zodiac, a house with its system, and a timeline with its period rules. Carrying those choices together lets another reader understand how the result was produced.


Guide index · A–Z lookup · Sources · Next: A–Z lookup