These keys supply the Intelligence panel with real, verified, live articles — headlines and URLs that actually exist. Both are free with no credit card required. Anthropic (Claude) then adds a coaching commentary layer on top of the real articles.
Finnhub → powers Financial Markets and Alternative Investments panels with live market news. Sign up at finnhub.io — your key appears on the dashboard immediately.
NewsData.io → powers Leadership & Voice panel with live articles. Sign up at newsdata.io — key appears in your account dashboard.
Without these keys, the Intelligence panel falls back to AI synthesis (clearly labelled) which does not contain real article URLs.
ClickUp, Anthropic, Finnhub, and NewsData all block direct browser requests (CORS). Airtable is the only exception — it works directly. All other APIs must route through the WordPress PHP proxy below. This is why Intelligence panels may show errors without it installed.
This snippet also powers cross-device sync — it stores your dashboard data (tasks, notes, captures, content calendar, revenue target, settings) in a WordPress option so it appears on every device you log into. If you're upgrading from an earlier version, re-paste this snippet to add the sync handler — the sync status pill in the topbar will read "Sync offline" until you do.
Updated to fix the Instagram-idea timeout: the proxy's outbound request limit was 30 seconds — the exact cause of "cURL error 28: Operation timed out after 30002 milliseconds." It's now 55 seconds. Re-paste the snippet below to pick up this fix — the change lives in the PHP, not in this page.
Install once and all live data features plus sync work.
Two options:
Option A — WPCode (recommended): Install the free WPCode plugin → Code Snippets → Add New → paste the snippet below → set type to PHP Snippet → Activate.
Option B — functions.php: Appearance → Theme File Editor → functions.php → paste the snippet before the final ?> closing tag (or at the very end if there is none).
Note: the snippet is written for PHP 5.4+ and all WordPress versions. Do not add <?php — it is already in your file.
/**
* VERITAS Dashboard - API Proxy
* Compatible with PHP 5.4+ and all WordPress versions
* In WPCode: paste as-is (leave "Run snippet" type as PHP)
* In functions.php: paste as-is after the opening <?php line
*/
add_action( 'wp_ajax_veritas_proxy', 'veritas_proxy_handler' );
add_action( 'wp_ajax_nopriv_veritas_proxy', 'veritas_proxy_handler' );
function veritas_proxy_handler() {
// Some idea-generation calls (Instagram especially, with its extra visual-direction
// fields) can take longer than 30s to complete. The old 30s curl timeout below was
// the exact cause of "cURL error 28: Operation timed out after 30002 milliseconds" —
// raised to 55s, with PHP's own execution limit lifted so it doesn't kill the
// request before curl's timeout even has a chance to fire.
if ( function_exists( 'set_time_limit' ) ) {
@set_time_limit( 60 );
}
$raw = isset( $_POST['payload'] ) ? stripslashes( $_POST['payload'] ) : '{}';
$payload = json_decode( $raw, true );
if ( empty( $payload ) || ! isset( $payload['url'] ) ) {
wp_send_json_error( 'No URL provided' );
return;
}
$url = esc_url_raw( $payload['url'] );
$method = isset( $payload['method'] ) ? strtoupper( $payload['method'] ) : 'GET';
$headers = isset( $payload['headers'] ) ? $payload['headers'] : array();
$body = isset( $payload['body'] ) ? $payload['body'] : null;
$args = array(
'method' => $method,
'headers' => $headers,
'timeout' => 55,
'sslverify' => true,
);
if ( ! empty( $body ) ) {
$args['body'] = $body;
}
$response = wp_remote_request( $url, $args );
if ( is_wp_error( $response ) ) {
wp_send_json( array( 'error' => array( 'message' => $response->get_error_message() ) ) );
return;
}
$body_raw = wp_remote_retrieve_body( $response );
$decoded = json_decode( $body_raw, true );
if ( $decoded !== null ) {
echo json_encode( $decoded );
} else {
echo $body_raw;
}
wp_die();
}
/**
* VERITAS Dashboard - Cross-Device Sync
* Stores the full dashboard state as one WordPress option so any device
* logging into the dashboard picks up the latest data. Single-tenant by
* design (one option row) — matches this dashboard's single-user use case.
*/
add_action( 'wp_ajax_veritas_sync', 'veritas_sync_handler' );
add_action( 'wp_ajax_nopriv_veritas_sync', 'veritas_sync_handler' );
function veritas_sync_handler() {
$option_name = 'veritas_dashboard_state';
$option_updated = 'veritas_dashboard_state_updated';
$op = isset( $_POST['op'] ) ? sanitize_text_field( $_POST['op'] ) : '';
if ( $op === 'save' ) {
$raw = isset( $_POST['state'] ) ? stripslashes( $_POST['state'] ) : '';
if ( $raw === '' || json_decode( $raw, true ) === null ) {
wp_send_json_error( 'Invalid state payload' );
return;
}
update_option( $option_name, $raw, false );
$now = time() * 1000; // milliseconds, to match JS Date.now()
update_option( $option_updated, $now, false );
wp_send_json_success( array( 'updated' => $now ) );
} elseif ( $op === 'load' ) {
$raw = get_option( $option_name, '' );
$updated = (int) get_option( $option_updated, 0 );
wp_send_json_success( array( 'state' => $raw, 'updated' => $updated ) );
} else {
wp_send_json_error( 'Unknown sync operation' );
}
wp_die();
}