AI Astrology Chat Endpoint: Why We Do Not Ship One

23 min read
Brett Calloway
astrologyAI AgentsRemote MCPBring Your Own LLM

A bundled AI astrology chat endpoint saves an hour of glue code and takes your system prompt, your model choice, your user memory and your margin.

TL;DR

  • RoxyAPI has no natural language chat query endpoint, and it is never going to have one. That is a declared architectural position, not a roadmap gap.
  • A vendor that runs the model inside its own endpoint owns four things that are supposed to be yours: the system prompt, the model, the user memory and personalization layer, and the per-query margin.
  • The alternative is Remote MCP: one entry in the tools array of the Anthropic, OpenAI and Google APIs. No install, no local stdio process, nothing to supervise. In our MIT template, switching between all three is one environment variable.
  • Bring your own model, pay the model vendor directly at list price, and keep every byte of end-user data inside your own stack. Start at Remote MCP docs.

There is a category of astrology API that sells one seductive endpoint: post birth data plus a question, get back a paragraph of interpretation. One call, no LLM plumbing, ship by Friday. It is the most expensive convenience in this market, and the invoice is the smallest part of the price. What you actually pay is control, in the four places that decide whether an insight app keeps users past week two. This is the due-diligence version of that trade, written by the vendor that refuses to sell you the endpoint. Every number below was captured live against production, and every line of code is copied out of a repository you can clone.

Does a bundled AI chat endpoint actually save you any time?

Barely. It removes the glue code between a model and a tool call, which is a few minutes to an hour at best, and it shrinks every quarter because every major model vendor now speaks Remote MCP natively. In exchange it takes four things permanently. That is not a shortcut, it is a mortgage.

Here is the hour it saves, itemized honestly:

Work a bundled endpoint removes for youWhat that work actually is today
Connecting the model to the dataOne object in the tools array. Anthropic, OpenAI and Google all accept a remote MCP server directly
Writing tool definitionsNone. The server publishes them and the model reads them. A keyless tools/list returned 38 tools for astrology alone
Running the tool-call loopThe SDK does it. In our MIT template it is one streamText call with a step limit
Writing the first system promptCopy the one in the template. It is 60 lines and already handles ambiguous dates, IANA timezones and language detection

Now what it takes, and none of it comes back. The first four decide whether the product survives:

What you hand overWith a bundled chat endpointWith structured data plus your own model
Voice and system promptTheirs. Hidden, unversioned, untestable. No guardrails you can add, no disclaimer you can insert, no way to stop it saying something you would never sayYours. Persona, tone, guardrails, refusal rules, reading level, response length, disclaimers
User memory and personalizationTheir conversation store, their schema, their retention, their outage. This is your retention curve, parked in infrastructure you do not runYour database, your embeddings, your user profile. The one part of the product that compounds
CostTheir per-query price, marked up over the model they call on your behalfModel list price, paid direct to the model vendor, with the calculation cached
Model portabilityWhatever model they picked, swapped on their schedule, with no changelog you controlAny model, switched with one environment variable, including a local one
Data jurisdictionTheir LLM subprocessor, chosen for you, possibly unnamedYour model vendor, in your DPA, under your terms
Language coverageA line in a prompt you cannot read, counted as a feature10+ reviewed locales on the calculation itself, plus whatever your model speaks

You are being asked to trade all six for an hour of integration work the model vendors have already automated.

On the cost row specifically: their unit is an AI query, yours is a user session, and an agent that chains four tool calls to answer one question spends four units. Deterministic calculations also cache and generated prose does not, so a repeat natal chart came back from us with x-cache: HIT while a chat endpoint bills again every time a user re-reads the same reading. The full markup arithmetic against published model token prices is in AI astrology API vs calculation infrastructure. This post is about what money cannot buy back.

Ready to keep all six? The Astrology API returns structured, typed JSON across 209+ endpoints and 14 insight domains on one key. See pricing.

How does an AI astrology chatbot actually work?

Three moving parts, and none of them are astrology-specific. An MCP client that fetches tool definitions once and caches them, a system prompt you own, and one streaming call that runs the tool loop until the model has what it needs. Everything below is copied from our MIT template at Templates, running on Next.js and the Vercel-maintained AI SDK (npm i ai, over 20M weekly downloads as of August 2026). That package is why switching models is no longer a project: one surface, one tool set, and every major provider behind the same call.

Step 1. Mount the servers. Tools from every server you connect merge into one set the model picks from. Mount location beside the domain server, because every chart tool needs latitude, longitude and an IANA timezone, and without it the user has to type coordinates by hand.

import { createMCPClient } from "@ai-sdk/mcp";

const client = await createMCPClient({
  transport: {
    type: "http",
    url: "https://roxyapi.com/mcp/astrology", // and /mcp/location, /mcp/tarot, ...
    headers: { Authorization: `Bearer ${process.env.ROXYAPI_KEY}` },
  },
});
const tools = await client.tools(); // fetched once, cached for the process lifetime

Step 2. Own the prompt. This is the artifact a bundled endpoint hides from you. Excerpted from src/lib/prompts.ts:

You are a warm, knowledgeable spiritual advisor powered by RoxyAPI.

PERSONALITY:
- Warm but direct. Not overly mystical or vague.
- Always ground interpretations in the actual data from tool results.

LOCATION FIRST, CHART SECOND (mandatory for every chart tool):
1. Call the location search tool with the nearest well-known city.
2. Read latitude, longitude, and timezone from the first returned city.
3. Call the chart tool and ALWAYS include timezone as that exact IANA string.

Ambiguous numeric dates: when both the day and the month could be 1-12,
do NOT guess the order. Ask once, naming both readings, then proceed.

MULTILINGUAL: detect the language of the incoming message and reply in it.

RESPONSE STYLE: never dump raw JSON. Interpret, explain, stay concise.

Sixty lines, every rule learned from a real failure. You can read it, version it, run evals against it, add your own guardrails and disclaimers, and rewrite one line at two in the morning when a user complains. None of that is possible with a prompt you cannot see, which is the part that matters most in a category where the model is writing about health, money and relationships under your brand.

Step 3. Run the loop. The whole handler, minus validation and rate limiting:

const result = streamText({
  model: getModel(),
  system: getSystemPrompt(),
  messages: await convertToModelMessages(messages),
  tools,
  stopWhen: stepCountIs(5), // cap the tool round-trips per message
});

return result.toUIMessageStreamResponse();

Step 4. Switch the provider. Same prompt, same servers, same tools, three vendors:

// LLM_PROVIDER = gemini | anthropic | openai
export function getModel() {
  switch (provider) {
    case "anthropic": return anthropic("claude-haiku-4-5-20251001");
    case "openai":    return openai("gpt-5-mini");
    case "gemini":
    default:          return google("gemini-2.5-flash");
  }
}

One environment variable. Nothing else moves: not the prompt, not the tools, not the memory schema, not the rendering.

What one message actually does

A user types "Read my chart. 15 July 1990, 14:30, New York." The model then, unprompted by any routing code you wrote:

  1. Calls the location search tool with New York, because the system prompt tells it to resolve a place before any chart call.
  2. Reads back latitude 40.7143, longitude -74.006, timezone America/New_York.
  3. Calls post_astrology_natal_chart with those three plus the date and time.
  4. Receives typed JSON: planets with longitude, sign, degree, speed and retrograde state, house cusps, aspects.
  5. Writes the reading in your voice, in the language the user wrote in.

Five steps, capped by stopWhen. You paid your model vendor for the thinking, you paid us two quota units for the two calculations, and nobody took a cut of the sentence at the end.

Or skip the SDK and call one provider directly

If you have already committed to a single model vendor and want nothing between you and their API, call the same two servers from their native surface. You give up the one-line provider swap and you gain total control of the request: every parameter, every beta flag, every streaming detail, and no dependency in the path.

# Messages API MCP connector, beta flag mcp-client-2025-11-20
client.beta.messages.create(
    model="claude-opus-5",
    max_tokens=4096,
    betas=["mcp-client-2025-11-20"],
    system=SYSTEM_PROMPT,
    mcp_servers=[
        {"type": "url", "url": "https://roxyapi.com/mcp/astrology",
         "name": "roxy-astrology", "authorization_token": ROXY_API_KEY},
        {"type": "url", "url": "https://roxyapi.com/mcp/location",
         "name": "roxy-location", "authorization_token": ROXY_API_KEY},
    ],
    tools=[
        {"type": "mcp_toolset", "mcp_server_name": "roxy-astrology"},
        {"type": "mcp_toolset", "mcp_server_name": "roxy-location"},
    ],
    messages=[{"role": "user", "content": "Read my chart. 15 July 1990, 14:30, New York."}],
)

Tool discovery is keyless, so inspect the surface before you pay. A tools/list call against /mcp/astrology returned 38 tools with no credential attached, and the fourteen domain servers return 206 between them. Pass compact: true on any tool call for a lossless token-optimized response: the natal chart result dropped from 41,359 characters to 27,184, about 34 percent smaller, which is inference cost your agent stops paying every turn.

Wiring the integration with a coding agent rather than at runtime? Point GitHub Copilot, Claude Code or Cursor at the keyless docs server at /mcp/docs instead: it returns documentation and field contracts so the agent writes correct code, and never burns quota on a calculation nobody reads. Every client config is in the Remote MCP guide.

Do not let a landing page do your evaluation

A rotating 3D solar system on a homepage proves that somebody bought a WebGL template. It says nothing about whether the ephemeris behind it is correct, whether the advertised endpoints exist, or whether the numbers on the pricing page are real. In 2026 the cheapest thing in software is a convincing surface, and the gap between a generated landing page and shipped code has never been wider.

Every row below is a five-minute check that replaces a claim you cannot verify:

The signal you are shownWhat it actually provesThe check that replaces it
Animated sky, drifting particles, glassmorphism, a generated hero illustrationSomebody bought or generated a front-end templateFetch /openapi.json. If it 404s there is no machine-readable contract to audit, and every number on the site is unfalsifiable
A percentage accuracy score, or a count of internal validation layersNothing. Self-graded against a self-defined suite, usually behind authAsk for a re-runnable benchmark against a named external reference. Ours is MIT licensed: 210 planet positions across 21 charts against NASA JPL Horizons
A large endpoint or operation count in the heroA number typed into a headingFetch the live spec and count the entries under .paths yourself. A spec generated from production cannot disagree with the product
A free playground that answers instantly with no keyPossibly a sample response, not arithmeticRead the response metadata first. A mode, sample or fixture flag means the input was never used. Then send two different birth dates and diff the numbers
A named system, tradition or domain on the feature listThat the words exist on their websiteSearch the spec for it. A domain sold on the pricing page with zero matching paths is the cheapest claim in this category to falsify
A proprietary, first-party or purpose-built model behind the chat endpointUsually a system prompt and a routerAsk which models it actually calls, and read their own benchmark charts for a third-party model name. A reseller with a hidden prompt is not a first-party model, and you are paying a markup to lose prompt control over models you could call yourself
A large language countOften one line in a system prompt, applied to one endpoint familyCollect every distinct lang enum the spec declares, then ask which endpoints carry it
Any headline number at allOnly that it was typed onceRead the same claim on the homepage, the pricing page and the docs. A vendor whose endpoint count or language count disagrees with itself across three of its own pages will not agree with its spec either
Named testimonials from named companiesNothing until you find the companySearch the company and the job title. Unfindable is a data point

Two tests a sample response cannot pass

One: cast something twice. A divination endpoint that draws has to vary, and a good one also has to repeat on demand. Four unseeded GET /iching/cast calls against production returned hexagrams 8, 26, 45 and 25. The same endpoint with ?seed=roxy-demo returned hexagram 40 three times running. A canned response fails both halves at once: it repeats when it should vary, and it ignores the seed when it should honour it. Reproducible readings are a documented parameter, not an accident, which is the difference between determinism and a fixture.

Two: move the clock by one minute. The Ascendant is the fastest-moving number in a chart, so a real engine has to move it and a sample cannot. Measured live against production, same place, same date:

Birth timeAscendant longitude
14:30:00216.947067
14:31:00217.143075

That is 0.196 degrees, about 706 arcseconds, from sixty seconds of clock. It is also why seconds are load-bearing on any endpoint returning an Ascendant or a house cusp, and why a provider that silently rounds birth time to the minute has decided on your behalf that house cusps do not matter. Run the same two calls against anyone and compare.

None of this is hostile, and we expect it to be pointed at us. It is why the spec is generated from production rather than hand-written, why the playground runs real calls with no signup and no key, why the benchmark is public and MIT licensed, and why every deploy runs 8,000+ automated tests with 1,900+ of them pinned to named external references. Verification is cheap when the thing being verified is real.

Who is in the request path when a vendor runs the model for you?

Someone you did not choose. A hosted chat endpoint takes your users birth date, birth time and birth place, which is personal data under GDPR, and forwards it to a model provider that is a subprocessor of your vendor and therefore a subprocessor of yours. You inherit that chain without selecting a single link in it.

Ask the vendor these, in writing, before you integrate:

  • Which model provider processes the request, in which country, named in a dated subprocessor register you can read before you pay
  • Whether prompts and completions are retained, for how long, and whether they are used to train anything
  • Whether Article 28(2) prior authorization exists for a change of model provider, or whether they can switch silently
  • What you are supposed to write in your own privacy policy about a subprocessor you cannot name

RoxyAPI is stateless by design. We hold no conversation, no journal, no profile and no end-user account. A calculation request goes in, structured JSON comes out, nothing about the user persists. The privacy policy states the country and the city rather than a region, and the DPA plus a dated subprocessor register are published free on every plan rather than gated behind a sales thread. When you bring your own model, that vendor sits in your own contract rather than hidden inside a stack you cannot inspect.

Why is memory and personalization your moat rather than theirs?

Because it is the only part of an insight app that compounds. Calculations are deterministic and identical everywhere: the same birth moment yields the same chart from every correct engine on earth. What makes a user open your app on day 90 is that it remembers the transit it flagged on day 12, learned that they skim the career section, and speaks in a voice they now recognize.

Hand that to a vendor and you have outsourced your retention curve: their conversation store, their schema, their export format, their outage. You cannot run an eval harness on a prompt you cannot read, you cannot A and B test a persona you do not control, and you cannot reproduce a support ticket that says the app told me something wrong, because the same input does not return the same output and the model version is not yours to pin.

Build the memory layer yourself on day one. It is a table and an embedding index, it is genuinely yours, and it is the thing a competitor cannot copy. We ship the pattern rather than the storage: the chatbot above is MIT licensed, clones in minutes, and leaves the memory exactly where it belongs, in your code.

Fifteen due-diligence questions for any vendor selling an AI query endpoint

Run these against any provider, including us. They are answerable in an afternoon, and a vendor that cannot answer them has told you something.

#QuestionWhy it decides the build
1Can I read the system prompt?If no, you cannot evaluate, guardrail, or brand the voice your users hear
2Can I change the model?If no, your product quality moves on their procurement schedule
3Which model runs it, and is it named in a dated subprocessor register?An unnamed subprocessor cannot be written into your own privacy policy
4Are my prompts and completions used for training?A chat endpoint is the exact surface where this matters most
5Is the output reproducible?Same input, different output means every support ticket is unfalsifiable
6Can the response be cached?Generated prose cannot, so you re-buy the same reading forever
7What is the billing unit, and what happens when it runs out?Per-AI-query pricing punishes exactly the agent chaining you want, and a wallet that empties mid-month returns a payment error to your users unless there is a documented overage path
8What is the added latency?Model inference in the data path makes your chart endpoint as slow as their slowest turn
9Can I run evals against it?No prompt access means no quality baseline and no regression alarm
10Who is liable for what it says?It writes health, money and relationship advice under your brand, not theirs
11What is the exit cost?Building on their prose means rewriting your interpretation layer to leave
12Do the raw numbers ship too, or only the paragraph?If only prose, every visual feature on your roadmap is impossible
13Does the spec declare response schemas, or only paths?A path list is an inventory, not a contract. With no declared 200 schema, no typed SDK can be generated from it and every field name you code against is a guess
14Which models does the proprietary model actually run on?If the answer is a router over frontier models, the differentiator was the markup
15What engine performs the calculations, and under what licence?A chat endpoint hides the whole stack behind a paragraph. If the maths runs on a copyleft library, the network-service clause can reach your codebase, and you cannot audit what you were never shown

Question 15 has a short answer in our case, and it belongs in the open: calculations run on Roxy Ephemeris, our own engine, verified against NASA JPL Horizons and carrying no AGPL anywhere in the request path. The method, the tolerances and the reference set are on /methodology, and the benchmark is a public MIT repo you can re-run rather than a number you have to believe.

Question 13 is the one almost nobody runs, and it is decisive. A spec can list hundreds of paths and declare a response schema for none of them, which reads as breadth in a marketing table and gives an integrating developer nothing: no types, no autocomplete, no generated SDK, no way to know what comes back without paying and probing. Ours declares them, which is why six typed SDKs regenerate from it automatically.

Question 12 is the quiet one. A vendor that returns only interpretation has made a chart wheel, a dasha table and a bodygraph undrawable. Our responses return the positions, the houses, the aspects and the interpretations, all typed, so you can render a wheel with the drop-in UI components at /ui and hand the same JSON to a model.

When a bundled chat endpoint is the right call

There is one, and it deserves saying plainly. If you are building a throwaway demo, a hackathon entry, or an internal tool with under a hundred users and no retention goal, a bundled endpoint is genuinely faster and the markup at that volume is rounding error. Take it. The trade only turns bad when the product is meant to last, because that is when a locked prompt, a fixed model and a memory store you do not own become the ceiling you cannot raise.

FAQ

Does RoxyAPI have an AI chat or natural language query endpoint? No, and it is a deliberate design decision rather than a missing feature. RoxyAPI returns verified structured calculations and lets you run any model over them through Remote MCP or function calling. You keep the system prompt, the guardrails, the model choice and the conversation memory, which are the things that decide whether users come back.

How does an AI astrology chatbot work without an AI astrology API? The model does the talking and an MCP server does the maths. Connect a RoxyAPI Remote MCP server to Claude, GPT or Gemini, pass your own system prompt, and the model resolves the birthplace, calls the chart tool, reads typed JSON back and writes the reading in your voice. Our MIT template does this in one streamText call.

Is Remote MCP different from a local MCP server? Yes, and the difference is operational. A local or stdio MCP server is a process you install, supervise and update on every machine running an agent. RoxyAPI Remote MCP is Streamable HTTP at a public URL, so a hosted agent, a serverless function or a no-code platform calls it directly with an API key and no installation at all.

Can I switch LLM providers without rewriting my astrology integration? Yes. The server, the tools, the field names and the JSON are identical no matter which model calls them, so switching vendors is one environment variable in our template and one tools object on the raw APIs. Prompts, memory schema and rendering code are untouched, which is exactly what a bundled chat endpoint takes away.

How do I tell whether an astrology API is real or just a good landing page? Two calls settle it. Send the same birth data twice with the times one minute apart: a real engine moves the Ascendant about two tenths of a degree, a canned response returns identical numbers. Then cast an I Ching hexagram or draw a tarot card twice with no seed: real ones vary, samples repeat. Also fetch the OpenAPI spec and check it declares response schemas rather than just listing paths.

Does RoxyAPI store my users birth data? No. RoxyAPI is stateless: a request goes in, structured JSON comes out, and no birth data, conversation, profile or journal is retained. Servers, database and cache are in Nuremberg, Germany, the DPA and the dated subprocessor register are published free on every plan, and no model provider sits in the request path that you did not choose yourself.

Conclusion

The endpoint that writes the paragraph for you also decides what your product sounds like, what it remembers, what it costs and who processes your users data. We do not sell it because those are not our decisions to make. Take the verified numbers from the Astrology API, point Remote MCP at whatever model you want, and keep the layer that actually retains users. Every domain, endpoint and MCP server sits in one flat subscription: see pricing.