Skip to content

Commit 17cf127

Browse files
committed
fix: ship .js import suffixes so NodeNext projects keep the SDK types, docs: most-used endpoints across all 18 domains composed from one location lookup, AGENTS task table in catalog order, llms-full headers without em dashes, ci: src/index.ts in the drift list
1 parent dd5dbb0 commit 17cf127

18 files changed

Lines changed: 375 additions & 282 deletions

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
ROXYAPI_SPEC_FILE: specs/openapi.json
3333
run: |
3434
bun run generate
35-
git diff --exit-code -- specs/openapi.json src/client.gen.ts src/sdk.gen.ts src/types.gen.ts src/client src/core README.md AGENTS.md docs/llms-full.txt \
35+
git diff --exit-code -- specs/openapi.json src/index.ts src/client.gen.ts src/sdk.gen.ts src/types.gen.ts src/client src/core README.md AGENTS.md docs/llms-full.txt \
3636
|| { echo 'codegen drift: commit the regenerated files'; exit 1; }
3737
3838
- name: Lint

‎AGENTS.md‎

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const { data } = await roxy.location.searchCities({ query: { q: 'New York' } });
2727
const { latitude, longitude, timezone } = data.cities[0];
2828
// `timezone` is the IANA string ("America/New_York"). Pass it directly to any chart
2929
// endpoint and the server resolves it to the DST-correct decimal offset using
30-
// the chart's own `date`, so a January 1990 New York chart picks EST (-5) even
30+
// the `date` of the chart itself, so a January 1990 New York chart picks EST (-5) even
3131
// when you looked the city up in July. If you prefer numbers, `utcOffset`
3232
// (5.5, -5, 9, ...) also works and produces identical charts.
3333
```
@@ -70,24 +70,26 @@ Type `roxy.` to see all available namespaces. Type `roxy.{domain}.` to see every
7070
Five rules to follow when writing any call with this SDK. Get these right and the generated types do the rest.
7171

7272
- **One options object, hey-api wrapped.** Every method takes a single object with `path`, `query`, and `body` keys. Path params go in `path`, query params in `query`, request body in `body`. Never flat named args. Right: `roxy.astrology.getDailyHoroscope({ path: { sign: 'aries' } })`. Wrong: `roxy.astrology.getDailyHoroscope({ sign: 'aries' })`.
73-
- **Always `await`. Always destructure `{ data, error, response }`.** All methods are async. `data` is the typed success response (undefined on error). `error` is the typed API error (`{ error: string, code: string }`, undefined on success). `response` is the raw `fetch` Response. Switch on `error.code`, not on `error.error`.
73+
- **Always `await`. Always destructure `{ data, error, response }`.** All methods are async. `data` is the typed success response (undefined on error). `error` is the typed API error (`{ error: string, code: string }`, undefined on success). `response` is the raw `fetch` Response. Switch on `error.code`, not on `error.error`. The pair is a discriminated union, so `data` is typed as possibly undefined until `error` is checked: write `if (error) throw error;` before reading `data` in a `strict` project, or pass `throwOnError: true` in the call options to have failures throw and `data` typed as always present.
7474
- **Method names match the OpenAPI `operationId` verbatim.** When in doubt, autocomplete `roxy.{domain}.` in your editor or `grep 'public ' node_modules/@roxyapi/sdk/dist/factory.d.ts`. Never invent a method from the URL path or a guess.
75-
- **Response field names come from the spec's response schema.** Field access is typed dot syntax (`data.cities[0].timezone`). TypeScript will catch any invented field at compile time via the generated types - if `tsc` complains, the field does not exist.
76-
- **Do not hand-roll requests.** No raw `fetch`, no axios. The SDK injects auth, base URL, retries, and typed responses. Use `createRoxy(key)` for the common case, or `new Roxy({ client })` with `createClient` from `@roxyapi/sdk/client` when you need a custom fetch or interceptors.
75+
- **Response field names come from the response schema of the spec.** Field access is typed dot syntax (`data.cities[0].timezone`). TypeScript will catch any invented field at compile time via the generated types - if `tsc` complains, the field does not exist.
76+
- **Do not hand-roll requests.** No raw `fetch`, no axios. The SDK injects auth, the base URL and typed responses; it does not retry, so wrap calls you want retried. Use `createRoxy(key)` for the common case, or `new Roxy({ client })` with `createClient` from `@roxyapi/sdk/client` when you need a custom fetch or interceptors.
7777

7878
## Critical patterns
7979

8080
### Two-step pattern for coordinate-dependent endpoints
8181

8282
```typescript
83-
const { data } = await roxy.location.searchCities({ query: { q: 'London' } });
83+
const { data, error } = await roxy.location.searchCities({ query: { q: 'London' } });
84+
if (error) throw error;
8485
const { latitude, longitude, timezone } = data.cities[0];
86+
const birth = { date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone };
8587

86-
const { data: chart } = await roxy.astrology.generateNatalChart({
87-
body: { date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone },
88-
});
88+
const { data: chart } = await roxy.astrology.generateNatalChart({ body: birth });
8989
```
9090

91+
One lookup feeds every domain. The same `birth` object is the body for `astrology.generateNatalChart`, `vedicAstrology.generateBirthChart`, `vedicAstrology.getCurrentDasha`, `ayurveda.calculateAyurvedicConstitution` and the `birthData` of `forecast.forecastTransits`; the instant alone (`date`, `time`, `timezone`) is the body for `humanDesign.generateBodygraph`, `chineseAstrology.generateBaziChart` and `kabbalah.generateBirthProfile`. Never look the city up twice for one person.
92+
9193
### GET endpoints - use `path` for URL params, `query` for query params
9294

9395
```typescript
@@ -126,7 +128,7 @@ await roxy.numerology.calculateLifePath({
126128
});
127129
```
128130

129-
Supported: `astrology`, `vedicAstrology`, `forecast`, `humanDesign`, `chineseAstrology`, `fengShui`, `mesoamericanAstrology`, `vastu`, `numerology`, `kabbalah`, `tarot`, `biorhythm`, `ayurveda`, `iching`, `crystals`, `angelNumbers`. English-only: `dreams`, `location`, `usage`, `languages`. The two Chinese scripts (`zh-Hans`, `zh-Hant`) currently ship on Chinese astrology and feng shui; every other domain answers those codes in English per field. To list supported codes at runtime, call `roxy.languages.listLanguages()`.
131+
Supported: `astrology`, `vedicAstrology`, `forecast`, `humanDesign`, `chineseAstrology`, `fengShui`, `mesoamericanAstrology`, `vastu`, `numerology`, `kabbalah`, `tarot`, `biorhythm`, `ayurveda`, `iching`, `crystals`, `angelNumbers`, `languages`. English-only: `dreams`, `location`, `usage`. The two Chinese scripts (`zh-Hans`, `zh-Hant`) currently ship on Chinese astrology and feng shui; every other domain answers those codes in English per field. To list supported codes at runtime, call `roxy.languages.listLanguages()`.
130132

131133
### Error handling
132134

@@ -151,54 +153,72 @@ console.log(data.sign, data.overview);
151153
| 401 | `invalid_api_key` | Key format invalid or tampered |
152154
| 401 | `subscription_not_found` | Key references non-existent subscription |
153155
| 401 | `subscription_inactive` | Subscription cancelled, expired, or suspended |
156+
| 401 | `api_key_revoked` | Key was deleted from the account |
154157
| 404 | `not_found` | Resource not found |
158+
| 4xx | `bad_request` and other status-derived codes | A client error the endpoint itself detected, such as a future birth date |
155159
| 429 | `rate_limit_exceeded` | Monthly quota reached |
156160
| 500 | `internal_error` | Server error |
157161

158162
## Common tasks
159163

160-
Ordered by domain priority (Western, Vedic, Forecast, Human Design, Chinese Astrology, Feng Shui, Numerology, Tarot, Biorhythm, I Ching, Crystals, Dreams, Angel Numbers, Location, Usage, Languages).
164+
In the catalog order (Western astrology, Vedic astrology, forecast, Human Design, Chinese astrology, feng shui, Mesoamerican astrology, Vastu, numerology, Kabbalah, tarot, biorhythm, Ayurveda, I Ching, crystals, dreams, angel numbers, location, usage, languages). `birth` is `{ date, time, latitude, longitude, timezone }` from the two-step pattern above.
161165

162166
| Task | Code |
163167
|------|------|
168+
| Find city coordinates (do this first) | `roxy.location.searchCities({ query: { q: 'Berlin' } })` |
164169
| Daily horoscope | `roxy.astrology.getDailyHoroscope({ path: { sign } })` |
165-
| Natal chart (Western) | `roxy.astrology.generateNatalChart({ body: { date, time, latitude, longitude, timezone } })` |
170+
| Natal chart (Western) | `roxy.astrology.generateNatalChart({ body: birth })` |
166171
| Synastry | `roxy.astrology.calculateSynastry({ body: { person1, person2 } })` |
167172
| Compatibility score | `roxy.astrology.calculateCompatibility({ body: { person1, person2 } })` |
168-
| Current moon phase | `roxy.astrology.getCurrentMoonPhase()` |
173+
| Current moon phase | `roxy.astrology.getCurrentMoonPhase({})` |
169174
| Transits | `roxy.astrology.calculateTransits({ body: { natalChart } })` |
170-
| Kundli (Vedic birth chart) | `roxy.vedicAstrology.generateBirthChart({ body: { date, time, latitude, longitude } })` |
171-
| Panchang (detailed) | `roxy.vedicAstrology.getDetailedPanchang({ body: { date, latitude, longitude } })` |
172-
| Choghadiya | `roxy.vedicAstrology.getChoghadiya({ body: { date, latitude, longitude } })` |
173-
| Current dasha | `roxy.vedicAstrology.getCurrentDasha({ body: { date, time, latitude, longitude } })` |
174-
| Mangal Dosha | `roxy.vedicAstrology.checkManglikDosha({ body: { date, time, latitude, longitude } })` |
175+
| Kundli (Vedic birth chart) | `roxy.vedicAstrology.generateBirthChart({ body: birth })` |
176+
| Panchang (detailed) | `roxy.vedicAstrology.getDetailedPanchang({ body: { date, latitude, longitude, timezone } })` |
177+
| Choghadiya | `roxy.vedicAstrology.getChoghadiya({ body: { date, latitude, longitude, timezone } })` |
178+
| Current dasha | `roxy.vedicAstrology.getCurrentDasha({ body: birth })` |
179+
| Mangal Dosha | `roxy.vedicAstrology.checkManglikDosha({ body: birth })` |
175180
| Guna Milan (matching) | `roxy.vedicAstrology.calculateGunMilan({ body: { person1, person2 } })` |
176-
| Navamsa (D9) | `roxy.vedicAstrology.generateNavamsa({ body: { date, time, latitude, longitude } })` |
177-
| KP chart | `roxy.vedicAstrology.generateKpChart({ body: { date, time, latitude, longitude } })` |
181+
| Navamsa (D9) | `roxy.vedicAstrology.generateNavamsa({ body: birth })` |
182+
| KP chart | `roxy.vedicAstrology.generateKpChart({ body: birth })` |
183+
| KP ruling planets | `roxy.vedicAstrology.getKpRulingPlanets({ body: { latitude, longitude, timezone } })` |
178184
| Nakshatra detail | `roxy.vedicAstrology.getNakshatra({ path: { id: 'ashwini' } })` |
185+
| Transit forecast | `roxy.forecast.forecastTransits({ body: { birthData: birth, startDate, endDate } })` |
186+
| Cross-domain timeline | `roxy.forecast.generateTimeline({ body: { birthData: birth, startDate, endDate } })` |
187+
| Human Design bodygraph | `roxy.humanDesign.generateBodygraph({ body: { date, time, timezone } })` |
188+
| Human Design connection | `roxy.humanDesign.calculateConnection({ body: { personA, personB } })` |
189+
| BaZi Four Pillars | `roxy.chineseAstrology.generateBaziChart({ body: { date, time, timezone } })` |
190+
| Chinese zodiac animal | `roxy.chineseAstrology.calculateZodiacAnimal({ body: { date } })` |
191+
| Almanac day (Tong Shu) | `roxy.chineseAstrology.getAlmanacDay({ path: { date } })` |
192+
| Kua number | `roxy.fengShui.calculateKuaNumber({ body: { date, gender } })` |
193+
| Flying star natal chart | `roxy.fengShui.generateFlyingStarChart({ body: { period, facing } })` |
194+
| Tzolkin day sign | `roxy.mesoamericanAstrology.calculateTzolkin({ body: { date } })` |
195+
| Full Maya chart | `roxy.mesoamericanAstrology.generateMayanChart({ body: { date } })` |
196+
| Vastu entrance | `roxy.vastu.calculateEntrancePada({ body: { plot, facing, doorPosition } })` |
197+
| Vastu room compliance | `roxy.vastu.calculateRoomCompliance({ body: { plot, facing, rooms } })` |
179198
| Life path number | `roxy.numerology.calculateLifePath({ body: { year, month, day } })` |
180199
| Full numerology chart | `roxy.numerology.generateNumerologyChart({ body: { fullName, year, month, day } })` |
181200
| Personal year | `roxy.numerology.calculatePersonalYear({ body: { month, day } })` |
201+
| Gematria | `roxy.kabbalah.calculateGematria({ body: { text } })` |
202+
| Kabbalah birth profile | `roxy.kabbalah.generateBirthProfile({ body: { date, time, timezone } })` |
182203
| Daily tarot card | `roxy.tarot.getDailyCard({ body: { seed } })` |
183204
| Three-card spread | `roxy.tarot.castThreeCard({ body: { question } })` |
184205
| Celtic Cross | `roxy.tarot.castCelticCross({ body: { question } })` |
185206
| Yes / no tarot | `roxy.tarot.castYesNo({ body: { question } })` |
186-
| Human Design bodygraph | `roxy.humanDesign.generateBodygraph({ body: { date, time, latitude, longitude, timezone } })` |
187-
| Forecast timeline | `roxy.forecast.generateTimeline({ body: { birthData, startDate, endDate } })` |
188-
| Daily biorhythm | `roxy.biorhythm.getDailyBiorhythm({ body: { seed } })` |
207+
| Daily biorhythm reading | `roxy.biorhythm.getDailyBiorhythm({ body: { seed } })` |
189208
| Biorhythm forecast | `roxy.biorhythm.getForecast({ body: { birthDate } })` |
190209
| Biorhythm compatibility | `roxy.biorhythm.calculateBioCompatibility({ body: { person1, person2 } })` |
210+
| Ayurvedic constitution | `roxy.ayurveda.calculateAyurvedicConstitution({ body: birth })` |
211+
| Dinacharya | `roxy.ayurveda.getDinacharyaSchedule({ body: { date, latitude, longitude, timezone } })` |
191212
| Daily hexagram | `roxy.iching.getDailyHexagram({ body: { seed } })` |
192-
| Cast I Ching reading | `roxy.iching.castReading()` |
213+
| Cast I Ching reading | `roxy.iching.castReading({})` |
193214
| Hexagram detail | `roxy.iching.getHexagram({ path: { number: 1 } })` |
194215
| Crystal by zodiac | `roxy.crystals.getCrystalsByZodiac({ path: { sign } })` |
195216
| Crystal by chakra | `roxy.crystals.getCrystalsByChakra({ path: { chakra } })` |
196217
| Dream symbol lookup | `roxy.dreams.getDreamSymbol({ path: { id: 'flying' } })` |
197218
| Angel number meaning | `roxy.angelNumbers.getAngelNumber({ path: { number: '1111' } })` |
198219
| Universal number lookup | `roxy.angelNumbers.analyzeNumberSequence({ query: { number: '1234' } })` |
199-
| Find city coordinates | `roxy.location.searchCities({ query: { q: 'Berlin' } })` |
200-
| Check API usage | `roxy.usage.getUsageStats()` |
201-
| List supported languages | `roxy.languages.listLanguages()` |
220+
| Check API usage | `roxy.usage.getUsageStats({})` |
221+
| List supported languages | `roxy.languages.listLanguages({})` |
202222

203223
## Field formats that trip agents
204224

@@ -232,7 +252,7 @@ These are the fields AI agents most often get wrong. Copy the format column exac
232252
|--------|---------|--------|---------|
233253
| UTC / London (winter) | `0` | Dubai | `4` |
234254
| London (summer, BST) | `1` | Karachi | `5` |
235-
| Berlin / Paris | `1` (winter) / `2` (summer) | Delhi / Mumbai (IST) | `5.5` |
255+
| Berlin / Paris | `1` (winter) / `2` (summer) | Delhi (IST) | `5.5` |
236256
| Istanbul | `3` | Kathmandu (NPT) | `5.75` |
237257
| Moscow | `3` | Dhaka | `6` |
238258
| Tehran | `3.5` (winter) / `4.5` (summer) | Bangkok | `7` |
@@ -242,7 +262,7 @@ These are the fields AI agents most often get wrong. Copy the format column exac
242262
| Denver (MST / MDT) | `-7` / `-6` | Auckland | `12` (winter) / `13` (summer) |
243263
| Los Angeles (PST / PDT) | `-8` / `-7` | Honolulu | `-10` |
244264

245-
DST matters. If the birth date falls inside a daylight-saving window, use the summer / DST offset. For Vedic endpoints this is rarely an issue (most users are in India, fixed 5.5), but Western natal charts must respect DST at the time of birth.
265+
DST matters. If the birth date falls inside a daylight-saving window, use the summer / DST offset, or pass the IANA string from the location lookup and let the server resolve it. India observes no DST, so a fixed `5.5` is always right there; anywhere else, a natal chart must carry the offset in force at the time of birth.
246266

247267
## Astrology domain gotchas for LLMs
248268

@@ -280,7 +300,7 @@ Use the SDK for typed TypeScript apps. Use MCP for AI agents (Claude Desktop, Cu
280300
- **Western `timezone` is required** and accepts either a decimal (`-5` for EST, `5.5` for IST, `0` for UTC) or an IANA string (`"America/New_York"`, `"Asia/Kolkata"`, `"UTC"`). IANA is resolved to the DST-correct offset for the request `date`. Vedic endpoints accept an optional `timezone` that defaults to `5.5` (IST).
281301
- **`data` and `error` are mutually exclusive.** If `error` is set, `data` is `undefined` and vice versa.
282302
- **Switch on `error.code`, not `error.error`.** The message may change; the code is stable.
283-
- **List endpoints may return paginated objects** (`{ items, total }`) instead of raw arrays. Check the type.
303+
- **List endpoints return a paginated envelope**, `{ total, limit, offset }` plus a named array (`cities`, `crystals`, `hexagrams`, `symbols`), never a bare array. Pass `query: { limit }` to widen a page; `listHexagrams` defaults to 20 of 64.
284304

285305
## Links
286306

0 commit comments

Comments
 (0)