Web SDK
@sorisdk/web-audio is the browser SDK for adding SORI audio recognition to a web service or browser-based product.
Beta
The Web SDK is currently in Beta. Because the implementation is still evolving, parts of the API and integration flow may change.
Prerequisites
- A secure context such as
https://orhttp://localhost - A modern browser with
AudioContextandMediaDevices.getUserMedia - Access to the ephemeral key flow provided by SORI
- Microphone permission granted by the user
npm and Bundler Integration
Install the versioned package in applications that use npm and a bundler:
npm install @sorisdk/web-audio@0.6.10Vite-based applications also need vite-plugin-wasm:
npm install --save-dev vite-plugin-wasmimport wasm from "vite-plugin-wasm";
export default {
plugins: [wasm()]
};AudioRecognizer handles authentication bootstrap, session management, pack caching, and microphone recognition. Obtain its ephemeral key from an application backend or serverless endpoint:
import { AudioRecognizer } from "@sorisdk/web-audio";
const recognizer = new AudioRecognizer({
appId: "YOUR_APP_ID",
ephemeralKey: async () => {
const response = await fetch("/api/ephemeral-key", {
method: "POST"
});
if (!response.ok) {
throw new Error(`Ephemeral key request failed: HTTP ${response.status}`);
}
const { ephemeral_key } = await response.json();
return ephemeral_key;
}
});
recognizer.on("campaign", (event) => {
console.log(event.campaign);
});
recognizer.on("error", ({ error }) => {
console.error(error);
});
await recognizer.start();Call stop() or destroy() when recognition should end or when the page is being cleaned up.
Standalone Browser Module
For a browser application that does not use npm or a bundler, import the standalone ESM module directly from the exact versioned URL. This is a native module import and does not create a global API:
<script type="module">
import { AudioRecognizer } from
"https://cdn.iplateia.com/web/sorisdk/v0.6.10/sori-web-audio.mjs";
const recognizer = new AudioRecognizer({
appId: "YOUR_APP_ID",
ephemeralKey: async () => {
const response = await fetch("/api/ephemeral-key", {
method: "POST"
});
if (!response.ok) {
throw new Error(`Ephemeral key request failed: HTTP ${response.status}`);
}
const { ephemeral_key } = await response.json();
return ephemeral_key;
}
});
recognizer.on("campaign", (event) => {
console.log(event.campaign);
});
recognizer.on("error", ({ error }) => {
console.error(error);
});
await recognizer.start();
</script>Keep the exact version in production; do not replace it with a mutable latest URL.
Protect the Ephemeral-Key Endpoint
The standalone module removes the frontend build requirement, but it does not remove the trusted-server requirement. Never embed a long-lived application secret in browser code.
The application operator must protect the endpoint used by ephemeralKey with the authentication or anonymous-session verification appropriate to the product, along with per-user, per-IP, or per-session rate limits, issuance quotas, and abuse monitoring. If the endpoint is on another origin, it may need CORS headers. CORS is not authentication and does not prevent scripts, bots, or non-browser clients from calling the endpoint.
For key issuance and relay patterns, see Ephemeral Key.
Content Security Policy
With a strict Content Security Policy (CSP), allow WebAssembly compilation with 'wasm-unsafe-eval'. Allow https://cdn.iplateia.com in both script-src and connect-src, and add the SORI API and ephemeral-key endpoint origins to connect-src. For example:
script-src 'self' 'wasm-unsafe-eval' https://cdn.iplateia.com;
connect-src 'self' https://cdn.iplateia.com https://console.soriapi.com;If your ephemeral-key endpoint uses another origin, add that origin to connect-src. Because the standalone example uses an inline module script, authorize it with a CSP nonce or hash, or move the code into an allowed external script. Do not enable 'unsafe-inline' just for this integration.
