1. Docs
  2. Integrations
  3. WordPress

Use RoxyAPI with WordPress

Add a daily horoscope shortcode, a natal chart block, a Life Path calculator, or a dream symbol lookup to any WordPress site in under 20 minutes.

WordPress powers about 40 percent of the web. Roxy plugs into it two ways: the official plugin gives you Gutenberg blocks and ready-made shortcodes, and the manual path uses standard PHP (wp_remote_post, transients, custom REST routes) for builders who want full control over each call.

  1. In WordPress admin go to Plugins → Add New.
  2. Search for RoxyAPI.
  3. Click Install Now, then Activate.
  4. Settings → RoxyAPI to paste your API key.

The plugin ships Gutenberg blocks and shortcodes covering astrology, tarot, numerology, horoscope, I Ching, and biorhythm. Source repo: github.com/RoxyAPI/sdk-wordpress.

Prefer the latest unreleased code? Grab roxyapi.zip from GitHub Releases and upload via Plugins → Add New → Upload Plugin.

Prefer to write each shortcode yourself? Skip the plugin and follow the manual path below.

What you can build on WordPress

  • Daily horoscope shortcode you drop into any post or page
  • Natal chart shortcode that takes attributes and renders the chart
  • Client-side horoscope picker backed by a custom REST route
  • Life Path calculator on a Contact Form 7 or WPForms submit
  • Vedic kundli generator with PDF export via FPDF or DOMPDF
  • Dream symbol lookup widget in the sidebar
  • WooCommerce reading product that emails the chart after checkout

What you need, 30 seconds

  1. A Roxy API key. Get one on the pricing page.
  2. A WordPress site where you can edit wp-config.php or install a plugin. Self-hosted WordPress works everywhere. WordPress.com Personal plan or higher also works (the free plan does not allow plugins or custom code).
  3. Ten minutes.

Not comfortable editing PHP? Install the free Code Snippets or WPCode plugin. Both let you paste PHP snippets in a UI without touching theme files. Every snippet on this page works inside Code Snippets unchanged.

Step 1, connect your first endpoint

Two places to store the key. Pick whichever matches your setup.

Most secure. The constant lives outside the database.

  1. Connect via SFTP, the host file manager, or the hosting control panel.
  2. Open wp-config.php in the WordPress root.
  3. Above the line that reads That is all, stop editing (near the bottom of the file) add:
    define( 'ROXY_API_KEY', 'your_roxyapi_key_here' );
  4. Save. The constant is now available in every PHP file. WordPress reads wp-config.php on every request, no restart needed.

Whichever path you pick, never put the key in a theme file that loads on the frontend, a wp_options row, a post meta field, a custom field value, or any JavaScript file. Those either ship to the browser or end up in a database export.

Now add a shortcode. Paste into Code Snippets as a new PHP snippet or into a child theme functions.php.

<?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'] );
    $valid = array( 'aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo', 'libra', 'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces' );
    if ( ! in_array( $sign, $valid, 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 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>Lucky number ' . intval( $data['luckyNumber'] ) . ', lucky color ' . esc_html( $data['luckyColor'] ) . '.</p>';
    $html .= '</div>';
    set_transient( $cache_key, $html, HOUR_IN_SECONDS );
    return $html;
}

Drop [roxy_horoscope sign="leo"] into any post or page in the block editor (Shortcode block). You should see the rendered horoscope with daily overview, love, career, lucky number, and lucky color.

Step 2, ship a useful feature

Here is the full flow for a natal chart shortcode that takes birth details and renders the chart.

<?php
add_shortcode( 'roxy_natal_chart', 'roxy_natal_chart_shortcode' );

function roxy_natal_chart_shortcode( $atts ) {
    $atts = shortcode_atts(
        array(
            'date'      => '',
            'time'      => '',
            'latitude'  => '',
            'longitude' => '',
            'timezone'  => 'UTC',
        ),
        $atts,
        'roxy_natal_chart'
    );
    if ( empty( $atts['date'] ) || empty( $atts['time'] ) || empty( $atts['latitude'] ) || empty( $atts['longitude'] ) ) {
        return '<p>Date, time, latitude, and longitude are required.</p>';
    }
    if ( ! defined( 'ROXY_API_KEY' ) ) {
        return '<p>RoxyAPI key not configured.</p>';
    }
    $payload = array(
        'date'      => sanitize_text_field( $atts['date'] ),
        'time'      => sanitize_text_field( $atts['time'] ),
        '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:

[roxy_natal_chart date="1990-05-12" time="14:30:00" latitude="40.7128" longitude="-74.0060" timezone="America/New_York"]

For a real production page, replace the raw <pre> JSON dump with a styled grid of planets, houses, and aspects. The astrology guide documents the response shape.

Public REST proxy for JavaScript widgets

If you want a JavaScript widget on the frontend to fetch fresh data after page load, register a custom REST route that proxies the call.

<?php
add_action( 'rest_api_init', function () {
    register_rest_route(
        'roxy/v1',
        '/horoscope/(?P<sign>[a-z]+)',
        array(
            'methods'             => 'GET',
            'callback'            => 'roxy_rest_horoscope',
            'permission_callback' => '__return_true',
        )
    );
} );

function roxy_rest_horoscope( $request ) {
    $sign = strtolower( $request['sign'] );
    $valid = array( 'aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo', 'libra', 'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces' );
    if ( ! in_array( $sign, $valid, true ) ) {
        return new WP_Error( 'invalid_sign', 'Invalid zodiac sign', array( 'status' => 400 ) );
    }
    if ( ! defined( 'ROXY_API_KEY' ) ) {
        return new WP_Error( '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 ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
        return new WP_Error( 'upstream', 'Upstream error', array( 'status' => 502 ) );
    }
    $data = json_decode( wp_remote_retrieve_body( $response ), true );
    set_transient( $cache_key, $data, HOUR_IN_SECONDS );
    return rest_ensure_response( $data );
}

Your endpoint is live at https://your-site.com/wp-json/roxy/v1/horoscope/aries. The browser only sees your own domain, never roxyapi.com.

Step 3, scale to the full surface

You have one shortcode working. Adding the next 130 endpoints is the same pattern: copy the snippet, change the URL, change the callback name, the ROXY_API_KEY constant is shared. Three places to pick the next one:

Where to put the code

Four options, roughly in order of "the right thing to do":

  1. Code Snippets plugin. Best for non-developers. Survives theme switches.
  2. Child theme functions.php. Survives parent theme updates. Loses everything if you switch themes.
  3. mu-plugins directory. Auto-loaded, survives every theme switch, never needs activation. Best for "this is part of the site forever".
  4. Custom plugin. Best if you plan to share or version the code separately.

Avoid editing the parent theme functions.php directly. Updates wipe it.

Gotchas

  • Backend-only key. The API key lives in wp-config.php or Code Snippets. Never put it in wp_options, a theme file that loads on the frontend, a custom field, or a JavaScript file.
  • Timezone. Prefer IANA strings ("America/New_York", "Asia/Kolkata"). Decimal offsets like 5.5 are accepted but do not handle daylight saving. The server resolves IANA to the DST-correct offset for the request date.
  • Rate limits. Every Roxy plan has daily and monthly caps. Every snippet on this page uses transients for at least an hour. For permanent data (dream symbols, hexagrams, angel numbers) use DAY_IN_SECONDS or WEEK_IN_SECONDS.
  • Object cache plugins. Redis or Memcached transients are per-process and flush on cache reset. If you need durability, use update_option or a custom table.
  • Refresh permalinks after adding a REST route. Go to Settings, Permalinks, click Save. WordPress regenerates the rewrite rules.
  • cURL SSL errors. If wp_remote_get errors with "cURL error 60", the host has stale CA certificates. Contact hosting support. Do not disable SSL verification; that opens you to man-in-the-middle attacks.

What to build next