- Docs
- Integrations
- WordPress
WordPress
Add RoxyAPI to any WordPress site and ship a daily horoscope widget, a natal chart shortcode, a Life Path calculator, a tarot card of the day block, or a dream symbol lookup tool. One API key, 10 domains, 130+ endpoints, called from PHP using WordPress's built-in HTTP API. If you run an astrology blog, a tarot reading site, a witch shop, a dream journal, or any spiritual content site on WordPress, this is the page you need.
This guide covers the standard WordPress patterns: shortcodes, transient caching, secure API key storage in wp-config.php, custom REST routes for client widgets, and where to put the code (functions.php vs custom plugin vs code snippets plugin). Works with WordPress 5.x, 6.x, and current 6.9.
Before you start
- A RoxyAPI account and an API key. Grab one from the pricing page, or test endpoints first with the pre-filled key on the interactive API reference.
- A WordPress site where you can edit
wp-config.phpand add custom PHP. Self-hosted WordPress works perfectly. WordPress.com Personal plan or higher also works (the free plan does not allow plugin installation or custom code). For shared hosting, this is supported by every host that supports WordPress. - Ten minutes.
Not comfortable editing PHP files? Install the free Code Snippets or WPCode plugin. Both let you paste PHP snippets into a UI and they handle activation safely without ever touching functions.php. Every snippet on this page works inside Code Snippets unchanged.
Step 1: store your API key (two options)
Your RoxyAPI key is a secret. It must run only on the server, never reach a visitor's browser, and never appear in your theme files. There are two safe places for it. Pick whichever matches your comfort level.
Option A (easiest): inside the Code Snippets snippet itself
If you are using the Code Snippets plugin (recommended for most users), define the key as a PHP constant at the very top of your snippet, above the shortcode registration. The constant will be available to every function in that snippet.
<?php
define( 'ROXY_API_KEY', 'your_roxyapi_key_here' );
// ...your shortcode and other functions go below...
That is it. No SFTP, no wp-config.php, no file editing. The key still runs only on the server because Code Snippets executes the PHP server-side just like a plugin does. The key never gets sent to a visitor's browser.
The trade-off: the snippet code (including your key) lives in the database in the wp_snippets table. That is fine for most sites. If you ever export your database for a backup or hand it to someone, your key is in that export. For sites that take backups seriously or share database dumps, use Option B instead.
Option B (most secure): wp-config.php constant
For production sites where you take database backups regularly or where multiple people have admin access, store the key in wp-config.php instead. The constant lives outside the database entirely.
- Connect to your site via SFTP, the hosting file manager, or your hosting control panel
- Open
wp-config.php(it lives in your WordPress root directory) - Find the line
/* That's all, stop editing! Happy publishing. */near the bottom - Above that line, add this:
define( 'ROXY_API_KEY', 'your_roxyapi_key_here' );
- Save the file
The constant ROXY_API_KEY is now available in every PHP file in your WordPress install. It never touches the database, never appears in any backup of wp_options, and never gets exposed by debug output as long as you do not echo it yourself.
Whichever option you pick, never put your API key in a theme file directly, in a custom-fields value, in a post meta row, in a wp_options row, or in any client-side JavaScript. All of those are visible to admins, end up in database exports, or worse, get sent to the browser. The auth dropdown of the Code Snippets snippet (Option A) and wp-config.php (Option B) are the only safe homes.
Step 2: add a daily horoscope shortcode (the simplest possible integration)
Shortcodes are the most natural WordPress integration pattern. A shortcode is a tag like [roxy_horoscope sign="aries"] that you drop into any post or page, and it gets replaced with whatever your callback function returns.
Paste this into your Code Snippets plugin as a new PHP snippet (or into your child theme's functions.php if you prefer):
<?php
add_shortcode( 'roxy_horoscope', 'roxy_horoscope_shortcode' );
function roxy_horoscope_shortcode( $atts ) {
$atts = shortcode_atts(
array( 'sign' => 'aries' ),
$atts,
'roxy_horoscope'
);
$sign = sanitize_key( $atts['sign'] );
if ( ! in_array( $sign, array( 'aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo', 'libra', 'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces' ), true ) ) {
return '<p>Invalid zodiac sign.</p>';
}
if ( ! defined( 'ROXY_API_KEY' ) ) {
return '<p>RoxyAPI key not configured.</p>';
}
$cache_key = 'roxy_horoscope_' . $sign;
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return $cached;
}
$response = wp_remote_get(
'https://roxyapi.com/api/v2/astrology/horoscope/' . $sign . '/daily',
array(
'headers' => array( 'X-API-Key' => ROXY_API_KEY ),
'timeout' => 10,
)
);
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return '<p>Could not load today\'s horoscope.</p>';
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
if ( empty( $data['overview'] ) ) {
return '<p>Horoscope unavailable.</p>';
}
$html = '<div class="roxy-horoscope">';
$html .= '<h3>' . esc_html( $data['sign'] ) . ' Daily Horoscope</h3>';
$html .= '<p>' . esc_html( $data['overview'] ) . '</p>';
$html .= '<p><strong>Love:</strong> ' . esc_html( $data['love'] ) . '</p>';
$html .= '<p><strong>Career:</strong> ' . esc_html( $data['career'] ) . '</p>';
$html .= '<p class="roxy-lucky">Lucky number: ' . intval( $data['luckyNumber'] ) . ' | Lucky color: ' . esc_html( $data['luckyColor'] ) . '</p>';
$html .= '</div>';
set_transient( $cache_key, $html, HOUR_IN_SECONDS );
return $html;
}
Now drop [roxy_horoscope sign="leo"] into any post or page in the block editor (use a Shortcode block). Save and view the page. You should see the rendered horoscope with the sign, daily overview, love, career, lucky number, and lucky color.
What this code does:
shortcode_attsmerges your[roxy_horoscope sign="leo"]attributes with defaultssanitize_keystrips anything dangerous from the user-provided sign- Whitelist check rejects unknown signs before they ever reach the API (saves your quota and avoids a 404)
get_transient/set_transientcaches the result for one hour using WordPress's built-in cache layer. Subsequent visits to any post with the same shortcode within the hour serve the cached HTML instantly without hitting the APIwp_remote_getis WordPress's HTTP API. It works on every host (some shared hosts block rawcURL, butwp_remote_getalways works because it falls back through multiple HTTP transports)is_wp_errorand response code check handle network failures and non-200 responses gracefullyesc_htmlescapes every value before output (prevents XSS if the API ever returns hostile content)HOUR_IN_SECONDSis a WordPress constant equal to 3600, much more readable than a raw number
Step 3: add a natal chart shortcode (POST endpoint)
For endpoints that take a JSON body (natal chart, synastry, Vedic kundli, Life Path), use wp_remote_post:
<?php
add_shortcode( 'roxy_natal_chart', 'roxy_natal_chart_shortcode' );
function roxy_natal_chart_shortcode( $atts ) {
$atts = shortcode_atts(
array(
'datetime' => '',
'latitude' => '',
'longitude' => '',
'timezone' => 'UTC',
),
$atts,
'roxy_natal_chart'
);
if ( empty( $atts['datetime'] ) || empty( $atts['latitude'] ) || empty( $atts['longitude'] ) ) {
return '<p>Birth datetime, latitude, and longitude are required.</p>';
}
if ( ! defined( 'ROXY_API_KEY' ) ) {
return '<p>RoxyAPI key not configured.</p>';
}
$payload = array(
'datetime' => sanitize_text_field( $atts['datetime'] ),
'latitude' => floatval( $atts['latitude'] ),
'longitude' => floatval( $atts['longitude'] ),
'timezone' => sanitize_text_field( $atts['timezone'] ),
);
$response = wp_remote_post(
'https://roxyapi.com/api/v2/astrology/natal-chart',
array(
'headers' => array(
'X-API-Key' => ROXY_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( $payload ),
'timeout' => 15,
)
);
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return '<p>Could not generate chart.</p>';
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
return '<pre class="roxy-chart">' . esc_html( wp_json_encode( $data, JSON_PRETTY_PRINT ) ) . '</pre>';
}
Use it like this in any post:
[roxy_natal_chart datetime="1990-05-12T14:30:00" latitude="40.7128" longitude="-74.0060" timezone="America/New_York"]
For a real production app, replace the raw <pre> JSON dump with a styled grid showing planets, houses, and aspects. Use the astrology guide to learn what fields the chart returns and how to render them.
Step 4: build a public REST proxy for client-side widgets
Sometimes you need a JavaScript widget on the frontend that fetches fresh data after the page loads. A common case: a "horoscope picker" where the user clicks a sign and the horoscope updates without a full page reload. For that, register a custom WordPress REST route that proxies the call.
<?php
add_action( 'rest_api_init', 'roxy_register_rest_routes' );
function roxy_register_rest_routes() {
register_rest_route(
'roxy/v1',
'/horoscope/(?P<sign>[a-z]+)',
array(
'methods' => 'GET',
'callback' => 'roxy_rest_horoscope',
'permission_callback' => '__return_true',
'args' => array(
'sign' => array(
'validate_callback' => function ( $value ) {
return in_array(
strtolower( $value ),
array( 'aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo', 'libra', 'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces' ),
true
);
},
),
),
)
);
}
function roxy_rest_horoscope( $request ) {
$sign = strtolower( $request['sign'] );
if ( ! defined( 'ROXY_API_KEY' ) ) {
return new WP_Error( 'roxy_no_key', 'API key not configured', array( 'status' => 500 ) );
}
$cache_key = 'roxy_rest_horoscope_' . $sign;
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return rest_ensure_response( $cached );
}
$response = wp_remote_get(
'https://roxyapi.com/api/v2/astrology/horoscope/' . $sign . '/daily',
array(
'headers' => array( 'X-API-Key' => ROXY_API_KEY ),
'timeout' => 10,
)
);
if ( is_wp_error( $response ) ) {
return new WP_Error( 'roxy_upstream', 'Upstream error', array( 'status' => 502 ) );
}
$code = wp_remote_retrieve_response_code( $response );
if ( 200 !== $code ) {
return new WP_Error( 'roxy_upstream', 'Upstream error', array( 'status' => $code ) );
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
set_transient( $cache_key, $data, HOUR_IN_SECONDS );
return rest_ensure_response( $data );
}
Your custom endpoint is now live at:
https://your-site.com/wp-json/roxy/v1/horoscope/aries
The frontend can now fetch from your own domain with a plain JavaScript fetch:
<div id="horoscope">Loading...</div>
<script>
fetch('/wp-json/roxy/v1/horoscope/leo')
.then(res => res.json())
.then(data => {
document.getElementById('horoscope').innerHTML =
'<h3>' + data.sign + '</h3>' +
'<p>' + data.overview + '</p>' +
'<small>Lucky: ' + data.luckyNumber + ' / ' + data.luckyColor + '</small>';
});
</script>
The browser only sees /wp-json/roxy/v1/..., never roxyapi.com. Your API key stays on the server, the response is cached for an hour by WordPress transients, and your visitor gets a fast widget.
The permission_callback => '__return_true' line makes this endpoint public. Anyone who knows the URL can call it. That is fine for a public horoscope widget, but do not use this pattern for endpoints that return user-specific data (personal natal charts, custom transit reports, anything tied to a logged-in user). For those, use is_user_logged_in() or check capabilities in the permission_callback.
Where to put this code
You have four options, in increasing order of "the right thing to do":
- Code Snippets plugin (easiest). Install Code Snippets or WPCode, paste the PHP into a new snippet, activate. No theme files touched. The snippets survive theme switches. Best for non-developers.
- Child theme
functions.php. Editwp-content/themes/your-child-theme/functions.phpand paste at the bottom. Survives parent theme updates. Loses everything if you switch themes. mu-pluginsdirectory. Createwp-content/mu-plugins/roxy.phpand paste the PHP wrapped in<?php. Must-Use plugins are auto-loaded, survive every theme switch, never need activation. Best for "this is part of the site forever".- A custom plugin. Create
wp-content/plugins/roxy-integration/roxy-integration.phpwith a plugin header, then paste the code. Activate from the plugins admin page. Best if you might want to share or version this code separately. Use this if you plan to publish it to the WordPress.org plugin directory eventually.
For a small site that just needs a horoscope shortcode, Code Snippets is the right answer. For a serious astrology site building multiple features, a custom plugin is the right answer. Avoid editing functions.php of a non-child theme directly — your changes will be wiped on the next theme update.
Test your API key outside WordPress first
Before you wire anything into WordPress, confirm your key works on its own. Open a terminal and run:
curl "https://roxyapi.com/api/v2/astrology/horoscope/aries/daily" \
-H "X-API-Key: YOUR_KEY"
If that prints JSON, the key is good and any error in WordPress is a code or config issue, not a RoxyAPI issue. If it returns 401, the key is wrong or your subscription is inactive. Check at your account page.
Troubleshooting
Shortcode renders nothing or "Invalid zodiac sign"
The shortcode attribute is missing or misspelled. Use exactly [roxy_horoscope sign="leo"] with one of the 12 lowercase zodiac signs. Check that you registered the shortcode in a snippet that is active in Code Snippets, or that your functions.php actually loaded.
"RoxyAPI key not configured"
The ROXY_API_KEY constant is not defined. Open wp-config.php, confirm the line define( 'ROXY_API_KEY', '...' ); is above the "stop editing" comment, save, and refresh the page. WordPress reads wp-config.php on every request, so no restart is needed.
"Could not load today's horoscope" with no detail
Add temporary debug output to see the actual error:
if ( is_wp_error( $response ) ) {
return '<pre>' . esc_html( $response->get_error_message() ) . '</pre>';
}
return '<pre>HTTP ' . wp_remote_retrieve_response_code( $response ) . ': ' . esc_html( wp_remote_retrieve_body( $response ) ) . '</pre>';
This shows the raw 401, 404, or network error from RoxyAPI. Common causes:
- Wrong API key (401
api_key_requiredorinvalid_api_key) - Wrong endpoint URL (404 with a
suggestionfield) - Wrong method (405 with an
allowarray) - Network failure (server cannot reach
roxyapi.com, often a hosting firewall — contact your host)
Remove the debug output once you find the issue.
429 rate_limited
You hit your monthly plan quota. The transient cache pattern in this guide already throttles your calls hard, so this typically means another part of your site is also calling RoxyAPI without caching. Audit your custom code, increase the transient TTL (HOUR_IN_SECONDS to DAY_IN_SECONDS), or upgrade on the pricing page.
Transients not caching (every page load hits the API)
The most common cause is an object cache plugin (Redis, Memcached) that stores transients in memory but loses them on every cache flush. Either accept the behavior, or use a persistent options table by using update_option / get_option instead of transients. The transient API is the right call for most sites though — investigate the cache plugin first.
The REST endpoint returns 404
Refresh your permalinks. Go to Settings > Permalinks in the WordPress admin and click Save (you do not need to change anything). WordPress regenerates the rewrite rules, and your custom REST route at /wp-json/roxy/v1/... will start working.
wp_remote_get returns "cURL error 60: SSL certificate problem"
Your hosting environment has stale CA certificates. Update your host's PHP environment or contact your hosting support. Do not disable SSL verification with 'sslverify' => false — that opens you up to man-in-the-middle attacks on every API call.
Extend your integration
You have one shortcode working in WordPress. Adding the next 130 endpoints is the same pattern: copy the snippet, change the URL, change the shortcode tag and callback name, the API key constant and wp_remote_get boilerplate stay the same. Three places to find the next endpoint to wire up:
- Interactive API reference — Scalar-powered live docs for every endpoint across all 10 domains. Try a call in the browser with the pre-filled test key, copy the curl example, then translate the URL and headers into a new
wp_remote_getorwp_remote_postcall inside your snippet. - Domain guides — short walkthroughs of which endpoints to call in what order for a given product:
- Western Astrology guide — natal charts, horoscopes, synastry, transits
- Vedic Astrology guide — kundli, Gun Milan, Vimshottari Dasha, panchang, KP
- Tarot guide — daily card, three-card, Celtic Cross, custom spreads
- Numerology guide — Life Path, Expression, Soul Urge, personal year
- One snippet, many shortcodes. A single Code Snippets entry can register as many shortcodes as you want. Add a new
add_shortcodecall and a new callback function inside the same snippet for every endpoint you wire up. TheROXY_API_KEYconstant is shared.
The pattern is the same every time: horoscope today, compatibility tomorrow, kundli next week. One key, every endpoint unlocked.
What to build first
- Daily horoscope shortcode in your sidebar. The Step 2 snippet, hour-cached. Drop
[roxy_horoscope sign="aries"]into a Custom HTML widget or any sidebar block. Costs you 12 API calls per day (one per sign) regardless of traffic. - Tarot card of the day on your homepage. Adapt the Step 2 snippet to call
POST /tarot/dailyand render the card name, image (if you host one), and meaning. - Birth chart calculator page. Build a Contact Form 7 or WPForms form that captures birth date, time, and place. On submission, call the Step 3
roxy_natal_chartsnippet with the form values and email the result to the user. - Dream symbol lookup widget. Search input in the sidebar → REST proxy endpoint at
/wp-json/roxy/v1/dreams/[query]→ results rendered below. Use the Step 4 pattern adapted toGET /dreams/symbols. - Life Path number calculator. Form on a "Free Tools" page → submit to a custom shortcode that calls
/numerology/life-path→ display the number with its meaning. - Vedic kundli generator with PDF export. Form → custom shortcode calls
/vedic-astrology/birth-chart→ render the kundli with planets, nakshatra, Vimshottari Dasha, and panchang. Pair with a PDF generation plugin like FPDF or DOMPDF for downloadable reports. - Daily crystal recommendation in your blog footer. Cached shortcode calling
/crystals/daily, displayed in every page footer. Bonus traffic loop: encourage readers to bookmark the page for daily crystal updates.
FAQ
How do I connect WordPress to RoxyAPI?
Define your API key as a constant in wp-config.php (define( 'ROXY_API_KEY', '...' );), then call wp_remote_get or wp_remote_post with the X-API-Key header set to ROXY_API_KEY in any shortcode, REST route, or plugin function. The Step 2 snippet on this page is a complete working example you can paste into Code Snippets.
Do I need to write PHP or can I use a plugin?
You need to write PHP, but you do not need to edit theme files. Install Code Snippets or WPCode, paste the snippets from this page into the plugin UI, and activate. There is no official RoxyAPI WordPress plugin yet, but the snippet approach is the same level of effort and far easier to maintain than a third-party plugin.
Does this work on WordPress.com?
Yes, on the Personal plan or higher. WordPress.com Personal, Premium, Business, and Commerce plans all allow plugin installation, so you can use Code Snippets or WPCode to paste the PHP snippets from this page. The free plan does not allow plugins or custom code. Self-hosted WordPress works on every host regardless of plan.
How accurate are the astrology calculations?
Every position comes from Roxy Ephemeris, verified against NASA JPL Horizons. See the methodology page for accuracy details, including sub-arcsecond planet positions and standard Placidus house calculation. Same engine for every endpoint, regardless of which integration calls it.
How do I cache responses to save quota?
Use WordPress transients (set_transient / get_transient). Every snippet on this page caches results for one hour using HOUR_IN_SECONDS. For data that changes daily (horoscopes, daily tarot cards), DAY_IN_SECONDS is a better TTL. For permanent data (dream symbols, hexagram meanings, angel number lookups), use WEEK_IN_SECONDS or longer.
Can I use this with WooCommerce to sell readings?
Yes. Add a custom WooCommerce product type that triggers a RoxyAPI call after checkout completes. Hook into woocommerce_order_status_completed to call /astrology/natal-chart (or any other endpoint) with the customer's birth data from custom checkout fields, then email the result. This is the same pattern serious astrology e-commerce sites already use.
Will my API key leak to my visitors?
Not if you keep it in wp-config.php as a constant. WordPress never exposes constants from wp-config.php to the frontend or to the REST API by default. The dangerous mistake is putting the key in the database (wp_options), in a custom field, in a theme file that gets loaded on the frontend, or in a JavaScript-callable AJAX endpoint that returns it. Avoid those four and your key stays safe.
Can I use the WordPress REST API to expose RoxyAPI calls to mobile apps?
Yes. The Step 4 pattern in this guide does exactly that. Register a custom REST route under roxy/v1, call RoxyAPI from PHP, return the result. Your mobile app calls https://your-site.com/wp-json/roxy/v1/horoscope/leo and gets clean JSON back. Add authentication (JWT, Application Passwords, or is_user_logged_in() checks) if the endpoint should be private.
Is there a ready-made WordPress plugin for RoxyAPI?
Not yet. If you build one and want it featured in our starters page, reply to your onboarding email with a link. The first community WordPress plugin for RoxyAPI gets a free month on us, and we will help you list it on the WordPress.org plugin directory.
Where do I get a RoxyAPI key?
Visit the pricing page for paid plans, or try the interactive API reference with a pre-filled test key first. Plans start at 5,000 requests per month, which is enough for a small WordPress site running for weeks even without caching.