Hooks Reference

Every action and filter ApproxIt exposes. Hook into these to customize behavior without modifying core code.

Hooks are grouped by lifecycle phase. All names are prefixed ax_.

Lifecycle

ax_loaded — action

Fires once after all ApproxIt classes are initialized on plugins_loaded:10. Safest hook to register your own integrations on.

PHP

add_action( 'ax_loaded', function () {
    // All ApproxIt classes are now available.
} );

ax_register_settings — action

Fires during register_settings() on admin_init. Use to register your own settings on the ax_settings_group group.

PHP

add_action( 'ax_register_settings', function () {
    register_setting( 'ax_settings_group', 'my_custom_option' );
} );

Lead Submission

ax_lead_submission_data — filter

Filters the lead data array before it is saved. Pro uses this to append map data; you can use it to add any custom fields posted with the form.

Signature: apply_filters( 'ax_lead_submission_data', array $data, array $post )

  • $data — The lead data array being built. Keys: estimator_id, mode, services, package, totals, etc.
  • $post — The raw $_POST superglobal at submission time.

PHP

add_filter( 'ax_lead_submission_data', function ( $data, $post ) {
    if ( ! empty( $post['custom_field'] ) ) {
        $data['custom_field'] = sanitize_text_field( $post['custom_field'] );
    }
    return $data;
}, 10, 2 );

ax_lead_semantic_score — filter

Filters the semantic priority score for a lead. Pro hooks this to run a Gemini classifier on the customer’s notes. Default value is null (no semantic bonus).

Signature: apply_filters( 'ax_lead_semantic_score', mixed $current, string $notes, array $data )

Expected return shape (if not null): array{ priority: 'high'|'medium'|'low', points: int, reason: string }.

PHP

add_filter( 'ax_lead_semantic_score', function ( $current, $notes, $data ) {
    if ( stripos( $notes, 'asap' ) !== false ) {
        return array(
            'priority' => 'high',
            'points'   => 20,
            'reason'   => 'Customer indicated urgency.',
        );
    }
    return $current;
}, 10, 3 );

ax_lead_score — filter

Filters the final lead score result before it is stored on the lead meta. Pro uses this to add a map-area bonus.

Signature: apply_filters( 'ax_lead_score', array $result, array $data )

  • $resultarray{ points: int, label: 'hot'|'warm'|'cold' }
  • $data — The lead data array.

PHP

add_filter( 'ax_lead_score', function ( $result, $data ) {
    // Add 5 bonus points for leads from a specific estimator.
    if ( (int) ( $data['estimator_id'] ?? 0 ) === 42 ) {
        $result['points'] += 5;
        if ( $result['points'] >= 70 )      $result['label'] = 'hot';
        elseif ( $result['points'] >= 40 )  $result['label'] = 'warm';
    }
    return $result;
}, 10, 2 );

ax_lead_meta_to_save — filter

Filters the meta array right before it is written to the lead post. Pro uses this to append _ax_lead_photos (uploaded attachment IDs) and map metadata.

Signature: apply_filters( 'ax_lead_meta_to_save', array $meta, int $post_id, array $data )

PHP

add_filter( 'ax_lead_meta_to_save', function ( $meta, $post_id, $data ) {
    $meta['_ax_lead_source_referrer'] = sanitize_text_field( $_SERVER['HTTP_REFERER'] ?? '' );
    return $meta;
}, 10, 3 );

ax_lead_created — action

Fires after the lead is fully saved (post + meta). Lite uses this to send email notifications. Pro adds SMS and abandoned-lead nudge scheduling.

Signature: do_action( 'ax_lead_created', int $post_id )

PHP

add_action( 'ax_lead_created', function ( $post_id ) {
    // Forward to your own CRM, Slack, Zapier, etc.
    wp_remote_post( 'https://your-crm.example/webhook', array(
        'body' => array(
            'lead_id' => $post_id,
            'name'    => get_the_title( $post_id ),
            'email'   => get_post_meta( $post_id, '_ax_lead_email', true ),
            'score'   => get_post_meta( $post_id, '_ax_lead_score', true ),
            'total'   => get_post_meta( $post_id, '_ax_lead_total', true ),
        ),
    ) );
} );

Lead Lifecycle

ax_lead_status_updated — action

Fires when the lead status changes (from the admin dropdown).

Signature: do_action( 'ax_lead_status_updated', int $post_id, string $new, string $old )

Status values: new, contacted, quoted, won, lost.

PHP

add_action( 'ax_lead_status_updated', function ( $post_id, $new, $old ) {
    if ( $new === 'won' ) {
        // Trigger a thank-you email, CRM update, etc.
    }
}, 10, 3 );

ax_lead_abandoned — action (Pro Only)

Fires from the Pro abandoned-beacon endpoint when a customer leaves the form without submitting. Lite never fires this hook.

Signature: do_action( 'ax_lead_abandoned', array $data )

ax_send_customer_nudge — action (Pro Only)

Scheduled WP-Cron event 30 minutes after submission. Pro uses it to send a follow-up SMS if the status is still new. You can subscribe to send your own follow-up email, Slack notification, etc.

Signature: do_action( 'ax_send_customer_nudge', int $post_id )

Email

ax_send_notification_email — filter

Allows alternative delivery handlers to intercept email. Pro’s SendGrid integration returns true from this filter when it has handled the send; if the filter returns falsy, ApproxIt falls back to wp_mail().

Signature: apply_filters( 'ax_send_notification_email', bool $handled, string $to_email, string $to_name, string $subject, string $html )

PHP

add_filter( 'ax_send_notification_email', function ( $handled, $to, $to_name, $subject, $html ) {
    if ( $handled ) return $handled;
    // Send via your own transactional service.
    $ok = my_custom_send( $to, $subject, $html );
    return $ok ? true : false;
}, 5, 5 );

Use a low priority (like 5) if you want to run before Pro’s SendGrid handler at default priority 10.

Frontend

ax_calculator_config — filter

Filters the JS config object passed to the frontend calculator. Pro uses this to inject the Maps API key, Gemini key, and the hasMap flag.

Signature: apply_filters( 'ax_calculator_config', array $config )

PHP

add_filter( 'ax_calculator_config', function ( $config ) {
    $config['my_custom_flag'] = true;
    return $config;
} );

The full config is exposed to JS as axCalcConfig.

ax_enqueue_public_scripts — action

Fires after Lite enqueues its public-facing scripts. Pro uses this to enqueue its map drawing and photo upload scripts.

Signature: do_action( 'ax_enqueue_public_scripts' )

ax_enqueue_leads_scripts — action

Same as above, but for the admin leads dashboard.

Templates

ax_templates_all — filter

Filters the registered industry templates array. Pro uses this to inject its seven additional templates. Returns associative array keyed by template slug.

Signature: apply_filters( 'ax_templates_all', array $templates )

PHP

add_filter( 'ax_templates_all', function ( $templates ) {
    $templates['my_industry'] = array(
        'tier'   => 'free',
        'meta'   => array(
            'label'   => 'My Industry',
            'icon'    => '⚒️',
            'color'   => '#0F172A',
            'tagline' => 'Custom services for my niche',
        ),
        'accent'    => '#0F172A',
        'services'  => array( /* ... */ ),
        'packages'  => array(),
        'questions' => array(),
    );
    return $templates;
} );

See includes/class-templates.php for the service / package / question helper functions (svc(), pkg(), q_select(), etc.).

Admin UI Injection

These actions let you inject markup into specific admin views.

ax_lead_detail_zone1 / zone2 / zone3 — action

Three injection points in the lead detail card. Pro uses these to render photo galleries, AI analysis, property intelligence, and the timeline.

Signature: do_action( 'ax_lead_detail_zone1', int $lead_id, array $data, string $status, string $score )

ax_leads_after_stats — action

Fires after the lead-dashboard stats row. Pro uses this to render its analytics panel.

ax_est_card_extra — action

Fires inside each estimator card on the estimators list. Pro renders a 7-day lead sparkline; Lite renders an upsell.

Signature: do_action( 'ax_est_card_extra', int $estimator_id )

ax_est_card_actions — action

Fires in the action area of each estimator card. Pro renders a Duplicate button.

ax_settings_tab_general / tab_connectivity / tab_communications — action

Three injection points in the settings page tabs. Use these to add your own settings fields without modifying the settings view directly.

PHP

add_action( 'ax_settings_tab_general', function () {
    ?>
    <div class="ax-stf-block">
        <label for="my_field">My Setting</label>
        <input type="text" id="my_field" name="my_field" value="<?php echo esc_attr( get_option( 'my_field', '' ) ); ?>">
    </div>
    <?php
} );

ax_leads_ajax_init — action

Fires during the admin AJAX registration phase. Use to register your own admin AJAX handlers in the same lifecycle as Lite’s.

Hook Execution Order (Visual)

A typical lead submission fires these hooks in order:

Plaintext

Customer submits form
        ↓
ax_lead_submission_data (filter — augment $data)
        ↓
ax_lead_semantic_score (filter — Pro classifier)
        ↓
ax_lead_score (filter — final score adjustments)
        ↓
ax_lead_meta_to_save (filter — augment meta)
        ↓
ax_lead_created (action — notifications)
        ↓
   wp_send_json_success()