sdk-typescript
AGENTS.md1 starsChanged 16 days agoMITView on GitHub
TypeScript SDK for RoxyAPI. 18+ domains (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) plus utility namespaces (usage, languages). One API key, fully typed, zero runtime dependencies. Before writing any code with this SDK, read docs/llms-full.txt in this package for the complete method reference with examples. createRoxy sets the base URL (https://roxyapi.com/api/v2) and auth header automatically. Every method returns { data, error,…
- Reads credentials
- Installs packages
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repositoryOne other file it gives its agents.
- docs/llms-full.txtllms.txt
The file
We split this AGENTS.md into the rules it gives an agent
9 rules. About 1 is common, 1 is distinctive, and 7 are very specific to this project.
≈1
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 25
Every chart, horoscope, panchang, dasha, dosha, navamsa, KP, synastry, compatibility, and natal endpoint needs latitude, longitude, and …
- Very specific: line 74
One options object, hey-api wrapped: Every method takes a single object with path, query, and body keys.
- Very specific: line 76
Method names match the OpenAPI
operationIdverbatim: When in doubt, autocomplete roxy.{domain}. - Very specific: line 273
Every error returns { error, code, doc_url }.
- Very specific: line 339
Every method has a matching MCP tool.
- Distinctive: line 346
Use the SDK for typed TypeScript apps.
- Very specific: line 351
Parameters are objects, not positional: Always { path: {...} }, { body: {...} }, or { query: {...} }.
- Common: line 354
Do not expose API keys client-side: Call Roxy from server code only.
- Very specific: line 357
dataanderrorare mutually exclusive: If error is set, data is undefined and vice versa.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
@roxyapi/sdk - Agent Guide
TypeScript SDK for RoxyAPI. 18+ domains (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) plus utility namespaces (usage, languages). One API key, fully typed, zero runtime dependencies.
Before writing any code with this SDK, read
docs/llms-full.txtin this package for the complete method reference with examples.
Install and initialize
npm install @roxyapi/sdkimport { createRoxy } from '@roxyapi/sdk';
// Retries 429, 500, 502, 503 and 504 by default. Optional settings, shown with their defaults:
// createRoxy(key, { maxRetries: 2, initialDelayMs: 500, maxDelayMs: 30000 })
const roxy = createRoxy(process.env.ROXY_API_KEY!);createRoxy sets the base URL (https://roxyapi.com/api/v2) and auth header automatically. Every method returns { data, error, response }.
Critical rule: geocode before any chart endpoint
Every chart, horoscope, panchang, dasha, dosha, navamsa, KP, synastry, compatibility, and natal endpoint needs latitude, longitude, and (for Western) timezone. Never ask the user for coordinates. Always call roxy.location.searchCities first.
const { data } = await roxy.location.searchCities({ query: { q: 'New York' } });
const { latitude, longitude, timezone } = data.cities[0];
// `timezone` is the IANA string ("America/New_York"). Pass it directly to any chart endpoint.
// The server resolves it to the DST-correct decimal offset using the date of the chart itself,
// so a January 1990 New York chart gets EST (-5) even when you looked the city up in July.
// `utcOffset` is the offset in force today, not on the birth date, so pass the IANA `timezone` string.q accepts bare city ('Paris'), city + country ('Berlin Germany'), or comma-qualified ('Springfield, Illinois'). Use the qualified form to disambiguate same-named cities.
Domains
Type roxy. to see all available namespaces. Type roxy.{domain}. to see every method in that domain.
<!-- BEGIN:DOMAINS -->| Namespace | What it covers |
roxy.astrology | Western astrology API for natal birth charts, daily, weekly, monthly, and yearly horoscopes with unique content per s... |
roxy.vedicAstrology | Vedic astrology (Jyotish) and KP API for kundli generation with the sixteen Shodasavarga divisional charts (D1 to D60... |
roxy.forecast | Astrology forecast API that merges upcoming transit aspects, sign ingresses, retrograde stations, new and full moons,... |
roxy.humanDesign | Human Design API that generates the full bodygraph from a birth moment: type, strategy, inner authority, profile, def... |
roxy.chineseAstrology | Chinese zodiac and BaZi astrology API: Four Pillars charts, Chinese zodiac signs and the Chinese lunisolar calendar f... |
roxy.fengShui | Compute classical feng shui from one API: Xuan Kong flying star natal charts for any of the nine periods and 24 mount... |
roxy.mesoamericanAstrology | Calculate Mayan astrology day signs, the Tzolkin sacred round, the Haab year, the full Long Count and the Aztec tonal... |
roxy.vastu | Vastu Shastra API for directional home and plot analysis: entrance padas with the classical effect of each of the 32... |
roxy.numerology | Numerology API for life path numbers, complete numerology charts and compatibility, in both Pythagorean and Chaldean... |
roxy.kabbalah | Kabbalah API for gematria, the 72 names, the Tree of Life and the Hebrew birthday |
roxy.tarot | Tarot reading API with the complete 78-card Rider-Waite-Smith deck and card meanings for love, career, health, and sp... |
roxy.biorhythm | Biorhythm API for entertainment and reflection, with 10 model cycle types across 3 primary (physical, emotional, inte... |
roxy.ayurveda | Ayurveda API for dosha profiles, the dinacharya daily routine and the ritucharya seasonal regimen, with a verse cited... |
roxy.iching | I-Ching oracle API with all 64 hexagrams, 384 changing lines, 8 trigrams, and modern interpretations for love, career... |
roxy.crystals | Crystal healing API covering the most popular and widely-searched healing crystals and gemstones, from Amethyst and R... |
roxy.dreams | Dream interpretation API with a 2,200+ symbol dream dictionary and psychological meanings covering animals, objects,... |
roxy.angelNumbers | Angel numbers API with meanings for 111, 222, 333, 444, 555, 666, 777, 888, 999, 1111, and 75+ sequences covering eve... |
roxy.location | Timezone and location API with city search and geocoding across 5,180,000+ cities, towns and villages in 240+ countri... |
roxy.usage | Monitor your API usage, check rate limits, and track request consumption |
roxy.reports | Branded reports built from the API: a natal chart and more as a print-ready PDF, self-contained HTML or Markdown, whi... |
roxy.languages | List the response languages accepted by the lang query parameter on every i18n-aware endpoint |
<!-- END:DOMAINS -->The table above covers every endpoint across 18+ product domains plus usage and languages, and auto-syncs from specs/openapi.json at release time.
Quality guidelines for agents
The rules to follow when writing any call with this SDK. Get these right and the generated types do the rest.
- One options object, hey-api wrapped. Every method takes a single object with
path,query, andbodykeys. Path params go inpath, query params inquery, request body inbody. Never flat named args. Right:roxy.astrology.getDailyHoroscope({ path: { sign: 'aries' } }). Wrong:roxy.astrology.getDailyHoroscope({ sign: 'aries' }). - Always
await. Always destructure{ data, error, response }. All methods are async.datais the typed success response (undefined on error).erroris the typed API error ({ error, code, doc_url }, plusissueson avalidation_error; undefined on success).responseis the rawfetchResponse and is optional in the types, so writeresponse?.status. Switch onerror.code, not onerror.error. The pair is a discriminated union, sodatais typed as possibly undefined untilerroris checked: writeif (error) throw error;before readingdatain astrictproject, or passthrowOnError: truein the call options to have failures throw anddatatyped as always present. - Method names match the OpenAPI
operationIdverbatim. When in doubt, autocompleteroxy.{domain}.in your editor orgrep 'public ' node_modules/@roxyapi/sdk/dist/factory.d.ts. Never invent a method from the URL path or a guess. - 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 - iftsccomplains, the field does not exist. - Look up any operation or field beyond this guide. Query the combined OpenAPI spec at
https://roxyapi.com/api/v2/openapi.jsonwith the jq recipe inhttps://roxyapi.com/AGENTS.md, or search the keyless Docs MCP server athttps://roxyapi.com/mcp/docs(one tool,search_docs). - Do not hand-roll requests. No raw
fetch, no axios. The SDK injects auth, the base URL and typed responses; it retries 429, 500, 502, 503 and 504 up to twice by default (see Retries;createRoxy(key, { maxRetries: 0 })turns that off). UsecreateRoxy(key)for the common case, ornew Roxy({ client })withcreateClientfrom@roxyapi/sdk/clientwhen you need a custom fetch or interceptors.
Critical patterns
Two-step pattern for coordinate-dependent endpoints
const { data, error } = await roxy.location.searchCities({ query: { q: 'London' } });
if (error) throw error;
const { latitude, longitude, timezone } = data.cities[0];
const birth = { date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone };
const { data: chart } = await roxy.astrology.generateNatalChart({ body: birth });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.
GET endpoints - use path for URL params, query for query params
await roxy.astrology.getDailyHoroscope({ path: { sign: 'aries' } });
await roxy.crystals.getCrystalsByZodiac({ path: { sign: 'leo' } });
await roxy.crystals.searchCrystals({ query: { q: 'amethyst' } });POST endpoints - use body for request data
Most valuable endpoints (charts, spreads, calculations) are POST:
await roxy.astrology.generateNatalChart({
body: { date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone },
});
await roxy.vedicAstrology.generateBirthChart({
body: { date: '1990-01-15', time: '14:30:00', latitude, longitude },
});
await roxy.tarot.castCelticCross({ body: { question: 'What should I focus on?' } });
await roxy.numerology.calculateLifePath({ body: { year: 1990, month: 1, day: 15 } });Multi-language via query: { lang }
Ten languages: en, tr, de, es, fr, hi, pt, ru, zh-Hans, zh-Hant. Defaults to en.
await roxy.tarot.getDailyCard({ body: { date: '2026-04-22' }, query: { lang: 'es' } });
await roxy.numerology.calculateLifePath({
body: { year: 1990, month: 1, day: 15 },
query: { lang: 'hi' },
});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().
Common tasks
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.
| Task | Code |
| Find city coordinates (do this first) | roxy.location.searchCities({ query: { q: 'Berlin' } }) |
| Daily horoscope | roxy.astrology.getDailyHoroscope({ path: { sign } }) |
| Natal chart (Western) | roxy.astrology.generateNatalChart({ body: birth }) |
| Synastry | roxy.astrology.calculateSynastry({ body: { person1, person2 } }) |
| Compatibility score | roxy.astrology.calculateCompatibility({ body: { person1, person2 } }) |
| Current moon phase | roxy.astrology.getCurrentMoonPhase({}) |
| Transits | roxy.astrology.calculateTransits({ body: { natalChart } }) |
| Kundli (Vedic birth chart) | roxy.vedicAstrology.generateBirthChart({ body: birth }) |
| Panchang (detailed) | roxy.vedicAstrology.getDetailedPanchang({ body: { date, latitude, longitude, timezone } }) |
| Choghadiya | roxy.vedicAstrology.getChoghadiya({ body: { date, latitude, longitude, timezone } }) |
| Current dasha | roxy.vedicAstrology.getCurrentDasha({ body: birth }) |
| Mangal Dosha | roxy.vedicAstrology.checkManglikDosha({ body: birth }) |
| Guna Milan (matching) | roxy.vedicAstrology.calculateGunMilan({ body: { person1, person2 } }) |
| Navamsa (D9) | roxy.vedicAstrology.generateNavamsa({ body: birth }) |
| KP chart | roxy.vedicAstrology.generateKpChart({ body: birth }) |
| KP ruling planets | roxy.vedicAstrology.getKpRulingPlanets({ body: { latitude, longitude, timezone } }) |
| Nakshatra detail | roxy.vedicAstrology.getNakshatra({ path: { id: 'ashwini' } }) |
| Transit forecast | roxy.forecast.forecastTransits({ body: { birthData: birth, startDate, endDate } }) |
| Cross-domain timeline | roxy.forecast.generateTimeline({ body: { birthData: birth, startDate, endDate } }) |
| Human Design bodygraph | roxy.humanDesign.generateBodygraph({ body: { date, time, timezone } }) |
| Human Design connection | roxy.humanDesign.calculateConnection({ body: { personA, personB } }) |
| BaZi Four Pillars | roxy.chineseAstrology.generateBaziChart({ body: { date, time, timezone } }) |
| Chinese zodiac animal | roxy.chineseAstrology.calculateZodiacAnimal({ body: { date } }) |
| Almanac day (Tong Shu) | roxy.chineseAstrology.getAlmanacDay({ path: { date } }) |
| Kua number | roxy.fengShui.calculateKuaNumber({ body: { date, gender } }) |
| Flying star natal chart | roxy.fengShui.generateFlyingStarChart({ body: { period, facing } }) |
| Tzolkin day sign | roxy.mesoamericanAstrology.calculateTzolkin({ body: { date } }) |
| Full Maya chart | roxy.mesoamericanAstrology.generateMayanChart({ body: { date } }) |
| Vastu entrance | roxy.vastu.calculateEntrancePada({ body: { plot, facing, doorPosition } }) |
| Vastu room compliance | roxy.vastu.calculateRoomCompliance({ body: { plot, facing, rooms } }) |
| Life path number | roxy.numerology.calculateLifePath({ body: { year, month, day } }) |
| Full numerology chart | roxy.numerology.generateNumerologyChart({ body: { fullName, year, month, day } }) |
| Personal year | roxy.numerology.calculatePersonalYear({ body: { month, day } }) |
| Gematria | roxy.kabbalah.calculateGematria({ body: { text } }) |
| Kabbalah birth profile | roxy.kabbalah.generateBirthProfile({ body: { date, time, timezone } }) |
| Daily tarot card | roxy.tarot.getDailyCard({ body: { seed, date } }), both optional: seed fixes the card per user (omit for an anonymous card), date is YYYY-MM-DD and defaults to today in UTC |
| Three-card spread | roxy.tarot.castThreeCard({ body: { question } }) |
| Celtic Cross | roxy.tarot.castCelticCross({ body: { question } }) |
| Yes / no tarot | roxy.tarot.castYesNo({ body: { question } }) |
| Biorhythm reading | roxy.biorhythm.getReading({ body: { birthDate } }) |
| Daily biorhythm (seeded) | roxy.biorhythm.getDailyBiorhythm({ body: { seed } }) |
| Biorhythm forecast | roxy.biorhythm.getForecast({ body: { birthDate } }) |
| Biorhythm compatibility | roxy.biorhythm.calculateBioCompatibility({ body: { person1, person2 } }) |
| Ayurvedic constitution | roxy.ayurveda.calculateAyurvedicConstitution({ body: birth }) |
| Dinacharya | roxy.ayurveda.getDinacharyaSchedule({ body: { date, latitude, longitude, timezone } }) |
| Daily hexagram | roxy.iching.getDailyHexagram({ body: { seed } }) |
| Cast I Ching reading | roxy.iching.castReading({}) |
| Hexagram detail | roxy.iching.getHexagram({ path: { number: 1 } }) |
| Crystal by zodiac | roxy.crystals.getCrystalsByZodiac({ path: { sign } }) |
| Crystal by chakra | roxy.crystals.getCrystalsByChakra({ path: { chakra } }) |
| Dream symbol lookup | roxy.dreams.getDreamSymbol({ path: { id: 'flying' } }) |
| Angel number meaning | roxy.angelNumbers.getAngelNumber({ path: { number: '1111' } }) |
| Universal number lookup | roxy.angelNumbers.analyzeNumberSequence({ query: { number: '1234' } }) |
| Check API usage | roxy.usage.getUsageStats({}) |
| List supported languages | roxy.languages.listLanguages({}) |
Field formats that trip agents
These are the fields AI agents most often get wrong. Copy the format column exactly.
| Field | Format | Good | Bad |
timezone | Decimal hours (number) OR IANA string | 5.5, -5, 0 (decimal) OR "Asia/Kolkata", "America/New_York" (IANA, resolved to DST-correct offset for the chart date) | "5:30", "+0530", "GMT-5", partial names |
date | ISO date string | "1990-01-15" | "Jan 15 1990", new Date(), "15/01/1990", "1990-1-15" |
time | 24-hour string | "14:30:00", "09:00:00" | "2:30 PM", "14:30" (no seconds), "9:0:0" (no leading zeros) |
latitude | Decimal degrees (number) | 51.5074 (London), -33.8688 (Sydney), 40.7128 (NYC) | "28°36'N", "28 36 50", strings |
longitude | Decimal degrees (number) | -0.1278 (London), -74.006 (NYC), 139.6917 (Tokyo) | Same as latitude - no DMS strings |
sign (horoscope path) | Lowercase zodiac name | aries, taurus, gemini, ... pisces | "♈", "1". Case does not matter ("Aries" works), lowercase is canonical |
chakra (crystals path) | Title-case English name from the fixed enum | "Root", "Sacral", "Solar Plexus", "Heart", "Throat", "Third Eye", "Crown" | "heart", "third-eye", "solar plexus" - route is case-insensitive at runtime, but the generated TS enum is title-case; lowercase fails tsc --strict. |
fullName (numerology) | Birth-certificate name | "John William Smith", "Priya Rajesh Sharma" | Nickname, married name, partial name - affects all letter-based calcs |
seed | Any string (deterministic) | "user-42", "session-abc-123", email hash | Numbers, objects - must be string |
number (angel numbers path) | String | "1111", "777", "1234" | 1111 (int) fails path validation |
id (nakshatra / dream / tarot) | Slug | "ashwini", "flying", "the-fool", "three-of-cups" | Display names, uppercase, spaces |
houseSystem | Enum | "placidus" (default), "whole-sign", "equal", "koch" | "Placidus", "whole_sign", "WS" |
ayanamsa (KP) | Enum | "kp-newcomb" (default), "kp-old", "lahiri", "custom" | "KP", "New Comb", "Lahiri" |
nodeType (KP) | Enum | "mean" (default, traditional Vedic), "true" (osculating with perturbation corrections) | "true-node", "mean-node", "True Node" |
count (tarot draw) | Integer 1 to 78 | 3, 10, 78 | 0, 79, strings, floats |
mahadasha (path) | Planet name | "Ketu", "Venus", "Sun", "Moon", "Mars", "Rahu", "Jupiter", "Saturn", "Mercury" | "KETU" (works, case-insensitive), "ke", "Ke-tu" |
person1 / person2 | Object with full birth data | { date, time, latitude, longitude, timezone } (Western) or { date, time, latitude, longitude } (Vedic) | Separate top-level fields, missing time, partial object |
question (tarot / iching) | Optional string | "Should I accept the job offer?", "What should I focus on this week?" | Leave undefined for general reading. More specific = better interpretation. |
year / month / day (numerology) | Integer | 1990, 1, 15 | Zero-padded strings "01", decimals, full dates |
Timezone cheat sheet (most-asked locations)
| Region | Decimal | Region | Decimal |
| UTC / London (winter) | 0 | Dubai | 4 |
| London (summer, BST) | 1 | Karachi | 5 |
| Berlin / Paris | 1 (winter) / 2 (summer) | Delhi (IST) | 5.5 |
| Istanbul | 3 | Kathmandu (NPT) | 5.75 |
| Moscow | 3 | Dhaka | 6 |
| Tehran | 3.5 (winter) / 4.5 (summer) | Bangkok | 7 |
| Adelaide | 9.5 (winter) / 10.5 (summer) | Singapore / Beijing | 8 |
| New York (EST / EDT) | -5 / -4 | Tokyo | 9 |
| Chicago (CST / CDT) | -6 / -5 | Sydney | 10 (winter) / 11 (summer) |
| Denver (MST / MDT) | -7 / -6 | Auckland | 12 (winter) / 13 (summer) |
| Los Angeles (PST / PDT) | -8 / -7 | Honolulu | -10 |
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.
Astrology domain gotchas for LLMs
LLMs hallucinate confidently in this category. These are the specific traps you will hit when writing client code:
- Ayanamsa is server-side in Vedic. LLMs default to tropical / Western math. Vedic endpoints apply sidereal Lahiri ayanamsa server-side. KP endpoints accept
ayanamsaofkp-newcomb(default),kp-old,lahiri, orcustom. Do not try to "correct" server output by subtracting ayanamsa in client code. - Tithi count is 30, not 2. 15 Shukla (waxing) plus 15 Krishna (waning). Older LLM training data conflates Purnima and Amavasya as single tithis. Our panchang response carries a
pakshafield ("Shukla"or"Krishna") plus a tithi number, so there are 30 distinct tithis in a lunar month. - Rahu and Ketu are shadow points, not planets. They do not appear in a real ephemeris. Endpoints accept
nodeTypeof"mean"(smooth mean node, traditional Vedic default) or"true"(osculating node with perturbation corrections) to select which calculation to use. - Nakshatra count is 27. Abhijit is sometimes treated as a 28th in some schools, but this API uses the standard 27.
roxy.vedicAstrology.listNakshatras()returns an array of length 27. - Retrograde is per-planet, not global. Natal chart planets and Vedic
metaincludeisRetrograde: booleanper planet. KP planet lists useretrograde. Never generate "Mercury retrograde globally" UI copy, check the specific planet in the response. - Tarot reversals are a product choice.
allowReversals: falseon a tarot draw means no reversed cards in that draw, period. It is not cosmically meaningful, it is a config flag. - Angel number lookup works for any positive integer. Digit-root fallback covers non-canonical numbers. Do not generate validation logic that rejects anything other than
111/222/333. - Seed-based daily endpoints are DETERMINISTIC per
(seed, date)pair. Same seed plus same date returns the same reading. This is by design for push-notification consistency. Do not describe it as "cached" or retry on stale responses. - Timezone affects Western calculations more than Vedic. Western natal charts must respect DST at the time of birth. Vedic endpoints default to IST (
5.5) which is DST-free. Pass the IANAtimezonestring from the location lookup ("America/New_York","Asia/Kolkata") directly to chart calls and the server resolves the DST-correct offset for the chartdate. Never pass theutcOffsetof the city record (the offset in force today) or the clock of the user right now.
Error handling
On a failure error is { error, code, doc_url }. The error field is human-readable (may change wording). The code field is machine-readable (stable, switch on this). The HTTP status and the Retry-After header are on response; retryAfterSeconds(response) reads the wait in seconds. A network failure (DNS, timeout, connection reset) is not an API error: the call throws fetch failed, so use try/catch where that matters.
const { data, error, response } = await roxy.astrology.getDailyHoroscope({
path: { sign: 'aries' },
});
if (error) {
console.error('Status:', response?.status, 'Code:', error.code, 'Message:', error.error);
return;
}
console.log(data.sign, data.overview);<!-- BEGIN:ERRORS -->Every error returns { error, code, doc_url }. Switch on code; error is readable text and may change. Each meaning below says whether and when to retry, and Retry-After carries the wait when the response sends it. Every code is documented at https://roxyapi.com/docs/errors.
| Status | Code | Meaning |
| 400 | validation_error | A field is missing or invalid. The body lists every failing field at once in issues, each with its path and the expected shape. |
| 400 | bad_request | The request was rejected as a whole, for example a body that is not valid JSON or a date range that ends before it starts. |
| 400 | date_out_of_range | A date lies outside the span the planetary positions are served for. The error names the supported dates. |
| 400 | invalid_branding | The report branding cannot be used, for example a logo that is not a PNG, JPEG, WebP or SVG image. |
| 400 | logo_fetch_failed | The report logo could not be fetched: it must be an HTTPS URL on a public host that answers within the size limit. |
| 400 | unsupported_character | The report text holds a character no report font draws. The error names it: remove or replace it. |
| 401 | api_key_required | No API key was sent. |
| 401 | invalid_api_key | The key sent is malformed or cannot be verified. |
| 401 | api_key_revoked | The key was valid once and has since been revoked from the account page. |
| 401 | subscription_not_found | The key verifies, but the subscription behind it no longer exists. |
| 401 | subscription_inactive | The subscription behind the key is cancelled, expired or suspended, or a trial is past its end date. |
| 401 | publishable_key_not_allowed_on_mcp | A publishable key was used on a Remote MCP server, which takes a secret key. |
| 401 | invalid_client_ip | A keyless request could not be attributed to a caller. |
| 401 | unauthorized | Authentication failed with no more specific reason to give. |
| 403 | forbidden | The key is valid, but this request is not permitted. |
| 403 | origin_required | A publishable key with an origin allowlist was used with no Origin header, as from a server or a native app. |
| 403 | origin_not_allowed | The calling site is not on the origin allowlist of this publishable key. |
| 404 | not_found | Nothing is served at this path, or the identifier in it does not exist. A path miss adds suggestions, the closest real endpoints. |
| 405 | method_not_allowed | The path exists for a different HTTP method. The body lists the accepted methods in allow, as does the Allow header. |
| 409 | conflict | The request cannot be applied in the current state. |
| 410 | gone | The path was removed permanently. |
| 413 | payload_too_large | The request body is larger than the API accepts. A body far over the cap is refused before it reaches the API and returns a bare 413 with no JSON body. |
| 415 | unsupported_media_type | A request with a body was sent without Content-Type: application/json. |
| 422 | unprocessable_entity | Every field is valid, but the combination cannot be computed. |
| 429 | rate_limit_exceeded | The monthly request allowance is used up. Retry-After gives the seconds to the reset. |
| 429 | rate_limit_per_minute | The per-minute limit of the plan was reached. Retry-After gives the seconds to the next minute, and the monthly allowance is not charged. |
| 429 | rate_limited | A rate limit was reached, reported without the plan detail. |
| 429 | free_tier_exhausted | A keyless request has used up its trial allowance. |
| 429 | reports_rate_limited | Too many reports were requested this minute. Retry-After gives the seconds to the next minute. |
| 500 | internal_error | The request failed inside our service. Retry with exponential backoff. |
| 503 | compute_saturated | Heavy calculations are briefly at capacity. Send the same request again after Retry-After seconds. |
| 503 | reports_busy | Report rendering is briefly at capacity. Send the same request again after Retry-After seconds. |
| 503 | report_render_timeout | The report took too long to render. Send the same request again. |
| Any | error | A fallback for a status with no more specific code. The status and the error field carry the signal. |
<!-- END:ERRORS -->Retries
Retries are on by default: a request is resent up to twice after a 429, 500, 502, 503 or 504, or after a connection that was never made (refused or unresolvable host). Pass maxRetries to change the count, or maxRetries: 0 to turn retries off. A read timeout is never retried. The wait follows Retry-After when the response sends it, and a full-jitter backoff otherwise (initialDelayMs 500, maxDelayMs 30000 by default). A Retry-After longer than maxDelayMs, such as the wait for a monthly allowance, is not waited for: the error comes back at once. An abort signal on the call stops any wait. On a persistent failure the total is 1 + maxRetries requests, so 3 by default and exactly 1 with maxRetries: 0.
import { createRoxy, ErrorCodes, retryAfterSeconds } from '@roxyapi/sdk';
const roxy = createRoxy(process.env.ROXY_API_KEY!, { maxRetries: 4 });
const { data, error, response } = await roxy.astrology.getDailyHoroscope({
path: { sign: 'aries' },
});
if (error) {
if (error.code === ErrorCodes.RateLimitPerMinute || error.code === ErrorCodes.ComputeSaturated) {
console.warn('retry in', retryAfterSeconds(response), 'seconds');
} else {
console.error(response?.status, error.code, error.doc_url);
}
}ErrorCodes holds every code as a typed constant (ErrorCodes.RateLimitPerMinute is 'rate_limit_per_minute'), and the ErrorCode type accepts codes added later. retryAfterSeconds(response) returns the Retry-After wait in seconds, or undefined when the response has none.
MCP equivalents
Every method has a matching MCP tool. The remote MCP server per domain is at https://roxyapi.com/mcp/{domain} (Streamable HTTP, no stdio / no self-hosting). Tool names follow {method}_{path_snake_case}, for example:
POST /astrology/natal-chart->post_astrology_natal_charton/mcp/astrologyGET /astrology/horoscope/{sign}/daily->get_astrology_horoscope_sign_dailyon/mcp/astrologyPOST /vedic-astrology/birth-chart->post_vedic_astrology_birth_charton/mcp/vedic-astrologyPOST /tarot/spreads/celtic-cross->post_tarot_spreads_celtic_crosson/mcp/tarot
Use the SDK for typed TypeScript apps. Use MCP for AI agents (Claude Desktop, Cursor MCP, OpenAI agents) where the agent selects tools based on user intent.
Gotchas
- Geocode first. Any chart, panchang, synastry, compatibility, or natal endpoint needs coordinates. Call
roxy.location.searchCitiesbefore the chart method. - Parameters are objects, not positional. Always
{ path: {...} },{ body: {...} }, or{ query: {...} }. - Do not guess method names. Type
roxy.domain.and let autocomplete show them. Method names come fromoperationIdin the OpenAPI spec, not URL paths. - Do not use raw
fetch. The SDK handles auth, base URL, and typed responses. - Do not expose API keys client-side. Call Roxy from server code only.
- Date format is
YYYY-MM-DD, time isHH:MM:SS. Both are strings. - Western
timezoneis required and accepts either a decimal (-5for EST,5.5for IST,0for UTC) or an IANA string ("America/New_York","Asia/Kolkata","UTC"). IANA is resolved to the DST-correct offset for the requestdate. Vedic endpoints accept an optionaltimezonethat defaults to5.5(IST). dataanderrorare mutually exclusive. Iferroris set,dataisundefinedand vice versa.- Switch on
error.code, noterror.error. The message may change; the code is stable. - A city record has
city,province,country,iso2,latitude,longitude,timezone,utcOffsetandpopulation. The name iscity, nevername. utcOffseton a city record is the offset in force today. Pass the IANAtimezonestring to chart calls so the server resolves the offset for the birth date.- A natal chart
planetsis a list of objects. Find a body byname:chart.planets.find((p) => p.name === 'Moon'). - In a Vedic chart
meta.Moon.rashiis a string andmeta.Moon.nakshatrais an object (name,pada,lord). Displaymeta.Moon?.nakshatra.name. - A
validation_errorcarriesissues, each withpath(the dot-separated field, such astimeorperson1.date),messageandcode. Loop over them to show every failing field:if (error && 'issues' in error) { for (const issue of error.issues) console.error(issue.path, issue.message, issue.code); } signis matched case-insensitively. Lowercase is canonical.- Network failures throw. DNS, timeout and connection reset surface as a thrown
fetch failed, not aserror; wrap calls intry/catch. - Total requests on a persistent failure = 1 + retries. The default
maxRetriesof 2 makes 3 requests;maxRetries: 0makes exactly one. - List endpoints return a paginated envelope,
{ total, limit, offset }plus a named array (cities,crystals,hexagrams,symbols), never a bare array. Passquery: { limit }to widen a page;listHexagramsdefaults to 20 of 64.
Links
- Full method reference:
docs/llms-full.txt(bundled in this package) - Documentation: https://roxyapi.com/docs
- Interactive API docs: https://roxyapi.com/api-reference
- Pricing and API keys: https://roxyapi.com/pricing
- MCP for AI agents: https://roxyapi.com/docs/mcp
- Templates: https://roxyapi.com/templates
- Source and issues: https://github.com/RoxyAPI/sdk-typescript
- Other SDKs: Python https://pypi.org/project/roxy-sdk/, PHP https://packagist.org/packages/roxyapi/sdk, .NET https://www.nuget.org/packages/RoxyApi.Sdk, Go https://pkg.go.dev/github.com/RoxyAPI/sdk-go, Rust https://crates.io/crates/roxyapi
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

