Give your sales team an assistant who answers their questions 24/7

Your reps lose 100+ hours/month chasing answers.

NextKS delivers instant answers on product, process, and pricing questions - right inside Slack.
Just plug it in - your reps stay in flow, new hires ramp faster, and repeated questions disappear.
Even if:
▪️You already have knowledge sharing tools and processes. Or internal support.
▪️Your data is scattered all over the place and written in different languages.
▪️The quality of your existing data is rather questionable.

const voiceBtn = document.getElementById('voiceBtn'); const voiceLabel = document.getElementById('voiceLabel'); const waveform = document.getElementById('waveform'); const spinner = document.getElementById('spinner'); const statusBox = document.getElementById('statusBox'); const statusText = document.getElementById('statusText'); const listeningSpinner = document.getElementById('listeningDots'); const STATE = { IDLE: 'idle', INIT: 'initializing', MICINIT: 'initializing mic', LISTEN: 'listening', PROC: 'processing', SPEAK: 'speaking' }; let currentState = STATE.IDLE; let ws, audioCtx, micNode, procNode, inputStream; let playbackQueue = []; let isEndOfStream = false; let isPlaying = false; let currentSource = null; function logState(to) { console.log(`→ State: ${to}`); currentState = to; switch (to) { case STATE.IDLE: statusBox.style.display = 'none'; voiceLabel.textContent = "📞AI Voice Assistant - ask anything"; spinner.classList.remove('active'); waveform.classList.remove('active'); statusText.textContent = ''; listeningSpinner.style.display = 'none'; break; case STATE.INIT: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Hang up'; spinner.classList.add('active'); waveform.classList.remove('active'); statusText.textContent = 'Connecting…'; listeningSpinner.style.display = 'none'; break; case STATE.MICINIT: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Hang up'; spinner.classList.add('active'); waveform.classList.remove('active'); statusText.textContent = 'Initializaing mic…'; listeningSpinner.style.display = 'none'; break; case STATE.LISTEN: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Hang up'; spinner.classList.remove('active'); waveform.classList.remove('active'); statusText.textContent = "I'm listening"; listeningSpinner.style.display = 'inline-flex'; break; case STATE.PROC: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Hang up'; spinner.classList.add('active'); waveform.classList.remove('active'); statusText.textContent = 'Thinking, hang on a sec…'; listeningSpinner.style.display = 'none'; break; case STATE.SPEAK: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Hang up'; spinner.classList.remove('active'); waveform.classList.add('active'); statusText.textContent = ''; listeningSpinner.style.display = 'none'; break; } } voiceBtn.onclick = () => { if (currentState === STATE.IDLE) { startSession(); } else { stopSession(); } }; function stopSession() { console.log('Stopping session…'); ws.send(JSON.stringify({ event: 'stop_session' })); ws.close(); if (currentSource) { currentSource.stop(); currentSource = null; } playbackQueue = []; isEndOfStream = true; isPlaying = false; teardownAudio(); logState(STATE.IDLE); } async function startSession() { logState(STATE.INIT); /* 1) Check server health */ try { /*const resp = await fetch('https://voiceassistant2.onrender.com/');*/ const resp = await fetch('https://voice-assistant-927518067979.europe-west1.run.app'); if (!resp.ok) throw new Error(`Status ${resp.status}`); console.log('Server healthy, opening WS…'); } catch (err) { console.error('Server health check failed:', err); return; /* bail out */ } /*ws = new WebSocket('wss://voiceassistant2.onrender.com/ws');*/ ws = new WebSocket('wss://voice-assistant-927518067979.europe-west1.run.app/ws'); ws.onopen = () => { console.log('WS open, sending handshake'); ws.send(JSON.stringify({ event: 'handshake', thread_id: localStorage.getItem('thread_id') || null })); }; ws.onmessage = async (evt) => { /* 1) Control messages (JSON text) */ if (typeof evt.data === 'string') { let msg; try { msg = JSON.parse(evt.data); } catch (e) { console.warn('Bad JSON from server:', evt.data); return; } switch (msg.event) { case 'handshake_ack': console.log('Handshake ACK, thread_id=', msg.thread_id); localStorage.setItem('thread_id', msg.thread_id); await startMic(); logState(STATE.PROC); break; case 'utterance_done': console.log('Received utterance_done → marking end of stream'); isEndOfStream = true; break; default: console.warn('ws.onmessage unknown event:', msg.event); } return; } /* 2) Binary messages = raw PCM from server if (evt.data instanceof ArrayBuffer) { if (evt.data.byteLength === 0) return; playbackQueue.push(evt.data); return; }*/ /* binary messages come in as Blobs in some browsers */ if (evt.data instanceof Blob || evt.data instanceof ArrayBuffer) { playbackQueue.push(evt.data); if (currentState !== STATE.SPEAK) { logState(STATE.SPEAK); playLoop(); } return; } /* 3) Anything else */ console.warn('ws.onmessage received unexpected data type:', evt.data); }; ws.onclose = (e) => { console.log('WebSocket closed:', e.code, e.reason); teardownAudio(); logState(STATE.IDLE); }; ws.onerror = (e) => { console.error('WebSocket error:', e); }; } async function startMic() { logState(STATE.MICINIT); audioCtx = new AudioContext({ sampleRate: 24000 }); const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mic = audioCtx.createMediaStreamSource(stream); const proc = audioCtx.createScriptProcessor(4096, 1, 1); proc.onaudioprocess = (e) => { if (currentState !== STATE.LISTEN) return; const inF32 = e.inputBuffer.getChannelData(0); const int16 = new Int16Array(inF32.length); for (let i = 0; i < inF32.length; i++) { const s = Math.max(-1, Math.min(1, inF32[i])); int16[i] = s < 0 ? s * 0x8000 : s * 0x7FFF; } ws.send(int16.buffer); }; mic.connect(proc); proc.connect(audioCtx.destination); micNode = mic; procNode = proc; inputStream = stream; /*logState(STATE.INIT);*/ /*detectSilence(audioCtx, mic, proc, stream);*/ } function teardownAudio() { if (procNode) { procNode.disconnect(); procNode = null; } if (micNode) { micNode.disconnect(); micNode = null; } if (inputStream) { inputStream.getTracks().forEach(t => t.stop()); inputStream = null; } if (audioCtx && audioCtx.state !== 'closed') { audioCtx.close(); } audioCtx = null; } function detectSilence(ctx, mic, proc, stream) { const analyser = ctx.createAnalyser(); mic.connect(analyser); analyser.fftSize = 512; const data = new Uint8Array(analyser.frequencyBinCount); const thresh = 9; const delay = 1500; let speechStarted = false; let silentSince = null; (function check() { analyser.getByteFrequencyData(data); const avg = data.reduce((a,b)=>a+b,0)/data.length; if (!speechStarted) { if (avg >= thresh) { speechStarted = true; console.log('Speech started—now watching for silence'); silentSince = Date.now(); } } else { if (avg < thresh) { /* if silence continues long enough, stop */ if (Date.now() - silentSince > delay) { console.log('Silence detected → end_audio (mic still open)'); logState(STATE.PROC); ws.send(JSON.stringify({ event: 'end_audio' })); return; } } else { /* reset timer while speech continues */ silentSince = Date.now(); } } requestAnimationFrame(check); })(); } async function playLoop() { if (isPlaying) return; isPlaying = true; if (!window.__playCtx) { window.__playCtx = new AudioContext(); await window.__playCtx.resume(); } const ctx = window.__playCtx; logState(STATE.SPEAK); const FRAME_RATE = 24000; while (!isEndOfStream || playbackQueue.length > 0) { if (playbackQueue.length === 0) { await new Promise(r => setTimeout(r, 50)); continue; } /* 1) Pop the next raw chunk (Blob or ArrayBuffer) */ const raw = playbackQueue.shift(); /* 2) Convert to ArrayBuffer if needed*/ let buf; if (raw instanceof Blob) { buf = await raw.arrayBuffer(); } else { buf = raw; } if (buf.byteLength === 0) continue; /* 3) Decode & play at correct sample rate*/ const int16 = new Int16Array(buf); const f32 = new Float32Array(int16.length); for (let i = 0; i < int16.length; i++) { f32[i] = int16[i] / 32768; } const audioBuf = ctx.createBuffer(1, f32.length, FRAME_RATE); audioBuf.copyToChannel(f32, 0); const src = ctx.createBufferSource(); src.buffer = audioBuf; src.connect(ctx.destination); currentSource = src; /* 4) Wait its true duration*/ await new Promise(resolve => { src.onended = () => { if (currentSource === src) currentSource = null; resolve(); }; src.start(); }); } console.log('✅ Playback complete'); isEndOfStream = false; isPlaying = false; logState(STATE.LISTEN); detectSilence(audioCtx, micNode, procNode, inputStream); } /* initialize UI to the starting state*/ logState(STATE.IDLE);

“..it has proven to be a game-changer for us.” - Director of Technical Support, Lokalise

 

 

Instant setup & instant benefits

Get started with a one-click setup and a 15-minute onboarding. Enjoy instant improvements without any extra headaches.

Your 1st line of sales support

Equip your sales team with instant answers to pricing, playbooks, objections, and product details - so they can close deals faster.

No more language barriers

Now, you can access knowledge and get answers instantly in any language - no matter what language it’s in.

No AI training or migration

No extra processes, no discruptive changes. Keep using Slack, Confluence, web docs, and your current tools. NextKS plugs in seamlessly.

100+ hours saved/month

Free up your best talents from answering repetitive Q&A. Save up to 20% of your employes' time McKinsey & Company research

Auto-assign and avoid spam messages

Avoid spamming colleagues. Turn your question into a Q&A ticket directly in Slack and autoassign the right SME.

Uncover the Cost of Inefficient Communication


Business Calculator

Result

Your inefficient internal knowledge sharing costs you approximately 0 every year.

Your revenue is probably lower by 0 every year due to inefficient Sales & CSM onboarding.

Join Our Early Access Program


We’re looking for fast-growing companies to help us shape the future of knowledge sharing.
Here’s what you’ll get:

Free Access
Get full access to our solution for free during the beta period—no strings attached.

Exclusive Insights
As a beta partner, you’ll have first access to our dashboard that tracks knowledge sharing and team adoption.

Early Adopter Perks
Be part of the core group shaping how this tool works. Your feedback will directly impact its design and features.

Discounted Pricing
Enjoy special early adopter discounts when the full version launches.

Recognition
Gain early recognition as an innovator—we’ll spotlight your team’s success (with your permission) in our case studies.

Features


NextKS Framework helps your team get answers instantly, without endless back-and-forth. It uses AI to respond directly in Slack or routes questions to the right expert, cutting down wasted time and reducing bottlenecks. No more digging through threads or waiting for replies—just fast, accurate answers when and where you need them.▪️NextKS Assistant - delivers instant answers - or connects you with the right SME in seconds.
▪️NextKS Portal - gives you deep insights into your organization's knowledge flow, from overreliance on key experts to trending topics.

1. AI-Powered Intelligent Chat

Engage with a smart assistant that taps into your company-wide knowledge, directly from Slack. Powered by AI, the NextKS Assistant provides instant, insightful responses based on your team's collective expertise. Say goodbye to long waits and embrace quick, reliable answers without leaving your workspace.

2. Integrated Question Ticketing System

Easily turn unresolved queries into tickets that automatically involve only the relevant experts—no spam or unnecessary disturbances for the rest of the team. This Slack-based system ensures smooth collaboration, so you get the right answer, fast, with minimal distractions.

3. Smart Knowledge Retention

Once a question is answered and accepted, it’s stored in a dynamic, company-wide knowledge base for future use, ensuring that every question is answered only once. With each interaction, your team builds a long-lasting resource that continuously grows and improves, giving you access to previously solved problems at your fingertips.

4. Expert Discovery & Connection

Automatically connect with the right experts across your company when the AI can’t provide an answer. The system ensures that only those with the knowledge are involved, making knowledge-sharing efficient and focused. Stop searching for answers—NextKS brings the experts directly to you, within Slack.

5. Platform Analytics

This analytics dashboard provides you with all essential metrics related to the platform's usage. You can track the adoption rate, trending topics, and the approximate number of hours the tool saved in your organization.

Testimonials


Dmitry Olenov, Director of Technical Support at Lokalise.

We recently began integrating the NextKS tool to enhance our internal technical support, and it has proven to be a game-changer for us. Aligning seamlessly with our long-term vision, NextKS is setting a new standard for how Internal Support should function on a company level.
It's the solution we have been dreaming of ...
Read the full text

Dmitry Olenov, Director of Technical Support at Lokalise.

We recently began integrating the NextKS tool to enhance our internal technical support, and it has proven to be a game-changer for us. Aligning seamlessly with our long-term vision, NextKS is setting a new standard for how Internal Support should function on a company level.
During the early stages of implementation, feedback from our support managers and staff has been overwhelmingly positive. It's the solution we have been dreaming of, striking the perfect balance between cutting-edge AI technology and human collaboration. This synergy provides us with an efficient, scalable and streamlined support experience.
Remarkably, we've observed an increase in incoming inquiries, as people are less hesitant to ask questions when those are private. Simultaneously, the number of requests needing dedicated Support specialist intervention has decreased significantly, demonstrating NextKS's effectiveness in empowering users and resolving issues autonomously. We are excited about the continued positive impact this tool will have on our operations and growth.

Lokalise Case Study

About Us


At NextKS, we’re on a mission to drive team growth and efficiency by simplifying knowledge sharing.Our vision is simple:
To make work life easier - by turning knowledge sharing into a seamless, frustration-free experience.
We believe that work life should be easier, more enjoyable, and free from constant frustration. We understand that when information is buried in endless messages, documents, or locked away in people’s heads, it holds your team back. We’ve designed NextKS to eliminate those obstacles by making knowledge sharing effortless, intuitive, and accessible to everyone - no matter where they are or what language they speak. With a powerful AI Assistant and a streamlined Q&A workflow, we ensure that your team can focus on what truly matters: doing their best work and enjoying the process.Welcome to a new era of collaboration and knowledge sharing.
Welcome to NextKS.

Team


Milan Karásek
Lead Software Engineer

Tomas Franc
Founder, CEO

Liam James
Founder’s Associate (Biz Dev focus)

const voiceBtn = document.getElementById('voiceBtn'); const voiceLabel = document.getElementById('voiceLabel'); const waveform = document.getElementById('waveform'); const spinner = document.getElementById('spinner'); const statusBox = document.getElementById('statusBox'); const statusText = document.getElementById('statusText'); const listeningSpinner = document.getElementById('listeningDots'); const STATE = { IDLE: 'idle', INIT: 'initializing', MICINIT: 'initializing mic', LISTEN: 'listening', PROC: 'processing', SPEAK: 'speaking' }; let currentState = STATE.IDLE; let ws, audioCtx, micNode, procNode, inputStream; let playbackQueue = []; let isEndOfStream = false; let isPlaying = false; let currentSource = null; function logState(to) { console.log(`→ State: ${to}`); currentState = to; switch (to) { case STATE.IDLE: statusBox.style.display = 'none'; voiceLabel.textContent = "📞AI Voice Assistant - ask anything"; spinner.classList.remove('active'); waveform.classList.remove('active'); statusText.textContent = ''; listeningSpinner.style.display = 'none'; break; case STATE.INIT: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Stop'; spinner.classList.add('active'); waveform.classList.remove('active'); statusText.textContent = 'Connecting…'; listeningSpinner.style.display = 'none'; break; case STATE.MICINIT: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Stop'; spinner.classList.add('active'); waveform.classList.remove('active'); statusText.textContent = 'Initializaing mic…'; listeningSpinner.style.display = 'none'; break; case STATE.LISTEN: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Stop'; spinner.classList.remove('active'); waveform.classList.remove('active'); statusText.textContent = "I'm listening"; listeningSpinner.style.display = 'inline-flex'; break; case STATE.PROC: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Stop'; spinner.classList.add('active'); waveform.classList.remove('active'); statusText.textContent = 'Thinking, hang on a sec…'; listeningSpinner.style.display = 'none'; break; case STATE.SPEAK: statusBox.style.display = 'inline-flex'; voiceLabel.textContent = '☎️ Stop'; spinner.classList.remove('active'); waveform.classList.add('active'); statusText.textContent = ''; listeningSpinner.style.display = 'none'; break; } } voiceBtn.onclick = () => { if (currentState === STATE.IDLE) { startSession(); } else { stopSession(); } }; function stopSession() { console.log('Stopping session…'); ws.send(JSON.stringify({ event: 'stop_session' })); ws.close(); if (currentSource) { currentSource.stop(); currentSource = null; } playbackQueue = []; isEndOfStream = true; isPlaying = false; teardownAudio(); logState(STATE.IDLE); } async function startSession() { logState(STATE.INIT); /* 1) Check server health */ try { /*const resp = await fetch('https://voiceassistant2.onrender.com/');*/ const resp = await fetch('https://voice-assistant-927518067979.europe-west1.run.app'); if (!resp.ok) throw new Error(`Status ${resp.status}`); console.log('Server healthy, opening WS…'); } catch (err) { console.error('Server health check failed:', err); return; /* bail out */ } /*ws = new WebSocket('wss://voiceassistant2.onrender.com/ws');*/ ws = new WebSocket('wss://voice-assistant-927518067979.europe-west1.run.app/ws'); ws.onopen = () => { console.log('WS open, sending handshake'); ws.send(JSON.stringify({ event: 'handshake', thread_id: localStorage.getItem('thread_id') || null })); }; ws.onmessage = async (evt) => { /* 1) Control messages (JSON text) */ if (typeof evt.data === 'string') { let msg; try { msg = JSON.parse(evt.data); } catch (e) { console.warn('Bad JSON from server:', evt.data); return; } switch (msg.event) { case 'handshake_ack': console.log('Handshake ACK, thread_id=', msg.thread_id); localStorage.setItem('thread_id', msg.thread_id); await startMic(); logState(STATE.PROC); break; case 'utterance_done': console.log('Received utterance_done → marking end of stream'); isEndOfStream = true; break; default: console.warn('ws.onmessage unknown event:', msg.event); } return; } /* 2) Binary messages = raw PCM from server if (evt.data instanceof ArrayBuffer) { if (evt.data.byteLength === 0) return; playbackQueue.push(evt.data); return; }*/ /* binary messages come in as Blobs in some browsers */ if (evt.data instanceof Blob || evt.data instanceof ArrayBuffer) { playbackQueue.push(evt.data); if (currentState !== STATE.SPEAK) { logState(STATE.SPEAK); playLoop(); } return; } /* 3) Anything else */ console.warn('ws.onmessage received unexpected data type:', evt.data); }; ws.onclose = (e) => { console.log('WebSocket closed:', e.code, e.reason); teardownAudio(); logState(STATE.IDLE); }; ws.onerror = (e) => { console.error('WebSocket error:', e); }; } async function startMic() { logState(STATE.MICINIT); audioCtx = new AudioContext({ sampleRate: 24000 }); const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mic = audioCtx.createMediaStreamSource(stream); const proc = audioCtx.createScriptProcessor(4096, 1, 1); proc.onaudioprocess = (e) => { if (currentState !== STATE.LISTEN) return; const inF32 = e.inputBuffer.getChannelData(0); const int16 = new Int16Array(inF32.length); for (let i = 0; i < inF32.length; i++) { const s = Math.max(-1, Math.min(1, inF32[i])); int16[i] = s < 0 ? s * 0x8000 : s * 0x7FFF; } ws.send(int16.buffer); }; mic.connect(proc); proc.connect(audioCtx.destination); micNode = mic; procNode = proc; inputStream = stream; /*logState(STATE.INIT);*/ /*detectSilence(audioCtx, mic, proc, stream);*/ } function teardownAudio() { if (procNode) { procNode.disconnect(); procNode = null; } if (micNode) { micNode.disconnect(); micNode = null; } if (inputStream) { inputStream.getTracks().forEach(t => t.stop()); inputStream = null; } if (audioCtx && audioCtx.state !== 'closed') { audioCtx.close(); } audioCtx = null; } function detectSilence(ctx, mic, proc, stream) { const analyser = ctx.createAnalyser(); mic.connect(analyser); analyser.fftSize = 512; const data = new Uint8Array(analyser.frequencyBinCount); const thresh = 9; const delay = 1500; let speechStarted = false; let silentSince = null; (function check() { analyser.getByteFrequencyData(data); const avg = data.reduce((a,b)=>a+b,0)/data.length; if (!speechStarted) { if (avg >= thresh) { speechStarted = true; console.log('Speech started—now watching for silence'); silentSince = Date.now(); } } else { if (avg < thresh) { /* if silence continues long enough, stop */ if (Date.now() - silentSince > delay) { console.log('Silence detected → end_audio (mic still open)'); logState(STATE.PROC); ws.send(JSON.stringify({ event: 'end_audio' })); return; } } else { /* reset timer while speech continues */ silentSince = Date.now(); } } requestAnimationFrame(check); })(); } async function playLoop() { if (isPlaying) return; isPlaying = true; if (!window.__playCtx) { window.__playCtx = new AudioContext(); await window.__playCtx.resume(); } const ctx = window.__playCtx; logState(STATE.SPEAK); const FRAME_RATE = 24000; while (!isEndOfStream || playbackQueue.length > 0) { if (playbackQueue.length === 0) { await new Promise(r => setTimeout(r, 50)); continue; } /* 1) Pop the next raw chunk (Blob or ArrayBuffer) */ const raw = playbackQueue.shift(); /* 2) Convert to ArrayBuffer if needed*/ let buf; if (raw instanceof Blob) { buf = await raw.arrayBuffer(); } else { buf = raw; } if (buf.byteLength === 0) continue; /* 3) Decode & play at correct sample rate*/ const int16 = new Int16Array(buf); const f32 = new Float32Array(int16.length); for (let i = 0; i < int16.length; i++) { f32[i] = int16[i] / 32768; } const audioBuf = ctx.createBuffer(1, f32.length, FRAME_RATE); audioBuf.copyToChannel(f32, 0); const src = ctx.createBufferSource(); src.buffer = audioBuf; src.connect(ctx.destination); currentSource = src; /* 4) Wait its true duration*/ await new Promise(resolve => { src.onended = () => { if (currentSource === src) currentSource = null; resolve(); }; src.start(); }); } console.log('✅ Playback complete'); isEndOfStream = false; isPlaying = false; logState(STATE.LISTEN); detectSilence(audioCtx, micNode, procNode, inputStream); } /* initialize UI to the starting state*/ logState(STATE.IDLE);

Pricing Plans

🎯Compact🔹NextKS Assistant (Slack-based knowledge sharing and collaboration tool)For smaller rapidly scaling teams (up to 50 users), looking to improve knowledge-sharing efficiency and reduce repetitive questions.


◾€599* /month (billed annually)
◾€699* /month (billed monthly)
Extra 50 users:
    + €89* /month (billed annually)
    + €99* /month (billed monthly)

Features:
✔ Intelligent chat and knowledge-sharing via Slack
✔ Question ticketing system for team collaboration
✔ Knowledge retention with vector-based storage
✔ Basic analytics (e.g., ticket volume, knowledge usage, time saved)
✔ Up to 50 users
✔ Basic support (email support & online knowledge base)

*Prices exclude VAT. VAT is charged where applicable based on EU regulations.

💎Elite🔹NextKS Assistant (Slack-based knowledge sharing and collaboration tool)
🔹NextKS Portal (knowledge management web app)
Designed for larger organizations (up to 500 users), with advanced knowledge management, analytics, and automated question routing.


◾€1,499* /month (billed annually)
◾€1,799* /month (billed monthly)
Extra 200 users
    +€249* /month (billed annually)
    +€299* /month (billed monthly)

Features:
✔ Everything in Compact, plus:
✔ Web-based surveys to assess expertise & team satisfaction
✔ AI-driven auto-assign to route questions to the right experts
✔ Advanced analytics (e.g., skill mapping, top performer reliance)
✔ Up to 500 users
✔ Priority support (dedicated account manager, live chat, email support)

*Prices exclude VAT. VAT is charged where applicable based on EU regulations.