Skip to content
anecho.ai
Start · quickstart

From nothing to a processed stream in five minutes.

Anecho is a stream processor with two outputs. This page gets one running. The routing question — which output goes where — is the important one, and it has its own guide.

  1. Step 01

    Get a key

    Sign up and the key is on screen. No demo call, no procurement thread, no minimum commitment. The free tier is 10,000 processed minutes a month, every month, and it does not expire.

  2. Step 02

    Install

    One package for servers, one for browsers, one for Python. The orchestrator plugins wrap the same core.

  3. Step 03

    Open a session

    A session is a stateful stream processor. It is cheap to create and must not be shared between callers — each conversation gets its own.

  4. Step 04

    Feed it blocks and route the output

    Push float32 mono blocks in, get an aligned pair out. Send the enhanced channel to turn-taking and the raw channel to your transcriber.

Install
npm install @anecho/sdk
# browser build
npm install @anecho/sdk-web
Authenticate

Keys are environment-scoped. A key that starts hk_test_ is metered but free and rate-limited; hk_live_ bills per minute. Browser sessions use a short-lived token minted by your server — never put a live key in a client bundle.

server · mint a browser token
import { Anecho } from "@anecho/sdk";

const anecho = new Anecho({ apiKey: process.env.ANECHO_API_KEY! });

// 15-minute token, scoped to one session.
const token = await anecho.createClientToken({ ttlSeconds: 900 });
First stream
node · @anecho/sdk
import { Anecho } from "@anecho/sdk";

const anecho = new Anecho({ apiKey: process.env.ANECHO_API_KEY! });

const session = await anecho.createSession({
  model: "clearline-s",  // Clearline, streaming variant
  sampleRate: 8000,         // the carrier rate. Nothing here resamples it.
  echoSuppression: true,    // residual echo the carrier AEC left behind
  splitPipeline: true,      // the default. See /docs/split-pipeline.
});

// Blocks are float32 mono in [-1, 1]. Block size is session.blockSize;
// anything else is buffered for you, at the cost of one extra hop of latency.
for await (const block of pcm8kMono) {
  const { enhanced, raw, speech, score } = session.process(block);

  if (speech) turnDetector.push(enhanced);   // Onset decision
  stt.push(raw);                             // unprocessed by default
  quality.record(score);                     // Nyquist, 0–1
}

session.close();
Verify

Before you tune anything, measure. The SDK ships the same alignment code the benchmark uses, so you can score your own audio against your own reference text and find out whether enhancement is helping your pipeline.

node · score your own pipeline
import { wer } from "@anecho/sdk/metrics";

const a = wer(reference, transcriptFromRaw);
const b = wer(reference, transcriptFromEnhanced);

console.log(a.wer, b.wer, b.wer - a.wer);
// Positive delta means enhancement hurt this condition. Publish it anyway.
Next

Split pipeline

Why the two outputs exist and how to route them without breaking alignment.

Read
Next

API reference

Every option, every field on the frame, and what each model id means.

Read
Next

Orchestrators

Drop-in plugins for LiveKit Agents and Pipecat.

Read