Build a PHP Insight App: Astrology, Vedic, Tarot APIs
Build a PHP astrology, Vedic kundli, and tarot app with the new roxyapi/sdk Composer package. Laravel, Symfony, vanilla PHP, one API key.
TL;DR
- One Composer package,
roxyapi/sdk, ships on Packagist today and covers Western astrology, Vedic kundli, panchang, tarot, numerology, biorhythm, I Ching, crystals, dreams, angel numbers, and location across 131 endpoints. - Install with
composer require roxyapi/sdk. Requires PHP 8.2+. One dependency, Saloon v4. - Geocode the birth city with
$roxy->location->searchCitiesfirst. Feedlatitude,longitude, andtimezoneinto every chart, panchang, dasha, or natal call. - Works in Laravel, Symfony, Slim, WordPress, and vanilla PHP. Build a multi-domain insight app this afternoon with the astrology API.
The new RoxyAPI PHP SDK published to Packagist today as roxyapi/sdk v0.1.1. One Composer install gives every PHP project the same surface the TypeScript and Python SDKs already ship: Western astrology, Vedic astrology, numerology, tarot, biorhythm, I Ching, crystals, dreams, angel numbers, location, plus usage and language helpers. Methods are named arguments, responses are plain associative arrays, and the only runtime dependency is Saloon v4. This post is the launch note and a hands-on tutorial: by the end you will have a small PHP app that calls multiple RoxyAPI domains and returns JSON ready for any frontend.
What does the new PHP SDK cover, and why ship one now
roxyapi/sdk is the third sibling in the RoxyAPI client family, after @roxyapi/sdk on npm and roxy-sdk on PyPI. The PHP version covers the same 131 endpoints across 12 domains under one API key. PHP runs the largest CMS and e-commerce footprint on the web (WordPress, Drupal, Magento), and the Laravel and Symfony ecosystems keep growing. Shipping a typed PHP SDK closes the last big gap in the agent-and-app stack. The package depends only on Saloon v4, the modern PHP HTTP SDK framework, plus PHP 8.2 named arguments.
| Property | Endpoints | What it covers |
|---|---|---|
$roxy->astrology | 22 | Western natal charts, transits, synastry, daily, weekly, and monthly horoscopes |
$roxy->vedicAstrology | 42 | Kundli, panchang, dasha, dosha, KP system, navamsa, Guna Milan |
$roxy->numerology | 16 | Life Path, Expression, Soul Urge, Personal Year, compatibility |
$roxy->tarot | 10 | Daily card, Celtic Cross, three-card, love, yes-no, card catalog |
$roxy->biorhythm | 6 | Daily, forecast, compatibility, critical days |
$roxy->iching | 9 | Daily hexagram, cast, 64 hexagrams catalog |
$roxy->crystals | 12 | By zodiac, chakra, birthstone, free-text search |
$roxy->dreams | 5 | Symbol lookup, daily symbol |
$roxy->angelNumbers | 4 | Sequence meanings, daily, universal lookup |
$roxy->location | 3 | City search and geocoding |
$roxy->usage / $roxy->languages | 2 | Quota stats and the eight lang codes |
Ready to build with this? Astrology API and Vedic Astrology API run under one key. See pricing.
How to install the PHP SDK and authenticate in two minutes
Pull the package with Composer, then resolve a Roxy connector through the createRoxy factory. The factory sets the base URL (https://roxyapi.com/api/v2) and the X-API-Key header on every outgoing request, so application code never builds an HTTP client by hand. Get a key at pricing; every plan includes every domain. Export the key as an environment variable rather than hard-coding it. PHP picks it up via getenv in any framework.
composer require roxyapi/sdk
<?php
require __DIR__ . '/vendor/autoload.php';
use function RoxyAPI\Sdk\createRoxy;
$roxy = createRoxy(getenv('ROXY_API_KEY'));
// First call: no body, no coordinates, just a sign
$horoscope = $roxy->astrology->getDailyHoroscope(sign: 'aries');
echo $horoscope['overview'], PHP_EOL;
echo 'Energy rating: ', $horoscope['energyRating'], "/10", PHP_EOL;
echo 'Lucky number: ', $horoscope['luckyNumber'], PHP_EOL;
The package lives at packagist.org/packages/roxyapi/sdk and the source is at github.com/RoxyAPI/sdk-php. Every method returns array<string, mixed> decoded from the API response, or throws RoxyAPI\Sdk\RoxyApiException on any 4xx or 5xx. Access response fields with $result['key']['subkey']. Object syntax like $result->key throws a runtime Attempt to read property error because the SDK never returns objects on the success path.
How to geocode a birth city and generate a Vedic kundli
Every chart, panchang, dasha, dosha, navamsa, KP, synastry, compatibility-score, and natal endpoint needs latitude, longitude, and timezone. Never ask a user to type coordinates. Call $roxy->location->searchCities first, take the first hit, and feed latitude, longitude, and timezone into the chart method. The timezone field on the city is the IANA identifier (Asia/Kolkata, America/New_York), and chart endpoints accept both the IANA string and the decimal utcOffset (5.5, -5) on the same call. The server resolves the IANA string to the DST-correct offset for the chart date, so a winter birth in New York returns EST and a summer birth returns EDT without caller-side date math.
// Step 1: geocode
$result = $roxy->location->searchCities(q: 'Mumbai');
['latitude' => $lat, 'longitude' => $lon, 'timezone' => $tz] = $result['cities'][0];
// Step 2: generate the kundli
$kundli = $roxy->vedicAstrology->generateBirthChart(
date: '1990-01-15',
time: '14:30:00',
latitude: $lat,
longitude: $lon,
timezone: $tz,
);
// Look up any planet by name on the meta dict
echo $kundli['meta']['Sun']['rashi'], "\n"; // e.g. "Capricorn"
echo $kundli['meta']['Moon']['nakshatra']['name'], "\n"; // e.g. "Uttara Ashadha"
echo 'Pada: ', $kundli['meta']['Moon']['nakshatra']['pada'], "\n";
// Iterate the rashi houses for the 12-sign chart
foreach (['aries','taurus','gemini','cancer','leo','virgo',
'libra','scorpio','sagittarius','capricorn','aquarius','pisces'] as $rashi) {
foreach ($kundli[$rashi]['signs'] ?? [] as $planet) {
echo $rashi, ': ', $planet['graha'], "\n";
}
}
The Vedic response is where the depth lives. Each planet on the meta dict carries graha, rashi, longitude, nakshatra.name, nakshatra.pada, nakshatra.key, and isRetrograde. The full Vedic astrology API reference documents every field, and the POST /vedic-astrology/birth-chart lands directly on the playground.
How to combine domains in a single multi-insight call
Multi-domain readings are the unlock that single-purpose APIs cannot match. Once the connector is wired, computing a numerology Life Path, a daily tarot card, and a Western natal chart for the same user is three method calls on the same $roxy instance. Each domain hangs off a property on the connector, each method maps to one operationId in the spec, and each response is a plain array. The pattern below builds the data layer for a full insight profile; a frontend hits one PHP endpoint and gets every domain back in one JSON document.
function buildProfile(\RoxyAPI\Sdk\Roxy $roxy, string $city, array $birth): array
{
$cities = $roxy->location->searchCities(q: $city);
$loc = $cities['cities'][0];
return [
'lifePath' => $roxy->numerology->calculateLifePath(
year: $birth['year'],
month: $birth['month'],
day: $birth['day'],
),
'dailyCard' => $roxy->tarot->getDailyCard(seed: $birth['user_id']),
'natalChart' => $roxy->astrology->generateNatalChart(
date: sprintf('%04d-%02d-%02d', $birth['year'], $birth['month'], $birth['day']),
time: $birth['time'],
latitude: $loc['latitude'],
longitude: $loc['longitude'],
timezone: $loc['timezone'],
),
];
}
$profile = buildProfile($roxy, 'Mumbai', [
'year' => 1990, 'month' => 1, 'day' => 15,
'time' => '14:30:00', 'user_id' => 'user-42',
]);
echo 'Life Path: ', $profile['lifePath']['number'], "\n";
echo 'Today: ', $profile['dailyCard']['card']['name'],
($profile['dailyCard']['card']['reversed'] ? ' (reversed)' : ''), "\n";
echo 'Ascendant: ', $profile['natalChart']['ascendant']['sign'], "\n";
echo 'Sun: ', $profile['natalChart']['planets'][0]['sign'] ?? '?', "\n";
Sub-objects on responses are arrays, not scalars. $chart['ascendant'] is ['sign' => ..., 'degree' => ..., 'longitude' => ...], not a string. Drilling in ($chart['ascendant']['sign']) is required. The same rule applies to meta.{Planet}.nakshatra on the Vedic chart and card on the tarot daily.
How to wire the SDK into Laravel, Symfony, or vanilla PHP
The SDK is framework-agnostic because Composer autoload runs everywhere a PHP project does. The same roxyapi/sdk install works in Laravel, Symfony, Slim, Lumen, WordPress (via composer require), and a single index.php. Laravel users register the connector once as a singleton in a service provider, then inject RoxyAPI\Sdk\Roxy into any controller. Symfony users wire the same singleton through services.yaml. Vanilla PHP users call createRoxy directly at the top of any script.
// app/Providers/RoxyServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use RoxyAPI\Sdk\Roxy;
use function RoxyAPI\Sdk\createRoxy;
class RoxyServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Roxy::class, function () {
$key = (string) config('services.roxyapi.key', env('ROXY_API_KEY', ''));
if ('' === $key) {
throw new \RuntimeException('ROXY_API_KEY is not configured.');
}
return createRoxy($key);
});
}
}
Add the matching entry to config/services.php ('roxyapi' => ['key' => env('ROXY_API_KEY')]) and the connector resolves from the container.
// app/Http/Controllers/HoroscopeController.php
use RoxyAPI\Sdk\Roxy;
class HoroscopeController extends Controller
{
public function show(Roxy $roxy, string $sign)
{
return $roxy->astrology->getDailyHoroscope(sign: $sign);
}
}
Laravel returns the array as JSON automatically. The same connector works inside a queue job, an Artisan command, or a scheduled task. For WordPress plugins or themes that already load Composer (or load it via the roxyapi-sdk-wordpress plugin), call createRoxy(get_option('roxy_api_key')) from a backend handler, never from a shortcode that runs on the client. For the full WordPress pattern, see the WordPress integration guide.
How to render the JSON in a browser and handle errors
The SDK returns JSON. Rendering belongs in the browser. The recommended path is @roxyapi/ui, the open-source web component library: PHP fetches the JSON, the browser hands it to a <roxy-natal-chart> or <roxy-tarot-card> element, and the wheel or card renders without any PHP templating. The same components work in WordPress shortcodes, Shopify themes, plain HTML, and React projects. The pattern below is the full server-plus-browser loop from the SDK examples directory.
// /api/natal-chart.php
require __DIR__ . '/../vendor/autoload.php';
use function RoxyAPI\Sdk\createRoxy;
use RoxyAPI\Sdk\RoxyApiException;
header('Content-Type: application/json');
$roxy = createRoxy(getenv('ROXY_API_KEY'));
try {
echo json_encode($roxy->astrology->generateNatalChart(
date: $_GET['date'],
time: $_GET['time'],
latitude: (float) $_GET['lat'],
longitude: (float) $_GET['lon'],
timezone: is_numeric($_GET['tz']) ? (float) $_GET['tz'] : $_GET['tz'],
));
} catch (RoxyApiException $e) {
http_response_code($e->statusCode);
echo json_encode(['error' => $e->error, 'code' => $e->errorCode]);
}
<script type="module"
src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js"></script>
<roxy-natal-chart id="chart"></roxy-natal-chart>
<script type="module">
const r = await fetch('/api/natal-chart.php?date=1990-01-15&time=14:30:00&lat=28.6139&lon=77.209&tz=5.5');
document.getElementById('chart').data = await r.json();
</script>
RoxyApiException is the only real object on the response path. Three properties matter: statusCode (HTTP status as int), errorCode (machine-readable, stable, switch on this), and error (human-readable, wording may change between releases). Stable codes are validation_error, api_key_required, invalid_api_key, subscription_inactive, not_found, rate_limit_exceeded, and internal_error. For unit tests, drop the Saloon MockClient in and stub responses by request class without ever touching the network.
use RoxyAPI\Sdk\Generated\Requests\GetDailyHoroscopeRequest;
use Saloon\Http\Faking\MockClient;
use Saloon\Http\Faking\MockResponse;
$roxy = createRoxy('test-key');
$roxy->withMockClient(new MockClient([
GetDailyHoroscopeRequest::class => MockResponse::make([
'sign' => 'aries', 'overview' => 'fixture overview',
]),
]));
FAQ
How to add Western astrology to a PHP project?
Install the SDK with composer require roxyapi/sdk and create a client with $roxy = createRoxy(getenv('ROXY_API_KEY')). The astrology namespace exposes 22 endpoints, including $roxy->astrology->getDailyHoroscope(sign: 'aries') for a transit-driven daily horoscope and $roxy->astrology->generateNatalChart(...) for a full natal chart with planets, houses, and aspects. Every method returns an associative array, so access fields with bracket syntax like $horoscope['overview'].
How to add Vedic astrology and kundli generation to a PHP project?
After installing roxyapi/sdk, call $roxy->vedicAstrology->generateBirthChart(date: '1990-01-15', time: '14:30:00', latitude: 19.0760, longitude: 72.8777). The response carries per-planet nakshatra with name and pada for pada-quarter precision, combustion data, planetary war flags, and per-rashi placements. Pair it with $roxy->vedicAstrology->getDetailedPanchang(...) to return 15+ muhurtas (rahuKaal, abhijit, brahma, vijaya, varjyam, amritkalam, and more) in one call.
How to add numerology to a PHP project?
Install roxyapi/sdk and call $roxy->numerology->calculateLifePath(year: 1990, month: 1, day: 15) for the life path number. The numerology namespace also exposes expression, soul urge, personality, personal year, and 36-point relationship compatibility methods. No birth time or coordinates required, pure date arithmetic, and every method accepts an optional lang argument for localized interpretations in eight languages.
How to draw a daily tarot card in PHP?
Use $roxy->tarot->getDailyCard(seed: 'user-42') from the installed roxyapi/sdk. Pass a stable seed per user (user id, session token, hashed email) for reproducible daily readings, so same seed plus same date returns the same card every time. Read $daily['card']['name'] for the card title and $daily['card']['dailyMessage'] for the interpretation. For multi-card spreads call $roxy->tarot->castThreeCard(question: '...') or $roxy->tarot->castCelticCross(question: '...').
How to geocode a birth city in PHP before generating a chart?
Call $roxy->location->searchCities(q: 'Mumbai') and read the first result from $cities['cities'][0]. The response gives latitude, longitude, and an IANA timezone string per city. Feed those three values into every chart endpoint that needs coordinates: natal chart, kundli, panchang, dasha, synastry, transits. The IANA timezone resolves DST correctly for historical birth dates, so a January 1990 New York chart picks EST automatically.
How to use the RoxyAPI PHP SDK in a Laravel application?
Register the RoxyAPI\Sdk\Roxy connector as a singleton in a service provider: $this->app->singleton(Roxy::class, fn () => createRoxy(config('services.roxyapi.key'))). Then inject it into any controller, job, or service via constructor type-hint. The same pattern works in Symfony with services.yaml, in Slim through the DI container, in WordPress plugins via the Composer autoload, and in vanilla PHP by constructing the connector once and reusing it across requests.
How to handle errors from the RoxyAPI PHP SDK?
Wrap calls in try { ... } catch (RoxyApiException $e) { ... } and switch on the machine-readable $e->errorCode. Stable codes include validation_error, invalid_api_key, subscription_inactive, not_found, rate_limit_exceeded, and internal_error. The exception also exposes $e->statusCode (HTTP status) and $e->error (human-readable message, may change wording). Transport failures like timeouts surface with errorCode of connection_error, so callers only ever catch one exception type.
How to mock the RoxyAPI PHP SDK in PHPUnit or Pest tests?
The SDK is built on Saloon, so use the Saloon MockClient to stub responses by request class. Import the request you want to mock (for example RoxyAPI\Sdk\Generated\Requests\GetDailyHoroscopeRequest), pass fixture data to MockResponse::make([...]), and call $roxy->withMockClient($mock). The mocked call returns the fixture without touching the network, so the same test suite runs in CI without an API key or rate budget.
Conclusion
The PHP SDK closes the last gap in the RoxyAPI client family: TypeScript, Python, and now PHP share the same operationId-driven surface across 131 endpoints and 12 domains under one key. Install with composer require roxyapi/sdk, set ROXY_API_KEY in the environment, and ship a Laravel, Symfony, WordPress, or vanilla PHP insight app this afternoon. Start with the astrology API and the pricing page to grab a key.