Skip to content
Gaurav TiwariDocs

Hooks and Filters Reference

Updated October 18, 2026

You want a new ticket to post into your own tool, a custom field to reach Chat or your analytics script to survive on the docs pages. Editing the plugin works until the next update wipes it out.

Core Support exposes 55 hooks for this: 13 actions and 42 filters, all named core_support_. This page lists each one with the arguments the code passes and what it changes. Put your code in a small plugin or a code snippets plugin, never in Core Support’s own files.

How to Read This Page

  • Action hooks run your code at a moment. Use add_action().
  • Filter hooks pass a value through your code and use what you return. Use add_filter(), and always return a value of the same type.
  • Arguments are listed in order. When a hook passes more than 1 argument, set the accepted-args count in add_action() or add_filter().
  • Defaults are the values Core Support passes before any filter runs.

Tickets

  • core_support_ticket_created (action): int $ticket_id. Fires after a ticket is opened by anyone other than an agent: a customer in the portal, an email, a form, a connected site or a Chat handoff. Team alerts and the FluentCRM sync run on this hook.
  • core_support_customer_replied (action): int $ticket_id, int $message_id. Fires after a customer’s reply is added to a ticket. Agent replies and notes don’t fire it.
add_action('core_support_ticket_created', function (int $ticket_id): void {
    error_log('New support ticket #' . $ticket_id);
});

Forms and Team Alerts

  • core_support_form_ticket_fields (filter): array $fields, string $plugin, string $form_id. The submitted fields before Core Support picks the email, name, subject and message. Each field is an array with key, label, value and type. $plugin is cf7, wpforms, gravityforms or fluentforms. Core Forms uses its own action and doesn’t pass through this filter.
  • core_support_alert_channels (filter): array $channels. The team alert channels, as objects implementing Gatilab\CoreSupport\Notifications\Channel. The built-in 5 are Telegram, Pushover, Discord, Slack and Webhook. A channel key must be 2 to 31 lowercase letters and digits starting with a letter, and every setting the channel owns starts with that key. Invalid or duplicate keys are skipped.

Open Tickets from Contact Forms and Team Alerts on Telegram, Pushover, Discord, Slack or a Webhook cover the screens these hooks sit behind.

Support, Docs and Changelog Pages

  • core_support_header_links (filter): array $links, string $page. The header links and buttons from Settings → Header and footer. Each link has label, url and style (link, button or primary). $page is docs, changelogs or portal. Links without a label or address are dropped.
  • core_support_footer_links (filter): array $links, string $page. The same for the footer links.
  • core_support_standalone_handles (filter): array $handles, as handle => true. On portal and changelog pages, which load only Core Support’s styles and scripts, this is the full list of handles kept. Add yours, such as an analytics script. On docs pages it starts empty, and a handle you add stays even when it looks like the theme’s.
  • core_support_theme_handle_prefixes (filter): array $prefixes, array $themes. Handle prefixes treated as the active theme’s on docs pages. $themes holds the active theme’s folder name and its parent’s. A prefix ending in - or _ matches the start of a handle.
add_filter('core_support_standalone_handles', function (array $handles): array {
    $handles['my-analytics'] = true;
    return $handles;
});

Docs Pages, Your Theme and Other Plugins explains which styles and scripts each page type keeps.

Changelogs

  • core_support_changelog_category (filter): string $category, string $label. The badge a change label maps to, such as fixed, or other when nothing matches. $label is the label as written. Custom badges from Settings → Changelogs use this filter and come back as custom-{slug}.
  • core_support_changelog_tone (filter): string $tone, string $category. A badge’s color: green, blue, orange, red, yellow or muted, or your own color as a hex code, rgb(), hsl(), oklch() or var(--name).
  • core_support_changelog_intro (filter): string $intro. The line under the heading on /changelogs/, also used as that page’s description. Default: “Every release across our products, newest first.”

Admin Screens

  • core_support_docs_url (filter): string $url, string $topic. The guide a question mark beside an admin section opens, such as https://gauravtiwari.org/docs/core-support/email/imap/. $topic names the section, such as imap, team-alerts or changelogs. Return another https:// address to send the links to your own docs, or an empty string to hide them.
// White-label: point every guide link at your own docs.
add_filter('core_support_docs_url', function (string $url, string $topic): string {
    return 'https://docs.example.com/help-desk/' . $topic . '/';
}, 10, 2);

// Or hide the question marks.
add_filter('core_support_docs_url', '__return_empty_string');

Chat: Placement and Page Context

  • core_support_chat_show_launcher (filter): bool $shown. Whether the chat button loads on the current page, after the Where the button shows settings are applied. Return false to keep it off a page or true to add it. Docs shown inside a connected site’s frame turn it off through this filter.
  • core_support_chat_page_context (filter): array $context, string $origin_url. The page the visitor is on, as sent to the model: url, title, content and post_id.

Chat: Settings

  • core_support_chat_default_settings (filter): array $defaults. Every Chat setting with its default. Saved values and the CORE_SUPPORT_CHAT constant override these.
  • core_support_chat_settings_sanitize (filter): array $output, array $input. The cleaned Chat settings just before they are saved, with the raw form input.

Chat: Providers and Models

  • core_support_chat_pre_llm_provider (filter): null $override, string $provider, string $task. Return an LLMProvider object to replace the chat model completely. $task is answers, followups or titles.
  • core_support_chat_llm_provider (filter): LLMProvider $llm, string $task. The built-in chat provider for a task. The built-in provider is created first, so its API key must already be set.
  • core_support_chat_pre_embedding_provider (filter): null $override, string $provider. Return an EmbeddingProvider object to replace the search model completely.
  • core_support_chat_embedding_provider (filter): EmbeddingProvider $embeddings. The built-in search model.
  • core_support_chat_embedding_dimensions (filter): int $dimensions, string $provider, string $model. The vector size stored for a search model. Default 512; 0 uses the model’s full size. $provider is openai or voyage. Changing it learns every post again in the background.
  • core_support_chat_moderation_provider (filter): ModerationProvider $moderation. The message check that runs before an answer. It uses OpenAI moderation when an OpenAI key is saved, and no check otherwise.
  • core_support_chat_vector_store (filter): VectorStore $store. Where learned passages are stored and searched. Default: the site’s database.
  • core_support_chat_model_catalog (filter): array $catalog. The providers, models, search models and thinking levels shown in Chat settings.
  • core_support_chat_is_reasoning_model (filter): bool $is_reasoning, string $model. Runs only for a model the built-in list doesn’t recognize, with false. Return true for a model that takes max_completion_tokens and refuses custom sampling values.
  • core_support_chat_http_timeout (filter): int $seconds. The timeout for provider requests. Default 60, minimum 1.

Chat: What It Learns

  • core_support_chat_post_html (filter): string $html, WP_Post $post. A post’s HTML after the_content, before it’s split into passages. Changelogs use it to add their kept release history.
  • core_support_chat_chunk_context (filter): string $context, WP_Post $post. The line every passage of a post starts with. Default: the title, after the docs product when there is one.
  • core_support_chat_post_fields (filter): array $fields, WP_Post $post. The custom fields Chat learns from a post. Each has name, label and value. Values you add are cleaned the same way, and empty ones are dropped.
  • core_support_chat_product_facts (filter): array $lines, WP_Post $post. The “Product facts” lines learned with a product, as Label: value strings. Add lines for your own product data or post types. Each line is cut at 400 characters and duplicates are dropped.
  • core_support_chat_watched_meta (filter): array $keys. Post meta keys whose changes mark a post for learning again. Changelogs add their release dates, pre-releases and kept history.
  • core_support_chat_max_queued_posts (filter): int $max, string $post_type. The most posts one reindex request queues. Default 5000.
  • core_support_chat_sweep_batch (filter): int $batch. The most posts one 30-minute check learns. Default 25, minimum 1.
  • core_support_chat_sweep_checks (filter): int $checks. How many unchanged learned posts each check also compares, oldest first, for changes no hook reported. Default 10; 0 turns it off.
  • core_support_chat_sweep_seconds (filter): int $seconds. How long one check may spend learning. Default 20, minimum 5.
add_filter('core_support_chat_product_facts', function (array $lines, WP_Post $post): array {
    $warranty = get_post_meta($post->ID, 'warranty_months', true);
    if ($warranty !== '') {
        $lines[] = 'Warranty: ' . $warranty . ' months';
    }
    return $lines;
}, 10, 2);

Chat: Search and the Prompt

  • core_support_chat_retrieved_chunks (filter): array $chunks, string $message. The passages chosen for an answer, before they are sent to the model. Each has id, score and metadata.
  • core_support_chat_full_scan_max_chunks (filter): int $max, string $embedding_model, int $dimensions. The most passages compared with every question. Default 5,000 at 512 dimensions, proportionally fewer for longer vectors. Above it, search scores a shortlist from word search.
  • core_support_chat_retrieval_candidates (filter): array $rows, string $text_query, string $embedding_model. The shortlist rows before they are scored. It runs only when search works from a shortlist instead of every passage.
  • core_support_chat_fallback_candidates (filter): int $limit. How many passages are scanned when word search finds nothing, above the full-scan limit. Default 400.
  • core_support_chat_rrf_k (filter): int $k. The constant used to combine meaning and word rankings. Default 60, minimum 1. Lower values give the top of each ranking more weight.
  • core_support_chat_max_prompt_faqs (filter): int $max, string $message. How many curated Q&A entries go into the prompt. Default 12; 0 sends every enabled entry.

These filters run while the visitor waits for an answer, so a higher limit costs response time.

Chat: Visitors and Limits

  • core_support_chat_trust_cloudflare (filter): bool $trust. Whether Cloudflare’s published edge ranges count as trusted proxies when Chat reads the visitor’s address. Default true.
  • core_support_chat_trusted_proxies (filter): array $proxies. Proxy addresses and CIDR ranges whose forwarding headers are trusted, after CORE_SUPPORT_TRUSTED_PROXIES and the Cloudflare ranges are added.
  • core_support_chat_rate_limit (filter): array $limits, string $bucket. The limit for one Chat bucket as [limit, window in seconds]. A limit or window of 0 turns that bucket off. The buckets and their defaults: – chat_session: 20 messages a minute per conversation, [20, 60] – chat_ip: 60 messages in 10 minutes per IP address, [60, 600] – chat_global: 240 messages a minute for the whole site, [240, 60] – contact_ip: 5 tickets an hour per IP address from “Talk to a person”, [5, 3600]
add_filter('core_support_chat_rate_limit', function (array $limits, string $bucket): array {
    return $bucket === 'chat_ip' ? [120, 600] : $limits;
}, 10, 2);

Chat: Actions

  • core_support_chat_message_answered (action): int $thread_id, string $message, string $reply, array $sources. After Chat answers a question.
  • core_support_chat_unanswered_question (action): int $thread_id, string $message. After an answer for which search found no passages. Useful for finding gaps in your docs.
  • core_support_chat_message_flagged (action): string $message, array $moderation. When moderation flags a message. $moderation has flagged, categories and scores. The visitor gets the fallback message.
  • core_support_chat_handoff (action): int $thread_id, int $ticket_id. After a conversation becomes a ticket through “Talk to a person”.
  • core_support_chat_thread_titled (action): int $thread_id, string $title. After the model names a conversation. It never fires while Conversation titles is set to No model: first words of the question.
  • core_support_chat_post_indexed (action): int $post_id, int $chunk_count. After a post is learned.
  • core_support_chat_post_index_skipped (action): int $post_id. When a post’s passages haven’t changed, so no embedding request is made.
  • core_support_chat_post_index_busy (action): int $post_id. When another run is already learning the post. Core Support marks it to learn again.
  • core_support_chat_post_forgotten (action): int $post_id. After a post’s passages are removed.
  • core_support_chat_search_model_switched (action): string $from, string $to. When search switches to a newly learned model. The old model’s passages are deleted next.
  • core_support_chat_sweep_done (action): array $result. After a 30-minute check, with time, learned, unchanged, forgotten, waiting and failed.
add_action('core_support_chat_unanswered_question', function (int $thread_id, string $message): void {
    error_log('Chat had no docs for: ' . $message);
}, 10, 2);

Good to Know

  • Agent actions such as a reply, a private note, a status change or an assignment have no hooks in 0.9.4.
  • Scheduled event hooks such as core_support_deliver are WP-Cron events, not extension points. Diagnostics and WP-CLI Commands lists them.
  • Return the type a filter expects. The header and footer link filters, for example, fall back to the original links when you don’t return an array.
Share

Was this helpful?

Still stuck? Open a support ticket