Справочник Astro API

REST API поверх расчётного ядра астрологии (движок Swiss Ephemeris, полная точность .se1, встроенный — без файлов данных во время выполнения). Все расчёты геоцентрические; позиции — эклиптические долготы в градусах. Тот же самый вычислительный код также работает на стороне клиента как модуль WebAssembly (см. ../README.md); этот документ описывает HTTP-поверхность, которую браузер использует как запасной вариант, пока не загрузится движок WASM, и для поиска городов.

Адрес сервера: https://astro.yuretz.ru — рабочее развёртывание; каждый пример на этой странице обращается непосредственно к нему и может быть запущен как есть.

Самостоятельно размещённая документация

Работающий сервер отдаёт собственную документацию (внешние инструменты не нужны):

URLЧто это
/docsЭтот справочник, отрендеренный в HTML
/docs/swaggerИнтерактивный обозреватель API + try-it — полностью самодостаточный (без CDN/внешних запросов)
/openapi.yamlСпецификация OpenAPI 3.1 (машиночитаемая)
/openapi.jsonТа же спецификация в формате JSON
/docs/api.mdЭтот файл, необработанный Markdown

Спецификация OpenAPI (../openapi.yaml) охватывает каждую конечную точку ниже и поддерживается в синхронизации с этим документом.

Соглашения

Орбы

Орбы аспектов (по каждому аспекту, по каждому телу, по каждому типу карты) и как их переопределять имеют собственную страницу: Орбы. Коротко: сетка aspects по умолчанию использует орбы по каждому аспекту (☌☍ 8°, △□ 7°, ✶ 5°, ⚻ 3°); отправьте orbs для классического метода полусумм орбов (moiety) по каждому телу, wide_aspects для интерпретационных орбов, minor_aspects для гармонических минорных.

Ошибки

Доменные ошибки (некорректный ввод, сбой эфемерид/движка) возвращают JSON-конверт:

{ "error": "houses undefined at latitude 89.9000: engine reported houses undefined" }
HTTP-статусЗначение
422 Unprocessable EntityНекорректный ввод (например, неразрешимый часовой пояс, значение вне диапазона) или дома не определены для заданной широты (полярные регионы с квадрантной системой домов)
500 Internal Server ErrorДвижок Swiss Ephemeris сообщил о сбое

Некорректно сформированные запросы никогда не достигают доменного слоя и используют собственный формат отклонения axum (тело в виде обычного текста, а не конверт {"error": …}):

HTTP-статусПричинаПример тела
422 Unprocessable EntityТело JSON не соответствует ожидаемой форме (отсутствующее/неверно типизированное поле)Failed to deserialize the JSON body into the target type: missing field datetime_utc at line 1 column 2
400 Bad RequestСтрока запроса не соответствует ожидаемой форме (отсутствующий/неверно типизированный параметр)Failed to deserialize query string: missing field lon``

Неизвестные пути не дают 404: сервер откатывается к отдаче встроенного одностраничного приложения (200 OK, text/html), чтобы работала клиентская маршрутизация/прямые ссылки. Для API-маршрутов тоже нет всеохватного 404 — путь с опечаткой под /v1/... также получает откат к SPA, а не JSON-ошибку.

Общие типы

Используются в запросах и ответах natal/transits/synastry/solar.

GeoLocation

ПолеТипОбязательныйПримечания
latitudenumberдаГрадусы, положительные к северу
longitudenumberдаГрадусы, положительные к востоку
altitudenumberнет (по умолчанию 0)Метры над уровнем моря

house_system (строковый enum, по умолчанию "koch"): koch · placidus · whole_sign · equal · regiomontanus · campanus

zodiac (строковый enum, по умолчанию "tropical"): tropical · sidereal (айанамша Лахири)

objects (массив ключей тел, необязательный — по умолчанию стандартные 12): sun moon mercury venus mars jupiter saturn uranus neptune pluto mean_node true_node mean_lilith true_lilith chiron south_node white_moon selena proserpina. Набор по умолчанию — всё перечисленное выше, кроме true_node, true_lilith, chiron, south_node, white_moon, selena, proserpina (для них нужны явные эфемериды астероидов/фиктивных тел, и они включаются по запросу). mean_lilith — средняя Чёрная Луна; true_lilith — истинная (оскулирующая) Чёрная Луна. south_node вычисляется (противоположен true_node), это не сырое тело движка. Если запрошенное тело не может быть вычислено (например, отсутствует файл эфемерид), оно молча исключается из ответа, а не приводит к сбою всей карты.

ObjectPosition (одна запись на каждое запрошенное тело, в массиве objects каждого ответа с картой):

ПолеТипПримечания
bodystringКлюч тела, как выше
longitudenumberЭклиптическая долгота, градусы [0, 360)
speed_longitudenumberГрадусы/сутки; отрицательное ⇒ ретроградный
signstringariespisces
degrees_in_signnumber[0, 30)
retrogradebooleanВсегда false для sun/moon независимо от знака скорости
dignitystring | omittedЭссенциальное достоинство (западная классика): domicile · exaltation · detriment · fall · peregrine. Только десять планет — исключается для математических точек (узлы/Лилит/жребии) и Хирона
dignity_schoolobject | omittedДостоинство по школе Ананды: { category, score }, category ∈ domicile_major·domicile_minor·exaltation·kinship·neutral·enmity·fall·detriment, score 0–6 (domicile 6 · exaltation 5 · kinship 4 · neutral 3 · enmity 2 · fall 1 · detriment 0). Присутствует для десяти планет, Хирона, Прозерпины и узлов. ⚠️ Одна из нескольких версий школы — см. примечание ниже
term_rulerstringЕгипетский управитель терма (границы) на этом градусе (позиционный; присутствует для всех объектов)
decan_rulerstringХалдейский управитель декана (лица) на этом градусе (позиционный)
speed_classstring | omittedfast / slow (относительно среднего суточного движения тела). Только физические тела — исключается для математических точек
stationaryboolean | omittedВот-вот станет станцией (|speed| менее ~10 % от среднего). Только физические тела — исключается для математических точек
houseinteger | omitted1..12 — присутствует только когда у карты есть дома
dispositorstring | omittedОсновной управитель знака объекта по rulership_scheme из запроса
solar_statusstring | omittedcazimi (<0°17′) · combust (<8.5°) · under_beams (<17°) · free — относительно Солнца. Только десять планет — исключается для математических точек и Хирона
declinationnumber | omittedЭкваториальное склонение, градусы (для параллели/контрпараллели; исключается для производных точек)
unaspectedboolean | omittedНе образует ни одного птолемеевского аспекта (соединение/секстиль/квадрат/трин/оппозиция — квинконс исключён) к другой из десяти планет; присутствует для десяти планет

Поля solar_status (относительно Солнца) и dispositor присутствуют всякий раз, когда набор объектов включает Солнце (то есть для объектов карты и транзитного кольца). Значением body также может быть part_fortune — Жребий Фортуны, вычисляемая точка, добавляемая в objects, когда присутствуют дома (день: Asc + Луна − Солнце; ночь: Asc + Солнце − Луна).

Математические точки против физических тел. Лунные узлы, Лилит, авестийские точки (Белая Луна / Селена / Прозерпина) и жребии (Жребий Фортуны) не имеют физического тела, поэтому их физические атрибуты / атрибуты достоинства исключаются: dignity, solar_status, speed_class, stationary. Остаются только позиционные поля — longitude, sign, degrees_in_sign, house, term_ruler, decan_ruler, dispositor, retrograde. Хирон — реальное тело: у него сохраняются speed_class/stationary; но классическое достоинство/сожжение для него не определены, поэтому dignity/solar_status для Хирона тоже исключаются.

dignity_school предварительно — одна из нескольких версий школы. Оно закодировано из источника «определений» школы (единичные управления + формула тригона: изгнание = напротив управления, kinship = трин к управлению, enmity = напротив kinship). Три документа школы Ананды в настоящее время противоречат друг другу, и это поле следует версии определений в ожидании собственного арбитража школы. Известные междокументные конфликты: (1) ось Овен–Скорпион (Овен→Марс против Овен→Плутон-основной); (2) экзальтации Нептуна и Плутона (Нептун-Водолей/Плутон-Лев против обратного); (3) единичное против двойного управления для высших планет/Хирона (двойное даёт обоим знакам score 6); (4) вторые изгнания светил (Солнце-Козерог и Луна-Водолей с оценкой 1, а не neutral). Не считайте эти ячейки окончательными.

Houses (присутствует в поле houses карты только когда была задана location):

ПолеТипПримечания
systemstringПовторяет запрошенную house_system
cuspsnumber[12]Долготы куспидов домов I … XII, градусы
ascendantnumberГрадусы
midheavennumberГрадусы
descendantnumberГрадусы; = ascendant + 180°
icnumberГрадусы; Imum Coeli = midheaven + 180°
vertexnumber | nullГрадусы, когда доступно
intercepted_signsstring[]Знаки, полностью заключённые внутри дома (без куспида внутри)
house_rulersarrayПо каждому дому: { house, ruler[], co_rulers[], almuten } — управитель(и) знака куспида (массив; 1–2 — двойные обители modern по секте или оси spbaa), управители включённых/занимающих знаков и альмутен градуса куспида

NatalChart также несёт анализ на уровне карты: sign_rulers (управитель(и) каждого из 12 знаков по rulership_scheme из запроса; каждая запись — массив из 1–2 тел — два на двойных обителях modern (по секте) и осях spbaa), sect (diurnal/nocturnal), final_dispositor (уникальная самодиспонирующая планета в современной схеме, иначе null), moon_phase (waxing/waning), moon_void ({ void, start?, until, next_sign_at, via_combusta?, spica_exception? } — Луна не образует больше ни одного мажорного аспекта до выхода из своего знака; start — начало холостого окна (последний точный аспект Луны в знаке, либо вход в знак, если аспектов не было), присутствует только при void: true; via_combusta отмечает Луну в 15° Весов – 15° Скорпиона, а spica_exception — средневековую защиту Луны без курса/поражённой Луны в соединении со Спикой ±1°) и declination_aspects ([{ a, b, kind: parallel|contraparallel, orb }], орб 1°).

Схемы управления (rulership_scheme, по умолчанию modern):

domicile_rulers (необязательно) — своя день/ночь-таблица обителей. Когда передана, переопределяет rulership_scheme для всего низового расчёта: поля dignity, dispositor, sign_rulers/house_rulers, receptions и альмутены считаются по ней. Секта карты выбирает активного управителя (день/ночь-столбец); оба владыки знака считаются обительюdignity и в баллах альмутена). Схемы traditional/spbaa и дефолт движка (без таблицы) остаются классическими. Два формата:

Далее она несёт анализ высшего порядка, весь вычисляемый один раз в astro-core и разделяемый API и веб-клиентом:

POST /v1/charts/transits и /v1/charts/synastry принимают необязательный orb (number): единый максимальный орб для каждого вида аспекта вместо значений по умолчанию для каждого вида (например, 6 для индекса конфликтности Шестопалова). Ответ синастрии также включает a_in_b_houses и b_in_a_houses ([{ body, house }] — планеты каждой карты, помещённые в дома другой) и кросс-контакты планета↔угол a_to_b_angles / b_to_a_angles (AngleAspect[] — тела одной карты к четырём углам другой; пусто без домов соответствующей карты).

Составные эндпоинты (/v1/charts/transits, /synastry, /solar, /return, /progressed) принимают те же параметры проекции ?profile=&fields=&precision=, что и /v1/charts/natal (только в строке запроса, не в теле) — пресет шейпит каждую вложенную карту (natal/transit/a/b/solar/returned/progressed), пропуская и вычисление, и сериализацию отброшенных блоков.

AspectHit (записи в массиве aspects любой карты — natal (внутри карты), transits, synastry, solar):

ПолеТипПримечания
a, bstringКлючи тел двух концов
kindstringconjunction sextile square trine opposition quincunx
anglenumberТочный угол аспекта: 0/60/90/120/150/180
orbnumberОтклонение от точного, градусы (0 = партиль), 2 знака после запятой
applyingbooleantrue = сходящийся (орб сокращается), false = расходящийся (орб растёт), по долготным скоростям обоих тел

Орбы по умолчанию: соединение/оппозиция 8°, трин/квадрат 7°, секстиль 5°, квинконс 3°. Не настраивается через API. Тот же матчер (орбы + правило сходящийся/расходящийся) используется для каждого списка аспектов здесь и кругом веб-клиента (через движок WASM), поэтому они никогда не расходятся.


GET /health

Проба живучести и информация о движке. Без аутентификации, дёшево, без удержания блокировки движка сверх вызова.

200 OK

{
  "status": "ok",
  "service": "astro",
  "engine": "swiss-ephemeris (embedded, in-memory)",
  "precision": "~0.001 arcsec"
}

engine/precision фиксированы для этого развёртывания (данные .se1 и хук swi_fopen в памяти всегда присутствуют — см. swisseph-embedded.md); нет деградированного/запасного режима для сообщения.

curl -s https://astro.yuretz.ru/health

POST /v1/charts/natal

Вычислить натальную карту (радикс): позиции тел плюс, когда задано местоположение, куспиды домов и углы.

Тело запроса (NatalRequest)

ПолеТипОбязательныйПо умолчаниюПримечания
datetime_utcstring (RFC 3339)даМомент рождения в UTC
locationGeoLocation | nullнетnullОпустить → houses исключается из ответа
house_systemstringнетkochСм. enum системы домов выше
zodiacstringнетtropicalСм. enum зодиака выше
objectsstring[]нетстандартные 12См. список ключей тел выше
wide_aspectsbooleanнетfalseТакже выдавать wide_aspects/wide_angle_aspects с конвенциональными орбами (мажоры 6°, светила 8°, квинконс 3°) с зеркалами Dsc/IC; derived отмечает попадание только в расширенной полосе. aspects/angle_aspects по умолчанию не меняются
orbsobjectнетДопуски орбов по каждому телу (классический метод полусумм орбов) для пяти птолемеевых аспектов; квинконс сохраняется со своим фиксированным орбом 3° (не отбрасывается). Присутствует (даже {}) → aspects используют их вместо значений по умолчанию для каждого аспекта; частичное отображение, опущенные тела сохраняют классические значения по умолчанию. Возвращается обратно в поле orbs ответа. См. страницу Орбы
minor_aspectsbooleanнетfalseТакже выдавать minor_aspects — гармонические миноры (полусекстиль, полуквадрат, квинтиль, семейства септиль/новиль, …) на узких орбах
asc_longitudenumberнетКармическая карта (метод Шестопалова): строить дома от этой долготы Асцендента (например, ASC = Восходящий узел) вместо горизонта. Система домов сохраняется — для широты места решается соответствующий ARMC, куспиды Коха/Плацидуса осмысленны. Требует location; только тропический зодиак
profilestringнетrawПресет проекции ответа (см. ниже); ?profile= в запросе имеет приоритет
precisionintegerнетпо умолчанию профиляДесятичное округление для числовых полей
fieldsstringнет+block/-block поверх профиля или голый белый список a,b

Проекция ответа (необязательно)

profile выбирает пресет, который пропускает и вычисление, и сериализацию блоков, которые он отбрасывает — более дешёвый ответ, а не просто отфильтрованный. Пресеты:

ПрофильЧто он возвращает
raw (по умолчанию)Всё; побайтово идентично непроецированному ответу
natal_interpНабор для интерпретации: отбрасывает у каждого объекта speed_longitude/declination, disposition.by_detriment и star_conjunctions/star_positions; округляет до 2 знаков
horaryТолько хорарные основы (дома, объекты, moon_void, planetary_hour, moon_sequence, аспекты, receptions, sign_rulers); 2 знака
calendarТолько позиции + дома; 2 знака

precision переопределяет округление; fields=+a,-b переключает отдельные блоки поверх профиля (голый fields=a,b — явный белый список). Параметры запроса имеют приоритет над теми же ключами в теле. Неизвестный profile даёт 422.

Ответ (NatalChart) — 200 OK

ПолеТипПримечания
datetime_utcstringПовторяет запрос
julian_day_utnumberЮлианский день, всемирное время
zodiacstringПовторяет запрос
objectsObjectPosition[]
aspectsAspectHit[]Аспекты между собственными объектами этой карты (внутри карты)
housesHouses | omittedПрисутствует только если была задана location

Ошибки

Пример

curl -s -X POST https://astro.yuretz.ru/v1/charts/natal \
  -H 'content-type: application/json' \
  -d '{
    "datetime_utc": "1990-05-15T09:20:00Z",
    "location": { "latitude": 55.7558, "longitude": 37.6178 },
    "house_system": "placidus",
    "zodiac": "tropical"
  }'
{
  "datetime_utc": "1990-05-15T09:20:00Z",
  "julian_day_ut": 2448026.888888889,
  "zodiac": "tropical",
  "objects": [
    { "body": "sun", "longitude": 54.288970350752, "speed_longitude": 0.9642565409, "sign": "taurus", "degrees_in_sign": 24.288970350, "retrograde": false },
    { "body": "moon", "longitude": 295.79073022998, "speed_longitude": 12.329011637, "sign": "capricorn", "degrees_in_sign": 25.790730229, "retrograde": false }
  ],
  "houses": {
    "system": "placidus",
    "cusps": [140.5, 168.2, "…"],
    "ascendant": 140.5,
    "midheaven": 45.1,
    "descendant": 320.5,
    "ic": 225.1,
    "vertex": 210.3
  }
}

GET /v1/charts/natal.svg

Натальный круг как отдельное SVG-изображение — та же геометрия, шрифты и глифы, что у веб-клиента — пригодно для непосредственного использования как <img src>. Неподвижные звёзды отрисовываются сразу за зодиакальным кольцом, каждая несёт нативную всплывающую подсказку <title> при наведении (имя + величина); передайте stars=false, чтобы их скрыть. Чтобы избежать загромождения, отрисовываются только астрологически значимые звёзды: постоянные якоря (четыре Королевские звезды + Алголь + Спика) плюс любая звезда в соединении с планетой или углом в этой карте.

Параметры запроса

ПараметрТипОбязательныйПо умолчаниюПримечания
datetime_utcstring (RFC 3339)даМомент рождения в UTC
lat, lonnumberнетОба вместе добавляют дома/углы
house_systemstringнетkochСм. enum системы домов
zodiacstringнетtropical
titlestringнетПодпись, отрисованная под кругом
starsbooleanнетtrueОтрисовать неподвижные звёзды за кольцом
themestringнетlightЦветовая схема: light или dark

Возвращает image/svg+xml (кэшируемо, max-age=3600).

Пример

https://astro.yuretz.ru/v1/charts/natal.svg?datetime_utc=1990-05-15T09:20:00Z&lat=55.7558&lon=37.6178&house_system=placidus
https://astro.yuretz.ru/v1/charts/natal.svg?datetime_utc=1990-05-15T09:20:00Z&lat=55.7558&lon=37.6178&theme=dark

POST /v1/charts/transits

Натальная карта плюс позиции тел на второй момент («транзит»), с меж-аспектами между двумя наборами.

Тело запроса (TransitsRequest)

ПолеТипОбязательныйПримечания
natalNatalRequestдаТа же форма, что тело /v1/charts/natal
transitMomentRequestда{ "datetime_utc": "…", "location": null }location принимается, но не используется для вычисления транзитных домов

Ответ (TransitsChart) — 200 OK

ПолеТипПримечания
natalNatalChartКак возвращается /v1/charts/natal
transitobject{ datetime_utc, julian_day_ut, objects } — та же форма objects, без houses
aspectsAspectHit[]Натал × транзит, все пары, включая совпадение тел (например, транзитное Солнце в соединении с натальным Солнцем)

Ошибки

Те же, что у /v1/charts/natal (ошибка может исходить из любого момента).

Пример

curl -s -X POST https://astro.yuretz.ru/v1/charts/transits \
  -H 'content-type: application/json' \
  -d '{
    "natal": { "datetime_utc": "1990-05-15T09:20:00Z", "location": { "latitude": 55.7558, "longitude": 37.6178 } },
    "transit": { "datetime_utc": "2026-07-02T10:00:00Z" }
  }'

POST /v1/charts/synastry

Две натальные карты (a, b) с меж-аспектами между ними.

Тело запроса (SynastryRequest)

ПолеТипОбязательныйПримечания
aNatalRequestда
bNatalRequestда

Ответ (SynastryChart) — 200 OK

ПолеТипПримечания
aNatalChart
bNatalChart
aspectsAspectHit[]a × b, все пары

Ошибки

Те же, что у /v1/charts/natal (может исходить из любой карты).


POST /v1/charts/solar

Натальная карта плюс соляр на заданный год (момент, когда транзитное Солнце возвращается к своей натальной эклиптической долготе), с меж-аспектами.

Тело запроса (SolarRequest)

ПолеТипОбязательныйПо умолчаниюПримечания
natalNatalRequestда
yearintegerдаКалендарный год возврата, поиск с ~2 дней до 1 января
locationGeoLocation | nullнетlocation наталаМесто, используемое для домов карты возврата

Ответ (SolarChart) — 200 OK

ПолеТипПримечания
natalNatalChart
solarNatalChartКарта возврата — datetime_utc это точный момент возврата
aspectsAspectHit[]Натал × соляр

Ошибки


POST /v1/charts/return

Карта возврата для любого тела: момент, когда оно в следующий раз достигает своей натальной долготы ближайший к around (лунный возврат, возврат Сатурна, возврат узлов — то же нахождение корней, что использует соляр, обобщённое).

Тело запроса (ReturnRequest)

ПолеТипОбязательныйПримечания
natalNatalRequestда
bodystringдаВозвращающееся тело (moon, saturn, mean_node, …)
aroundstring (RFC 3339)даПриблизительная дата; ближайший точный возврат ищется в пределах ±15 % периода тела
locationGeoLocation | nullнетДома карты возврата; по умолчанию как у натала

Ответ — 200 OK

{ natal: NatalChart, returned: NatalChart, aspects: AspectHit[] }returned это полная карта в момент возврата; aspects это натал × returned.

Ошибки


POST /v1/charts/progressed

Вторичные прогрессии (1 день эфемерид = 1 год жизни) или символические дирекции (каждая точка продвигается на фиксированную дугу за год).

Тело запроса (ProgressedRequest)

ПолеТипОбязательныйПо умолчаниюПримечания
natalNatalRequestда
targetstring (RFC 3339)даДата, до которой прогрессировать
methodstringнетsecondarysecondary или symbolic
ratenumberнет1Градусов в год для symbolic (1° = 1 год)

Ответ — 200 OK

{ natal, progressed: NatalChart, aspects: AspectHit[], age_years }. Secondary использует дробные дни напрямую (без округления дней); symbolic продвигает каждую долготу и поворачивает дома на дугу.


POST /v1/charts/directions/primary

Первичные дирекции — метод Плацидуса (полудуги, зодиакальные). Дуга прямого восхождения, подводящая промиссор к сигнификатору суточным вращением, переводится в годы жизни ключом. Сигнификаторы: Asc, MC, Солнце, Луна. Промиссоры: десять планет и их птолемеевы аспекты (☌ ✶ □ △ ☍). Считается тропически; требует места рождения (нужны дома/широта/ARMC). Подробности формул — /docs/calculations §16.4а.

Тело запроса (PrimaryDirectionsRequest)

ПолеТипОбязательныйПо умолчаниюПримечания
natalNatalRequestдаДолжен содержать location
keystringнетnaibodКлюч дуга→время: naibod (0°59′08″/год) или ptolemy (1°/год)
max_yearsnumberнет90Верхняя граница возраста для событий
conversebooleanнетtrueТакже считать конверсные дирекции

Ответ — 200 OK

{ birth, latitude, armc, obliquity, key, events[] }, где events отсортированы по возрасту, а каждое событие:

ПолеТипПримечания
significatorstringascendant | midheaven | sun | moon
promissorstringТело-промиссор
aspectstringconjunction sextile square trine opposition
motionstringdirect (промиссор ведётся к сигнификатору) | converse
arcnumberДуга дирекции в градусах прямого восхождения
yearsnumberВозраст перфекции (arc / ключ)
datestringКалендарная дата перфекции (birth + years)

POST /v1/aspect-hits

Точные даты, когда транзитное тело образует каждый мажорный аспект (соединение, секстиль, квадрат, трин, оппозиция) к натальным точкам, за диапазон дат, с окнами входа/выхода из орба. Один вызов заменяет двоичный поиск по /transits для «когда именно?».

Тело запроса (AspectHitsRequest)

ПолеТипОбязательныйПо умолчаниюПримечания
natalNatalRequestда
transit_bodystringодно из двухОдно транзитное тело
transit_bodiesstring[]одно из двухБатч: несколько транзитных тел за один вызов — натальная карта считается один раз, каждое событие в hits/angle_hits несёт своё transit_body; дубликаты схлопываются. Имеет приоритет над transit_body. Один батч-вызов заменяет N последовательных
from, tostring (RFC 3339)даДиапазон дат (to должен быть после from)
orbnumberнет1Орб (°) для окна входа/выхода
include_anglesbooleanнетfalseТакже находить корни точных аспектов к углам карты (Asc/MC + зеркала Dsc/IC) → angle_hits

Ответ (AspectHits) — 200 OK

{ orb, hits: [...], angle_hits?: [...] }, каждый список отсортирован по exact:

ПолеТипПримечания
transit_body, natal_bodystringДва конца
kindstringВид аспекта
anglenumber0/60/90/120/180
exactstringМомент точного попадания (UTC)
enters, leavesstringКогда тело входит в / выходит из окна orb (линейная оценка по скорости в точный момент)

При include_angles angle_hits[] добавляет { transit_body, angle (ascendant/ midheaven/descendant/imum_coeli), kind, exact_angle, exact, enters, leaves, derived? } — записи Dsc/IC это зеркала (derived: true) пересечения Asc/MC.

Пример

curl -s -X POST https://astro.yuretz.ru/v1/aspect-hits \
  -H 'content-type: application/json' \
  -d '{"natal":{"datetime_utc":"1990-05-15T09:20:00Z","location":{"latitude":55.7558,"longitude":37.6178}},
       "transit_body":"saturn","from":"2026-01-01T00:00:00Z","to":"2027-01-01T00:00:00Z"}'

POST /v1/moon/transit

Транзитная Луна за диапазон (≤ 400 дней, ~13 месяцев — календарный год с запасом за один вызов): окна Луны без курса и путь Луны через натальные дома. То же нахождение корней, что у moon_void; для пути по домам нужна натальная карта с местоположением (иначе только void_windows).

Тело запроса (MoonTransitRequest)

ПолеТипОбязательныйПримечания
natalNatalRequestдаМестоположение нужно для house_path
from, tostring (RFC 3339)даДиапазон, UTC; максимум 400 дней (~13 месяцев)

Ответ (MoonTransit) — 200 OK

БлокФорма элементаПримечания
void_windows{ from, to, via_combusta?, spica_exception?, clipped_start?, clipped_end? }Каждый период Луны без курса; конец окна = следующая ингрессия. Булевы флаги опускаются, когда false
house_path{ from, to, sign, natal_house }Непрерывные сегменты постоянного знака + натального дома (пересечения куспидов по развёрнутой долготе). Пусто без местоположения

Пример

curl -s -X POST https://astro.yuretz.ru/v1/moon/transit \
  -H 'content-type: application/json' \
  -d '{"natal":{"datetime_utc":"1990-05-15T09:20:00Z","location":{"latitude":55.7558,"longitude":37.6178}},
       "from":"2026-07-01T00:00:00Z","to":"2026-07-15T00:00:00Z"}'

GET /v1/extras

Затмения, ближайшие к заданному моменту, и данные неподвижной звезды Алголь (β Персея) — панель астрособытий вкладки «Информация». Вычисление разделяется с WASM-клиентом (astro_core::extras), поэтому результаты точно совпадают.

Параметры запроса

ПараметрТипОбязательныйПо умолчаниюПримечания
jdnumberдаЮлианский день (UT) — обычно julian_day_ut карты
zodiacstringнетtropicalТолько sidereal что-то меняет (влияет на algol_longitude); любое другое значение ведёт себя как tropical

Ответ (ExtrasResult) — 200 OK

ПолеТипПримечания
solar_eclipseobject | nullБлижайшее солнечное затмение (в любом направлении во времени)
solar_eclipse.datetime_utcstringRFC 3339 с числовым смещением (всегда +00:00)
solar_eclipse.kindstringtotal annular partial hybrid
lunar_eclipseobject | nullТа же форма, kind: total partial penumbral
algol_minimastring[]Временные метки минимумов яркости Алголя в пределах ±2 дней от jd
algol_longitudenumber | nullЭклиптическая долгота Алголя на jd, в запрошенном зодиаке

Пример

curl -s "https://astro.yuretz.ru/v1/extras?jd=2448026.888888889&zodiac=tropical"
{
  "solar_eclipse": { "datetime_utc": "1990-07-22T03:02:12+00:00", "kind": "total" },
  "lunar_eclipse": { "datetime_utc": "1990-08-06T14:12:21+00:00", "kind": "partial" },
  "algol_minima": ["1990-05-15T14:29:44+00:00"],
  "algol_longitude": 56.0304994657663
}

GET /v1/calendar/global

Фон года — небо само по себе, без натального ввода: ингрессии в знаки, ретроградные станции и периоды, мунданные (транзит×транзит) аспекты, фазы Луны и затмения за диапазон дат, в одном объекте. Это единый пакетный проход по эфемеридам, предназначенный для вычисления один раз в год и кэширования для всех (стоимость на пользователя ≈ 0). Каждый exact это истинное пересечение методом нахождения корней (момент UTC до субсекундной точности), никогда не оценка; разбиение событий на локальные дни — задача клиента (отправляйте from/to в UTC с ±1 днём отступа вокруг целевого местного года).

Луна по умолчанию исключена из ингрессий и пар аспектов (её ~146 ингрессий в год и сотни аспектов — забота на уровне пользователя/подсчёта очков) — назовите moon явно в bodies, чтобы её включить.

Параметры запроса

ПараметрТипОбязательныйПо умолчаниюПримечания
fromstring (RFC 3339)даНачало диапазона, UTC
tostring (RFC 3339)даКонец диапазона, UTC; максимум ~2 года после from
bodiesstringнетsun,mercury,venus,mars,jupiter,saturn,uranus,neptune,plutoСписок через запятую. Управляет ингрессиями + станциями. Если задан явно, мунданные аспекты перечисляют все пары среди этих тел (включайте Луну/быстрые тела здесь)
aspectsstringнетconjunction,sextile,square,trine,oppositionСписок видов аспектов через запятую для transit_aspects
zodiacstringнетtropicalsidereal сдвигает все долготы

Когда bodies опущено, transit_aspects использует кураторский пул пар — социальные /внешние между собой плюс каждая к Солнцу и Марсу (sun,mars,jupiter,saturn,uranus,neptune,pluto) — чтобы бесплатный слой не был затоплен шумом быстрых внутренних планет.

Ответ (GlobalCalendar) — 200 OK

БлокФорма элементаПримечания
ingresses{ body, sign, from_sign, exact, retrograde }Каждое пересечение границы знака; ретроградные повторные пересечения — отдельные записи. Отсортировано по exact
stations{ body, kind, exact, longitude, sign }kind: retrograde (D→R) / direct (R→D). Без Солнца/Луны/узлов
retrograde_periods{ body, start, end, sign_start, sign_end, clipped_start, clipped_end }Спаренные станции; промежуток за краем диапазона обрезается и помечается
transit_aspects{ body_a, body_b, kind, angle, exact, longitude, retrograde_a, retrograde_b }Точные мунданные аспекты; пара может стать точной до 3× (ретроградность). Отсортировано по exact
moon_phases{ phase, exact, moon_sign, sun_sign, moon_longitude, eclipse? }phase: new/first_quarter/full/last_quarter; eclipse = solar/lunar, если сизигия является затмением
eclipses{ kind, type, exact, longitude, sign, node }Полный список в диапазоне (обычно 4–7 в год). node: north/south (для попаданий на натальные узлы)

Ошибки

Пример

curl -s "https://astro.yuretz.ru/v1/calendar/global?from=2025-12-31T00:00:00Z&to=2027-01-02T00:00:00Z"
{
  "from": "2025-12-31T00:00:00Z",
  "to": "2027-01-02T00:00:00Z",
  "ingresses": [
    { "body": "mercury", "sign": "capricorn", "from_sign": "sagittarius", "exact": "2026-01-01T21:10:42Z", "retrograde": false }
  ],
  "stations": [
    { "body": "uranus", "kind": "direct", "exact": "2026-02-04T02:33:10Z", "longitude": 57.46, "sign": "taurus" }
  ],
  "retrograde_periods": [
    { "body": "jupiter", "start": "2025-12-31T00:00:00Z", "end": "2026-03-11T03:29:51Z", "sign_start": "cancer", "sign_end": "cancer", "clipped_start": true, "clipped_end": false }
  ],
  "transit_aspects": [
    { "body_a": "sun", "body_b": "mars", "kind": "conjunction", "angle": 0.0, "exact": "2026-01-09T11:41:13Z", "longitude": 289.22, "retrograde_a": false, "retrograde_b": false }
  ],
  "moon_phases": [
    { "phase": "full", "exact": "2026-01-03T10:02:55Z", "moon_sign": "cancer", "sun_sign": "capricorn", "moon_longitude": 103.03 }
  ],
  "eclipses": [
    { "kind": "solar", "type": "annular", "exact": "2026-02-17T12:11:53Z", "longitude": 328.8, "sign": "aquarius", "node": "north" },
    { "kind": "lunar", "type": "total", "exact": "2026-03-03T11:33:41Z", "longitude": 162.9, "sign": "virgo", "node": "south" }
  ]
}

POST /v1/geo/utc

Преобразовать местную гражданскую дату-время в часовом поясе IANA в UTC, учитывая исторические изменения DST/пояса (например, декретное время СССР, летнее время 5-го пояса Казахстана 1992 года). Разделяется с WASM-клиентом (astro_core::tz) — идентичные результаты в браузере и на сервере.

Тело запроса (UtcReq)

ПолеТипОбязательныйПримечания
datetime_localstringдаYYYY-MM-DDTHH:MM или YYYY-MM-DDTHH:MM:SS, без смещения часового пояса
tzstringдаИмя часового пояса IANA, например Europe/Moscow

Ответ (UtcResult) — 200 OK

ПолеТипПримечания
datetime_utcstringYYYY-MM-DDTHH:MM:SSZ
offsetstring±HH:MM
offset_secondsinteger
abbreviationstringнапример MSD, MSK — рендеринг смещения от chrono-tz, не всегда общепринятая аббревиатура

Для местного времени, попадающего в пробел DST (не существует) или неоднозначного (происходит дважды), используется самый ранний валидный момент UTC.

Ошибки

Пример

curl -s -X POST https://astro.yuretz.ru/v1/geo/utc \
  -H 'content-type: application/json' \
  -d '{ "datetime_local": "1990-05-15T12:00", "tz": "Europe/Moscow" }'
{ "datetime_utc": "1990-05-15T08:00:00Z", "offset": "+04:00", "offset_seconds": 14400, "abbreviation": "MSD" }

GET /v1/geo/search

Поиск по подстроке в базе городов GeoNames (234 640 городов, 42 языка) для выбора места рождения. Совпадения по префиксу ранжируются выше совпадений по подстроке; ничьи разрешаются по населению (по убыванию).

Параметры запроса

ПараметрТипОбязательныйПо умолчаниюПримечания
qstringдаСопоставляется без учёта регистра с именем города на каждом языке (так русский UI может найти «London», набранный по-английски)
limitintegerнет8Ограничено до [0, 20]
langstringнетruОдин из 42 поддерживаемых кодов (см. ниже); нераспознанные коды молча откатываются к ru

Ответ (GeoCity[]) — 200 OK

ПолеТипПримечания
namestringЛокализовано под lang; откатывается к английскому, затем к сырому имени GeoNames
countrystringЛокализованное название страны
admin1stringЛокализованный административный регион первого уровня (штат/область/…); "", если неизвестно
lat, lonnumberГрадусы
tzstringЧасовой пояс IANA, с применёнными историческими корректировками (см. swisseph-embedded.md / модуль geo для случая Тургай/Аркалык 1992)
populationinteger

Пустое q возвращает [].

Пример

curl -s "https://astro.yuretz.ru/v1/geo/search?q=Париж&limit=2&lang=ru"
[
  { "name": "Париж", "country": "Франция", "admin1": "Иль-де-Франс", "lat": 48.85341, "lon": 2.3488, "tz": "Europe/Paris", "population": 2138551 },
  { "name": "Париж", "country": "США", "admin1": "Техас", "lat": 33.66094, "lon": -95.55551, "tz": "America/Chicago", "population": 24782 }
]

GET /v1/geo/near

Ближайший город к координате (обратное геокодирование — используется для «определить моё местоположение»). Линейное сканирование по планарно аппроксимированному расстоянию (нормально в масштабе выбора города); не истинный поиск по большому кругу.

Параметры запроса

ПараметрТипОбязательныйПримечания
lat, lonnumberдаГрадусы
langstringнет (по умолчанию ru)Так же, как /v1/geo/search

Ответ — 200 OK

Один объект GeoCity или JSON null, если база данных пуста (на практике никогда — таблица всегда встроена).

curl -s "https://astro.yuretz.ru/v1/geo/near?lat=55.7558&lon=37.6178&lang=ru"

GET /v1/geo/tzcity

Самый населённый город в заданном часовом поясе IANA — запасной вариант местоположения, когда GPS недоступен, но известен часовой пояс браузера.

Параметры запроса

ПараметрТипОбязательныйПримечания
tzstringдаИмя часового пояса IANA
langstringнет (по умолчанию ru)Так же, как /v1/geo/search

Ответ — 200 OK

Один GeoCity или JSON null, если ни один город в базе данных не несёт эту точную строку часового пояса (примечание: это сопоставляется с сырым полем tz GeoNames, а не с исправленным историческими корректировками, которое /v1/geo/search возвращает в tz).

curl -s "https://astro.yuretz.ru/v1/geo/tzcity?tz=Europe/Moscow&lang=ru"

GET /v1/geo/pack

Загружаемый пакет городов по каждому языку, который клиентский JavaScript браузера (web/geopack.js) декодирует для запуска выбора города полностью офлайн. Не предназначен для общего потребления через API — это внутренний, двоичный, версионированный артефакт — но задокументирован здесь для полноты, поскольку это публичная HTTP-конечная точка.

Параметры запроса

ПараметрТипОбязательныйПримечания
langstringдаОдин из 42 поддерживаемых кодов; нераспознанные коды откатываются к ru
vstringнетТолько сброс кэша, игнорируется на стороне сервера (клиент устанавливает его в текущую версию данных)

Ответ — 200 OK

Всегда Content-Encoding: gzip (каждый современный клиент декодирует его прозрачно; несжатого варианта нет). Условный GET поддерживается через ETag/If-None-Match304 Not Modified.

ЗаголовокЗначение
Content-Typetext/tab-separated-values; charset=utf-8
Content-Encodinggzip
Cache-Controlpublic, max-age=31536000
ETagХеш содержимого (до gzip) пакета, меняется, когда меняются данные пакета

Формат тела (V3, после декодирования gzip) — столбцовый, отсортированный географически, варинт-дельты; не стабильный контракт, может меняться без повышения версии в этом документе (клиент заново выводит всё из тега #V3 на проводе и заголовка длины #S, поэтому он самоописывающийся):

#V3 <lang>
#S <n> <lenTz> <lenAdm> <lenNames> <lenEns> <lenExtra> <lenLat> <lenLon> <lenTzV> <lenPopV> <lenAdmV>
<tz dictionary, \n-joined>
<admin dictionary, "CC.code\tcountry\tregion" lines>
<names, \n-joined, localized to lang>
<English names, \n-joined, "" when identical to the localized name>
<extra search words, \n-joined, space-separated — every other language's
 spelling not already covered by name/English, so offline search matches
 any of the 42 languages regardless of the pack's language>
<zigzag-varint columns: lat delta ×1e5, lon delta ×1e5, tz index, population, admin index>

Строки отсортированы по широтной полосе 0.5° затем по долготе, что удерживает последовательные координатные дельты малыми для варинт-кодирования. См. crates/astro-api/src/geo.rs (pack()) для авторитетного генератора и web/geopack.js для эталонного декодера.

curl -s "https://astro.yuretz.ru/v1/geo/pack?lang=ru" -o pack.gz   # already gzip on the wire
gunzip -c pack.gz | head -c 200

Статические ресурсы — GET /*

Всё, что не сопоставлено маршрутом выше (включая неизвестные пути), отдаётся из встроенного бандла фронтенда (одностраничное приложение): /, /app.js, /style.css, /engine.js, /engine/astro.wasm, /geopack.js, /i18n/<lang>.json, иконки, шрифты, манифест. index.html шаблонизируется тремя значениями, внедряемыми сервером (версия ресурсов, хеш содержимого WASM, версия гео-данных), и отдаётся с Cache-Control: no-cache; каждый другой ресурс долго кэшируется (max-age=31536000) с ETag и сбрасывается через запрос ?v=, который встраивает index.html. engine/astro.wasm дополнительно согласует gzip (Accept-Encoding) и сообщает свой несжатый размер через заголовок x-wasm-size, чтобы клиент мог отрисовать точный UI прогресса загрузки. Это деталь реализации встроенного веб-приложения, а не стабильный API — см. README.md для архитектуры фронтенда.


Поддерживаемые языки (параметр lang)

42 кода, разделяемых между /v1/geo/search, /v1/geo/near, /v1/geo/tzcity, /v1/geo/pack и LANG_META фронтенда:

ru uk kk en de fr it pl be az uz ka hy es pt nl sv no da fi cs sk ro hu el
bg sr hr tr ar fa he hi bn ur zh ja ko vi th id ms

ar fa he ur пишутся справа налево во фронтенде; это не влияет на сам API. Нераспознанный код не является ошибкой — каждая конечная точка, принимающая lang, откатывается к ru.