How to Add Daily Horoscopes to Your App (5-Minute Guide)
Daily horoscopes are one of the most engaging features you can add to a wellness, lifestyle, or social app — and with a daily horoscope API, you can integrate them in minutes. This guide walks through everything you need: getting an API key, calling the horoscope endpoint with curl and JavaScript, using the SDK, scheduling automated fetches, rendering a React widget, and handling errors gracefully.
Why Use a Horoscope API?
Building horoscope content in-house is a maintenance burden. You would need to generate or license daily text, keep it fresh for all twelve zodiac signs, and structure it consistently. A dedicated horoscope API integration abstracts all of that away: one request returns a complete reading with mood, energy ratings, lucky numbers, and actionable advice, fully typed and ready to render.
GitStrology’s horoscope endpoint costs just 1 credit per call. The free tier includes 100 credits per month with no credit card required, which covers 100 daily horoscope requests — enough to prototype, test, and even serve a small early user base. For production scale, the Pro plan offers 10,000 credits for $19/month.
Step 1: Get Your API Key
Sign up for a free GitStrology account and generate an API key from the dashboard. Keys follow the format gs_live_ followed by a hex string, and the full key is shown only once at creation — copy it immediately and store it in an environment variable.
If you have never used the platform before, start with the quickstart guide, which covers account setup, key management, and your first request end to end. You can also review authentication best practices for guidance on key rotation and environment separation.
# .env.local GITSTROLOGY_API_KEY=gs_live_your_key_here
Never hardcode your key in source files or commit it to version control. The SDK reads from the GITSTROLOGY_API_KEY environment variable automatically.
Step 2: Make Your First Request with curl
The horoscope endpoint is a simple POST to /v1/horoscope. Pass a zodiac sign in the body, optionally with a date (defaults to today in UTC):
curl -X POST https://api.gitstrology.dev/v1/horoscope \
-H "X-API-Key: gs_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"sign":"aries"}'The response includes a rich daily reading plus your updated credit balance in the envelope:
{
"data": {
"date": "2026-08-03",
"sign": "aries",
"mood": "ambitious",
"energy": 4,
"luck": 3,
"love": 5,
"career": 4,
"summary": "Mars energy surges today. A bold move pays off.",
"advice": "Channel your fire into one decisive action.",
"luckyNumber": 42,
"luckyColor": "gold"
},
"credits": { "used": 1, "remaining": 99 }
}Each rating (energy, luck, love,career) is an integer from 1 to 5. The credits envelope lets you monitor usage and implement graceful degradation when you approach your limit. See the horoscope endpoint docs for the full field reference.
Step 3: Call the API with JavaScript fetch
For a plain fetch integration — useful if you are not using the SDK or are working in a non-TypeScript environment — here is a clean, typed helper:
type Horoscope = {
date: string;
sign: string;
mood: string;
energy: number;
luck: number;
love: number;
career: number;
summary: string;
advice: string;
luckyNumber: number;
luckyColor: string;
};
async function getHoroscope(sign: string, date?: string): Promise<Horoscope> {
const res = await fetch("https://api.gitstrology.dev/v1/horoscope", {
method: "POST",
headers: {
"X-API-Key": process.env.GITSTROLOGY_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({ sign, date }),
});
if (!res.ok) {
const error = await res.json().catch(() => ({}));
throw new Error(error.message || `HTTP ${res.status}`);
}
const json = await res.json();
return json.data as Horoscope;
}
// Usage
const horoscope = await getHoroscope("leo");
console.log(horoscope.summary);
console.log(`Lucky number: ${horoscope.luckyNumber}`);Always call the API server-side — never expose your API key in client-side JavaScript. In a Next.js App Router project, put this helper in a server component or a Route Handler.
Step 4: Use the Official SDK
The GitStrology TypeScript SDK handles authentication, JSON serialization, response parsing, and error normalization for you. Install it and initialize a client:
npm install gitstrology
// lib/gitstrology.ts
import { Gitstrology } from "gitstrology";
export const gs = new Gitstrology({
apiKey: process.env.GITSTROLOGY_API_KEY,
});import { gs } from "@/lib/gitstrology";
const horoscope = await gs.horoscope({ sign: "aries" });
console.log(horoscope.data.mood); // "ambitious"
console.log(horoscope.data.energy); // 4
console.log(horoscope.data.luckyColor); // "gold"
console.log(horoscope.credits.remaining); // 99The SDK is fully typed, so your editor will autocomplete every field and flag invalid signs at compile time. This is the recommended approach for any TypeScript or JavaScript project.
Step 5: Schedule Horoscopes with a Cron Job
Many apps want fresh horoscopes delivered automatically each morning. Using node-cron, you can fetch all twelve signs on a schedule and cache the results, minimizing credit usage and keeping response times fast for end users:
import cron from "node-cron";
import { gs } from "./lib/gitstrology";
const SIGNS = [
"aries", "taurus", "gemini", "cancer", "leo", "virgo",
"libra", "scorpio", "sagittarius", "capricorn", "aquarius", "pisces",
] as const;
// Cache layer (use Redis in production)
const cache = new Map<string, unknown>();
async function refreshDailyHoroscopes() {
const today = new Date().toISOString().slice(0, 10);
console.log(`Refreshing horoscopes for ${today}`);
for (const sign of SIGNS) {
try {
const result = await gs.horoscope({ sign, date: today });
cache.set(`horoscope:${sign}:${today}`, result.data);
} catch (err) {
console.error(`Failed for ${sign}:`, err);
}
}
console.log("All horoscopes refreshed. Total credits used: 12");
}
// Run at 6:00 AM UTC every day
cron.schedule("0 6 * * *", refreshDailyHoroscopes);
// Initial fetch on startup
refreshDailyHoroscopes();Fetching all twelve signs costs 12 credits per day (360/month), which fits comfortably within the Pro tier. By caching results, you serve unlimited reads from your database or cache layer without consuming additional API credits. For more on scheduling and automation, see the rate limits and credits documentation.
Step 6: Build a React Horoscope Widget
Here is a self-contained React component that displays a daily horoscope with a sign selector. In a Next.js App Router project, make it a server component that fetches data at request time:
// app/horoscope/page.tsx
import { gs } from "@/lib/gitstrology";
import Link from "next/link";
const SIGNS = [
"aries", "taurus", "gemini", "cancer", "leo", "virgo",
"libra", "scorpio", "sagittarius", "capricorn", "aquarius", "pisces",
] as const;
export default async function HoroscopePage({
searchParams,
}: {
searchParams: Promise<{ sign?: string }>;
}) {
const { sign } = await searchParams;
const selected = (sign && SIGNS.includes(sign as never))
? sign
: "aries";
const result = await gs.horoscope({ sign: selected });
const h = result.data;
return (
<div className="horoscope-widget">
<h2>Daily Horoscope</h2>
<nav className="sign-picker">
{SIGNS.map((s) => (
<Link
key={s}
href={`/horoscope?sign=${s}`}
className={s === selected ? "active" : ""}
>
{s}
</Link>
))}
</nav>
<div className="reading">
<h3>{h.sign.toUpperCase()} — {h.date}</h3>
<p className="mood">Mood: {h.mood}</p>
<p className="summary">{h.summary}</p>
<p className="advice">Advice: {h.advice}</p>
<div className="ratings">
<span>Energy: {"★".repeat(h.energy)}</span>
<span>Luck: {"★".repeat(h.luck)}</span>
<span>Love: {"★".repeat(h.love)}</span>
<span>Career: {"★".repeat(h.career)}</span>
</div>
<p className="lucky">
Lucky Number: {h.luckyNumber} — Lucky Color: {h.luckyColor}
</p>
</div>
</div>
);
}This component fetches the horoscope server-side on each request, so your API key never reaches the browser. For higher traffic, add the caching layer from Step 5 and read from it instead of calling the API on every page load.
Step 7: Handle Errors and Rate Limits
Production apps must handle the three common failure modes: invalid input, rate limiting, and credit exhaustion. The API returns standard HTTP status codes:
400— Invalid request (e.g., unrecognized sign)401— Missing or invalid API key402— Credit balance exhausted429— Rate limit exceeded (too many requests per minute)500— Server error (retry with backoff)
async function safeGetHoroscope(sign: string) {
try {
return await gs.horoscope({ sign });
} catch (error: any) {
const status = error.status || error.response?.status;
if (status === 400) {
console.error("Invalid sign:", sign);
return { error: "Invalid zodiac sign." };
}
if (status === 402) {
console.error("Out of credits. Upgrade at /pricing.");
return { error: "Daily horoscope unavailable. Please try again tomorrow." };
}
if (status === 429) {
console.error("Rate limited. Backing off.");
await new Promise((r) => setTimeout(r, 5000));
return gs.horoscope({ sign }); // retry once
}
console.error("Unexpected error:", error.message);
return { error: "Something went wrong. Please try again." };
}
}Always degrade gracefully — never show a raw error to end users. Return a neutral fallback message and log the technical detail server-side. For the full list of status codes and retry guidance, see rate limits and credits.
Valid Zodiac Signs
The API accepts the following lowercase sign identifiers. Validate user input against this list before calling the endpoint to avoid 400 errors. Presenting a constrained dropdown or chip selector in your UI is even better than free-text validation, because it prevents invalid input at the source and gives users a faster path to their reading:
const VALID_SIGNS = [
"aries", "taurus", "gemini", "cancer",
"leo", "virgo", "libra", "scorpio",
"sagittarius", "capricorn", "aquarius", "pisces",
] as const;
function isValidSign(input: string): boolean {
return (VALID_SIGNS as readonly string[]).includes(input.toLowerCase());
}Optimizing Credit Usage
Because horoscopes are deterministic for a given sign and date, the most effective optimization is caching. Fetch each sign once per day, store the result in Redis, a database, or even an in-memory map for small deployments, and serve all subsequent reads from the cache. With this pattern, 12 API credits per day covers unlimited user traffic for all twelve signs — the same 12 credits whether you have 10 users or 10 million.
The response envelope’s credits object is your real-time usage dashboard. Log credits.remaining after every call and set up an alert when it drops below a threshold (for example, 20% of your monthly budget). This gives you time to upgrade your plan before you hit a hard limit and degrade the user experience.
// Log credit usage and alert when low
function trackCredits(result: { credits: { used: number; remaining: number } }) {
const { used, remaining } = result.credits;
console.log(`Credits used: ${used}, remaining: ${remaining}`);
if (remaining < 20) {
// Trigger alert (Slack, email, PagerDuty, etc.)
console.warn("Credit balance low — consider upgrading at /pricing");
}
}Going Beyond Horoscopes
Once daily horoscopes are live, you can layer in complementary endpoints to enrich the experience. The /v1/moon-phase endpoint (1 credit) returns the current moon phase, illumination, and the zodiac sign the moon is transiting — perfect for a lunar widget next to the daily reading. You can also pull a user’s natal chart (5 credits, computed once and cached permanently) to personalize horoscope framing based on their actual sun, moon, and rising signs rather than a self-reported sun sign alone.
These combinations turn a simple daily reading into a richer, stickier product. The key is the same throughout: call server-side, cache aggressively, and let the credit envelope guide your scaling decisions. Explore the full API surface to see every endpoint available.
Key Takeaways
- The
/v1/horoscopeendpoint returns a complete daily reading — mood, ratings, summary, advice, lucky number, and color — for 1 credit per call. - The free tier includes 100 credits per month with no credit card, enough to prototype and serve a small user base.
- Always call the API server-side. Never expose your
X-API-Keyin client-side code. - The official TypeScript SDK handles auth, parsing, and typing automatically — use it instead of raw fetch when possible.
- Use a cron job with caching to fetch all twelve signs once per day (12 credits) and serve unlimited reads from your cache layer.
- Handle 400 (bad input), 402 (no credits), and 429 (rate limit) errors with user-friendly fallbacks.
- Every response includes a
creditsenvelope so you can monitor usage in real time.
Ready to ship daily horoscopes? Get your API key from the dashboard, follow the quickstart guide, and have a working integration in five minutes. For the full field reference, visit the horoscope docs.