diff --git a/app/controllers/api/v1/accounts/search_controller.rb b/app/controllers/api/v1/accounts/search_controller.rb
index 35979f70f..13e3a6a6c 100644
--- a/app/controllers/api/v1/accounts/search_controller.rb
+++ b/app/controllers/api/v1/accounts/search_controller.rb
@@ -15,6 +15,10 @@ class Api::V1::Accounts::SearchController < Api::V1::Accounts::BaseController
     @result = search('Message')
   end
 
+  def articles
+    @result = search('Article')
+  end
+
   private
 
   def search(search_type)
diff --git a/app/javascript/dashboard/api/search.js b/app/javascript/dashboard/api/search.js
index 7abb584c0..d533c2f28 100644
--- a/app/javascript/dashboard/api/search.js
+++ b/app/javascript/dashboard/api/search.js
@@ -40,6 +40,15 @@ class SearchAPI extends ApiClient {
       },
     });
   }
+
+  articles({ q, page = 1 }) {
+    return axios.get(`${this.url}/articles`, {
+      params: {
+        q,
+        page: page,
+      },
+    });
+  }
 }
 
 export default new SearchAPI();
diff --git a/app/javascript/dashboard/i18n/locale/en/search.json b/app/javascript/dashboard/i18n/locale/en/search.json
index 3cb566813..e8510ab97 100644
--- a/app/javascript/dashboard/i18n/locale/en/search.json
+++ b/app/javascript/dashboard/i18n/locale/en/search.json
@@ -4,12 +4,14 @@
       "ALL": "All",
       "CONTACTS": "Contacts",
       "CONVERSATIONS": "Conversations",
-      "MESSAGES": "Messages"
+      "MESSAGES": "Messages",
+      "ARTICLES": "Articles"
     },
     "SECTION": {
       "CONTACTS": "Contacts",
       "CONVERSATIONS": "Conversations",
-      "MESSAGES": "Messages"
+      "MESSAGES": "Messages",
+      "ARTICLES": "Articles"
     },
     "VIEW_MORE": "View more",
     "LOAD_MORE": "Load more",
diff --git a/app/javascript/dashboard/modules/search/components/SearchResultArticleItem.vue b/app/javascript/dashboard/modules/search/components/SearchResultArticleItem.vue
new file mode 100644
index 000000000..7e2da950e
--- /dev/null
+++ b/app/javascript/dashboard/modules/search/components/SearchResultArticleItem.vue
@@ -0,0 +1,69 @@
+
+
+
+  
+    
+      
+    
+    
+      
+        
+          {{ title }}
+        
+        
+          {{ category }}
+        
+      
+      
+        {{ truncatedContent }}
+      
+    
                {
         q: 'test',
       });
       expect(dispatch).toHaveBeenCalledWith('messageSearch', { q: 'test' });
+      expect(dispatch).toHaveBeenCalledWith('articleSearch', { q: 'test' });
     });
   });
 
@@ -150,6 +151,30 @@ describe('#actions', () => {
     });
   });
 
+  describe('#articleSearch', () => {
+    it('should handle successful article search', async () => {
+      axios.get.mockResolvedValue({
+        data: { payload: { articles: [{ id: 1 }] } },
+      });
+
+      await actions.articleSearch({ commit }, { q: 'test', page: 1 });
+      expect(commit.mock.calls).toEqual([
+        [types.ARTICLE_SEARCH_SET_UI_FLAG, { isFetching: true }],
+        [types.ARTICLE_SEARCH_SET, [{ id: 1 }]],
+        [types.ARTICLE_SEARCH_SET_UI_FLAG, { isFetching: false }],
+      ]);
+    });
+
+    it('should handle failed article search', async () => {
+      axios.get.mockRejectedValue({});
+      await actions.articleSearch({ commit }, { q: 'test' });
+      expect(commit.mock.calls).toEqual([
+        [types.ARTICLE_SEARCH_SET_UI_FLAG, { isFetching: true }],
+        [types.ARTICLE_SEARCH_SET_UI_FLAG, { isFetching: false }],
+      ]);
+    });
+  });
+
   describe('#clearSearchResults', () => {
     it('should commit clear search results mutation', () => {
       actions.clearSearchResults({ commit });
diff --git a/app/javascript/dashboard/store/modules/specs/conversationSearch/getters.spec.js b/app/javascript/dashboard/store/modules/specs/conversationSearch/getters.spec.js
index ea3ca7048..efce6084a 100644
--- a/app/javascript/dashboard/store/modules/specs/conversationSearch/getters.spec.js
+++ b/app/javascript/dashboard/store/modules/specs/conversationSearch/getters.spec.js
@@ -37,6 +37,15 @@ describe('#getters', () => {
     ]);
   });
 
+  it('getArticleRecords', () => {
+    const state = {
+      articleRecords: [{ id: 1, title: 'Article 1' }],
+    };
+    expect(getters.getArticleRecords(state)).toEqual([
+      { id: 1, title: 'Article 1' },
+    ]);
+  });
+
   it('getUIFlags', () => {
     const state = {
       uiFlags: {
@@ -45,6 +54,7 @@ describe('#getters', () => {
         contact: { isFetching: true },
         message: { isFetching: false },
         conversation: { isFetching: false },
+        article: { isFetching: false },
       },
     };
     expect(getters.getUIFlags(state)).toEqual({
@@ -53,6 +63,7 @@ describe('#getters', () => {
       contact: { isFetching: true },
       message: { isFetching: false },
       conversation: { isFetching: false },
+      article: { isFetching: false },
     });
   });
 });
diff --git a/app/javascript/dashboard/store/modules/specs/conversationSearch/mutations.spec.js b/app/javascript/dashboard/store/modules/specs/conversationSearch/mutations.spec.js
index 7bef2e527..bf7e833d0 100644
--- a/app/javascript/dashboard/store/modules/specs/conversationSearch/mutations.spec.js
+++ b/app/javascript/dashboard/store/modules/specs/conversationSearch/mutations.spec.js
@@ -101,17 +101,39 @@ describe('#mutations', () => {
     });
   });
 
+  describe('#ARTICLE_SEARCH_SET', () => {
+    it('should append new article records to existing ones', () => {
+      const state = { articleRecords: [{ id: 1 }] };
+      mutations[types.ARTICLE_SEARCH_SET](state, [{ id: 2 }]);
+      expect(state.articleRecords).toEqual([{ id: 1 }, { id: 2 }]);
+    });
+  });
+
+  describe('#ARTICLE_SEARCH_SET_UI_FLAG', () => {
+    it('set article search UI flags correctly', () => {
+      const state = {
+        uiFlags: {
+          article: { isFetching: true },
+        },
+      };
+      mutations[types.ARTICLE_SEARCH_SET_UI_FLAG](state, { isFetching: false });
+      expect(state.uiFlags.article).toEqual({ isFetching: false });
+    });
+  });
+
   describe('#CLEAR_SEARCH_RESULTS', () => {
     it('should clear all search records', () => {
       const state = {
         contactRecords: [{ id: 1 }],
         conversationRecords: [{ id: 1 }],
         messageRecords: [{ id: 1 }],
+        articleRecords: [{ id: 1 }],
       };
       mutations[types.CLEAR_SEARCH_RESULTS](state);
       expect(state.contactRecords).toEqual([]);
       expect(state.conversationRecords).toEqual([]);
       expect(state.messageRecords).toEqual([]);
+      expect(state.articleRecords).toEqual([]);
     });
   });
 });
diff --git a/app/javascript/dashboard/store/mutation-types.js b/app/javascript/dashboard/store/mutation-types.js
index a74207e92..f3817c45a 100644
--- a/app/javascript/dashboard/store/mutation-types.js
+++ b/app/javascript/dashboard/store/mutation-types.js
@@ -317,8 +317,10 @@ export default {
   CONVERSATION_SEARCH_SET: 'CONVERSATION_SEARCH_SET',
   CONVERSATION_SEARCH_SET_UI_FLAG: 'CONVERSATION_SEARCH_SET_UI_FLAG',
   MESSAGE_SEARCH_SET: 'MESSAGE_SEARCH_SET',
+  ARTICLE_SEARCH_SET: 'ARTICLE_SEARCH_SET',
   CLEAR_SEARCH_RESULTS: 'CLEAR_SEARCH_RESULTS',
   MESSAGE_SEARCH_SET_UI_FLAG: 'MESSAGE_SEARCH_SET_UI_FLAG',
+  ARTICLE_SEARCH_SET_UI_FLAG: 'ARTICLE_SEARCH_SET_UI_FLAG',
   FULL_SEARCH_SET_UI_FLAG: 'FULL_SEARCH_SET_UI_FLAG',
   SET_CONVERSATION_PARTICIPANTS_UI_FLAG:
     'SET_CONVERSATION_PARTICIPANTS_UI_FLAG',
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 5999c88a6..40d862b19 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -9,8 +9,10 @@ class SearchService
       { conversations: filter_conversations }
     when 'Contact'
       { contacts: filter_contacts }
+    when 'Article'
+      { articles: filter_articles }
     else
-      { contacts: filter_contacts, messages: filter_messages, conversations: filter_conversations }
+      { contacts: filter_contacts, messages: filter_messages, conversations: filter_conversations, articles: filter_articles }
     end
   end
 
@@ -90,4 +92,12 @@ class SearchService
       ILIKE :search OR identifier ILIKE :search", search: "%#{search_query}%"
     ).resolved_contacts.order_on_last_activity_at('desc').page(params[:page]).per(15)
   end
+
+  def filter_articles
+    @articles = current_account.articles
+                               .text_search(search_query)
+                               .reorder('updated_at DESC')
+                               .page(params[:page])
+                               .per(15)
+  end
 end
diff --git a/app/views/api/v1/accounts/search/_article.json.jbuilder b/app/views/api/v1/accounts/search/_article.json.jbuilder
new file mode 100644
index 000000000..a3cf94614
--- /dev/null
+++ b/app/views/api/v1/accounts/search/_article.json.jbuilder
@@ -0,0 +1,8 @@
+json.id article.id
+json.title article.title
+json.locale article.locale
+json.content article.content
+json.slug article.slug
+json.portal_slug article.portal.slug
+json.account_id article.account_id
+json.category_name article.category&.name
diff --git a/app/views/api/v1/accounts/search/_conversation_search_result.json.jbuilder b/app/views/api/v1/accounts/search/_conversation_search_result.json.jbuilder
new file mode 100644
index 000000000..a0b7e0203
--- /dev/null
+++ b/app/views/api/v1/accounts/search/_conversation_search_result.json.jbuilder
@@ -0,0 +1,15 @@
+json.id conversation.display_id
+json.account_id conversation.account_id
+json.created_at conversation.created_at.to_i
+json.message do
+  json.partial! 'message', formats: [:json], message: conversation.messages.try(:first)
+end
+json.contact do
+  json.partial! 'contact', formats: [:json], contact: conversation.contact if conversation.try(:contact).present?
+end
+json.inbox do
+  json.partial! 'inbox', formats: [:json], inbox: conversation.inbox if conversation.try(:inbox).present?
+end
+json.agent do
+  json.partial! 'agent', formats: [:json], agent: conversation.assignee if conversation.try(:assignee).present?
+end
diff --git a/app/views/api/v1/accounts/search/articles.json.jbuilder b/app/views/api/v1/accounts/search/articles.json.jbuilder
new file mode 100644
index 000000000..7d4fe031c
--- /dev/null
+++ b/app/views/api/v1/accounts/search/articles.json.jbuilder
@@ -0,0 +1,7 @@
+json.payload do
+  json.articles do
+    json.array! @result[:articles] do |article|
+      json.partial! 'article', formats: [:json], article: article
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/views/api/v1/accounts/search/index.json.jbuilder b/app/views/api/v1/accounts/search/index.json.jbuilder
index 1c6e86284..a3d8f1858 100644
--- a/app/views/api/v1/accounts/search/index.json.jbuilder
+++ b/app/views/api/v1/accounts/search/index.json.jbuilder
@@ -1,21 +1,7 @@
 json.payload do
   json.conversations do
     json.array! @result[:conversations] do |conversation|
-      json.id conversation.display_id
-      json.account_id conversation.account_id
-      json.created_at conversation.created_at.to_i
-      json.message do
-        json.partial! 'message', formats: [:json], message: conversation.messages.try(:first)
-      end
-      json.contact do
-        json.partial! 'contact', formats: [:json], contact: conversation.contact if conversation.try(:contact).present?
-      end
-      json.inbox do
-        json.partial! 'inbox', formats: [:json], inbox: conversation.inbox if conversation.try(:inbox).present?
-      end
-      json.agent do
-        json.partial! 'agent', formats: [:json], agent: conversation.assignee if conversation.try(:assignee).present?
-      end
+      json.partial! 'conversation_search_result', formats: [:json], conversation: conversation
     end
   end
   json.contacts do
@@ -23,10 +9,14 @@ json.payload do
       json.partial! 'contact', formats: [:json], contact: contact
     end
   end
-
   json.messages do
     json.array! @result[:messages] do |message|
       json.partial! 'message', formats: [:json], message: message
     end
   end
+  json.articles do
+    json.array! @result[:articles] do |article|
+      json.partial! 'article', formats: [:json], article: article
+    end
+  end
 end
diff --git a/config/routes.rb b/config/routes.rb
index 4b4db7b6d..d1705d605 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -137,6 +137,7 @@ Rails.application.routes.draw do
               get :conversations
               get :messages
               get :contacts
+              get :articles
             end
           end
 
diff --git a/spec/controllers/api/v1/accounts/search_controller_spec.rb b/spec/controllers/api/v1/accounts/search_controller_spec.rb
index b5644cebf..ea59bec9c 100644
--- a/spec/controllers/api/v1/accounts/search_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/search_controller_spec.rb
@@ -11,6 +11,11 @@ RSpec.describe 'Search', type: :request do
     create(:message, conversation: conversation, account: account, content: 'test2')
     create(:contact_inbox, contact_id: contact.id, inbox_id: conversation.inbox.id)
     create(:inbox_member, user: agent, inbox: conversation.inbox)
+
+    # Create articles for testing
+    portal = create(:portal, account: account)
+    create(:article, title: 'Test Article Guide', content: 'This is a test article content',
+                     account: account, portal: portal, author: agent, status: 'published')
   end
 
   describe 'GET /api/v1/accounts/{account.id}/search' do
@@ -33,10 +38,11 @@ RSpec.describe 'Search', type: :request do
         response_data = JSON.parse(response.body, symbolize_names: true)
 
         expect(response_data[:payload][:messages].first[:content]).to eq 'test2'
-        expect(response_data[:payload].keys).to contain_exactly(:contacts, :conversations, :messages)
+        expect(response_data[:payload].keys).to contain_exactly(:contacts, :conversations, :messages, :articles)
         expect(response_data[:payload][:messages].length).to eq 2
         expect(response_data[:payload][:conversations].length).to eq 1
         expect(response_data[:payload][:contacts].length).to eq 1
+        expect(response_data[:payload][:articles].length).to eq 1
       end
     end
   end
@@ -115,4 +121,60 @@ RSpec.describe 'Search', type: :request do
       end
     end
   end
+
+  describe 'GET /api/v1/accounts/{account.id}/search/articles' do
+    context 'when it is an unauthenticated user' do
+      it 'returns unauthorized' do
+        get "/api/v1/accounts/#{account.id}/search/articles", params: { q: 'test' }
+
+        expect(response).to have_http_status(:unauthorized)
+      end
+    end
+
+    context 'when it is an authenticated user' do
+      it 'returns all articles containing the search query' do
+        get "/api/v1/accounts/#{account.id}/search/articles",
+            headers: agent.create_new_auth_token,
+            params: { q: 'test' },
+            as: :json
+
+        expect(response).to have_http_status(:success)
+        response_data = JSON.parse(response.body, symbolize_names: true)
+
+        expect(response_data[:payload].keys).to contain_exactly(:articles)
+        expect(response_data[:payload][:articles].length).to eq 1
+        expect(response_data[:payload][:articles].first[:title]).to eq 'Test Article Guide'
+      end
+
+      it 'returns empty results when no articles match the search query' do
+        get "/api/v1/accounts/#{account.id}/search/articles",
+            headers: agent.create_new_auth_token,
+            params: { q: 'nonexistent' },
+            as: :json
+
+        expect(response).to have_http_status(:success)
+        response_data = JSON.parse(response.body, symbolize_names: true)
+
+        expect(response_data[:payload].keys).to contain_exactly(:articles)
+        expect(response_data[:payload][:articles].length).to eq 0
+      end
+
+      it 'supports pagination' do
+        portal = create(:portal, account: account)
+        16.times do |i|
+          create(:article, title: "Test Article #{i}", account: account, portal: portal, author: agent, status: 'published')
+        end
+
+        get "/api/v1/accounts/#{account.id}/search/articles",
+            headers: agent.create_new_auth_token,
+            params: { q: 'test', page: 1 },
+            as: :json
+
+        expect(response).to have_http_status(:success)
+        response_data = JSON.parse(response.body, symbolize_names: true)
+
+        expect(response_data[:payload][:articles].length).to eq 15 # Default per_page is 15
+      end
+    end
+  end
 end
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index af097a2c9..22809d042 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -10,6 +10,11 @@ describe SearchService do
   let!(:harry) { create(:contact, name: 'Harry Potter', email: 'test@test.com', account_id: account.id) }
   let!(:conversation) { create(:conversation, contact: harry, inbox: inbox, account: account) }
   let!(:message) { create(:message, account: account, inbox: inbox, content: 'Harry Potter is a wizard') }
+  let!(:portal) { create(:portal, account: account) }
+  let(:article) do
+    create(:article, title: 'Harry Potter Magic Guide', content: 'Learn about wizardry', account: account, portal: portal, author: user,
+                     status: 'published')
+  end
 
   before do
     create(:inbox_member, user: user, inbox: inbox)
@@ -27,7 +32,7 @@ describe SearchService do
       it 'returns all for all' do
         search_type = 'all'
         search = described_class.new(current_user: user, current_account: account, params: params, search_type: search_type)
-        expect(search.perform.keys).to match_array(%i[contacts messages conversations])
+        expect(search.perform.keys).to match_array(%i[contacts messages conversations articles])
       end
 
       it 'returns contacts for contacts' do
@@ -47,6 +52,12 @@ describe SearchService do
         search = described_class.new(current_user: user, current_account: account, params: params, search_type: search_type)
         expect(search.perform.keys).to match_array(%i[conversations])
       end
+
+      it 'returns articles for articles' do
+        search_type = 'Article'
+        search = described_class.new(current_user: user, current_account: account, params: params, search_type: search_type)
+        expect(search.perform.keys).to match_array(%i[articles])
+      end
     end
 
     context 'when contact search' do
@@ -143,6 +154,50 @@ describe SearchService do
         expect(search.perform[:conversations].map(&:id)).to include new_converstion.id
       end
     end
+
+    context 'when article search' do
+      it 'orders results by updated_at desc' do
+        # Create articles with explicit timestamps
+        older_time = 2.days.ago
+        newer_time = 1.hour.ago
+
+        article2 = create(:article, title: 'Spellcasting Guide',
+                                    account: account, portal: portal, author: user, status: 'published')
+        # rubocop:disable Rails/SkipsModelValidations
+        article2.update_column(:updated_at, older_time)
+        # rubocop:enable Rails/SkipsModelValidations
+
+        article3 = create(:article, title: 'Spellcasting Manual',
+                                    account: account, portal: portal, author: user, status: 'published')
+        # rubocop:disable Rails/SkipsModelValidations
+        article3.update_column(:updated_at, newer_time)
+        # rubocop:enable Rails/SkipsModelValidations
+
+        params = { q: 'Spellcasting' }
+        search = described_class.new(current_user: user, current_account: account, params: params, search_type: 'Article')
+        results = search.perform[:articles]
+
+        # Check the timestamps to understand ordering
+        results.map { |a| [a.id, a.updated_at] }
+
+        # Should be ordered by updated_at desc (newer first)
+        expect(results.length).to eq(2)
+        expect(results.first.updated_at).to be > results.second.updated_at
+      end
+
+      it 'returns paginated results' do
+        # Create many articles to test pagination
+        16.times do |i|
+          create(:article, title: "Magic Article #{i}", account: account, portal: portal, author: user, status: 'published')
+        end
+
+        params = { q: 'Magic', page: 1 }
+        search = described_class.new(current_user: user, current_account: account, params: params, search_type: 'Article')
+        results = search.perform[:articles]
+
+        expect(results.length).to eq(15) # Default per_page is 15
+      end
+    end
   end
 
   describe '#use_gin_search' do