HTTP API routing and versioning
The HTTP API exposes Vedic and Western calculations as JSON operations. It calculates results on demand; these routes do not create saved charts, birth records, or accounts. Use this guide to call the API or add a controller. The complete route inventory lists the available endpoints.
URL contract
Service endpoints follow /<service>/v<version>/<feature>.
| Segment | Meaning | Example |
|---|---|---|
| Service | Domain package that owns the calculation | vedic for @astrology/vedic, western for @astrology/western |
| Version | Explicit HTTP contract version for that service | v1 |
| Feature | Public calculation or discovery name | dasha, natal, capabilities |
Examples: POST /vedic/v1/dasha, POST /western/v1/natal, and
GET /western/v1/capabilities. There is no /api prefix. GET /health belongs to
the application and stays outside the service/version hierarchy.
GET reads health or capabilities. POST accepts a JSON calculation request, including nested profiles or reference data that would be unwieldy in query parameters. POST returns a result directly with status 200 on success; it does not imply persistence or creation of a resource. There are no PUT, PATCH, or DELETE routes.
Existing public feature names are preserved. In particular, Vedic uses transits while Western
uses transit. Vedic shadbala selects the internal strengths layer, and yogas selects
yoga-dosha. Use internal layer names in combined chart requests and public names in URLs.
Start and discover
From the repository root, install dependencies with the pinned pnpm version, then run:
pnpm setup:ephemeris
pnpm --filter @astrology/astrology-api... -r build
NASA_USER_AGENT="astrology-api/0.1 (you@example.com)" PORT=3001 pnpm --filter @astrology/astrology-api start
The native Swiss dependency must be built for the host platform. Setup downloads and verifies
the pinned ephemeris files before requests are served. The current startup requires
NASA_USER_AGENT, an identifying HTTP user-agent string, not a NASA API key. It constructs
both providers even though routing defaults to Swiss. PORT defaults to 3001.
curl http://localhost:3001/health
curl http://localhost:3001/vedic/v1/capabilities
curl http://localhost:3001/western/v1/capabilities
Health returns { "status": "ok", "vedic": true, "western": true } when both services are
enabled. It reports service presence, not a fresh provider calculation or external connectivity
test. Capabilities include service configurations and feature support; a mounted endpoint does
not guarantee that every profile, input, or provider supports its calculation.
Hosts can disable a tradition when assembling their runtime. Its whole route prefix is then absent and returns 404. The default server enables both traditions.
Request shapes
Send Content-Type: application/json. The HTTP app parses bodies up to 64 KB. Chart requests
must be objects with an instant string or number; the engines validate the instant and the
remaining values. Use an ISO timestamp with an explicit timezone, or epoch milliseconds.
Single-feature shortcuts
Vedic chart shortcuts and Western technique shortcuts accept shared chart fields plus an optional
singular request. This example uses the same natal input as the API-service integration test:
curl -X POST http://localhost:3001/western/v1/natal \
-H 'Content-Type: application/json' \
-d '{
"instant": "2000-01-01T12:00:00Z",
"houseObserver": { "latitude": 19.076, "longitude": 72.8777 }
}'
| Shared field | Meaning |
|---|---|
instant |
Moment being calculated; required |
houseObserver |
Location used for houses and chart angles |
positionObserver |
Separate observer for planetary positions when supported by the selected profile/provider |
profile |
Service-specific profile reference; omission selects the configured default |
allowPartial |
Passed to the chart engine to control supported partial-result behavior |
request |
Feature-specific options, mapped into that feature’s internal request entry |
Observer and feature requirements depend on the selected calculation. A missing observer is
not automatically filled from another field. allowPartial does not bypass input validation
or guarantee success after arbitrary failures. Unknown top-level chart fields are discarded
by the API-service adapter rather than treated as additional calculation options.
For example, /vedic/v1/shadbala maps request to requests.strengths and fixes
layers to ["strengths"]. Its response is the service’s chart result, not an extracted
strengths payload. Other shortcuts likewise return their complete chart result.
Combined charts
/vedic/v1/chart takes layers and optional requests keyed by internal layer name:
{
"instant": "2000-01-01T12:00:00Z",
"houseObserver": { "latitude": 19.076, "longitude": 72.8777 },
"layers": ["dasha", "varga"]
}
/western/v1/chart takes techniques and optional requests keyed by technique name.
For example, a natal-only request adds "techniques": ["natal"] to the input above and
omits layers. Some techniques need additional reference charts or options; adding their
names alone does not satisfy those inputs. These requests use plural requests, whereas
single-feature shortcuts use singular request.
Vedic operation requests
These four operations accept their own complete service request directly. They do not use the
shared shortcut envelope or wrap their input inside request.
| Endpoint | Top-level input |
|---|---|
/vedic/v1/panchang |
localDate, dayStart, observer, optional profile |
/vedic/v1/muhurta |
days, observer, purpose, packVersion, direction, optional minimumMinutes and profile |
/vedic/v1/transits |
mode, reference, optional profile and bindus; snapshot mode adds asOf, window mode adds window, step, optional bodies |
/vedic/v1/matching |
pair, optional profile |
See the Vedic request types for the nested
contracts. A request containing only instant is not a substitute for these operation inputs.
Responses and failures
Controllers serialize the API-service result directly, preserving domain values, metadata,
and provenance supplied by that service. There is no extra HTTP-level data wrapper.
POST /western/v1/compose returns the tropical snapshot directly for chart rendering, including
body positions and available houses/angles. It accepts shared chart fields and optional
houses: false to skip house placement; it does not take techniques or use the chart-result
envelope below. allowPartial is ignored by this snapshot operation.
Vedic and Western calculation results share these envelope fields:
| Field | Meaning |
|---|---|
value |
Calculated payload; chart calls key values by layer or technique |
rules |
Rules used to produce the result |
provenance |
Profile, rulebook, engine, and available astronomy evidence identities |
missing |
Explicitly omitted features and their reasons |
complete |
Whether the result is complete according to the service |
A 200 response can carry an incomplete chart when the service permits partial results. Clients
must inspect complete and missing before presenting all requested features as available.
See the Vedic result and
Western result types for full metadata contracts.
Failures use this envelope; detail is optional:
{
"error": {
"code": "LAYER_UNSUPPORTED",
"message": "closed",
"detail": { "gate": "probes" }
}
}
That is an illustrative coded failure from the controller tests, not the fixed message for
every unsupported layer. Clients should branch on code, not message wording.
| HTTP status | Examples |
|---|---|
| 400 | Invalid request, instant, observer, or malformed JSON |
| 404 | Unmounted route, unknown profile, rulebook, or muhurta pack |
| 422 | Unsupported feature, incompatible profile, unavailable factor, coverage or search limit |
| 502 | Provider response failure |
| 503 | Provider unavailable |
| 504 | Provider timeout |
| 500 | Unmapped error; internals hidden as INTERNAL / Internal error. |
Malformed JSON specifically returns INVALID_REQUEST / Body is not valid JSON..
Unmatched URLs return NOT_FOUND / No such route.. The old /v1/vedic/* and
/v1/western/* URLs have no aliases or redirects. Unknown versions such as /vedic/v2/*
also return 404 until explicitly mounted. Unsupported HTTP methods fall through to the
same 404 handler; there is no custom 405 response.
The body-size limit is enforced, but oversized-body errors currently have no dedicated status mapping and reach the generic 500 response. Authentication, CORS policy, and rate limiting are not implemented in this application; deployment infrastructure must supply any such policy.
Controller ownership and version changes
The source groups feature files by service. API versions appear in endpoint mounts, not directories:
apps/astrology-api/src/
app.ts mounts service/version prefixes and health
routes/
vedic/
index.ts assembles the Vedic v1 router
chart.ts registers POST /chart
dasha.ts registers POST /dasha
... one file for each remaining feature
western/
index.ts assembles the Western v1 router
natal.ts registers POST /natal
... one file for each remaining feature
Each feature file registers a relative path on its supplied router. It forwards the body to the injected API service and serializes the result. Calculation rules and shortcut translation belong to the domain/API-service layers; HTTP status mapping belongs to the application error handler. Neither layer selects a URL version automatically from a package or rulebook version.
To expose a new feature, establish its service contract, add its controller file, register it
in the service router, and update the route inventory and HTTP coverage. Adding an entry to
VEDIC_SHORTCUTS or WESTERN_TECHNIQUES alone no longer creates an HTTP endpoint.
When changing a published contract, register the new endpoint contract in the service’s route
files and mount the new prefix explicitly in the application. Do not add version directories.
For example, Vedic can gain
/vedic/v2/* while Western remains on /western/v1/*. Keep older mounted contracts stable
for their supported lifetime. Changes to field names, required inputs, response shapes, or
calculation conventions must be assessed as contract changes. Internal refactors that preserve
the contract do not themselves require a new URL version. Versioning is a maintainer policy,
not an automatic compatibility mechanism: shared services must preserve old-version behavior
or provide explicit translation when multiple versions are served.
Verify feature dispatch, request mapping, errors, disabled services, and version isolation with:
pnpm --filter @astrology/astrology-api... -r build
pnpm --filter @astrology/astrology-api check
pnpm --filter @astrology/astrology-api test
pnpm check:docs
HTTP tests use real Express routing with controlled domain-service implementations; they do not establish Swiss numerical accuracy or production deployment readiness.