API quickstart
Perceive8 exposes a REST + WebSocket API that turns audio recordings and live streams into transcripts, speaker labels, sentiment, topics, entities, and real-time alerts. This guide gets you from an API key to your first completed analysis.
Base URL
https://api.perceive8.com
Authentication
Perceive8 accepts two authentication methods for REST requests.
API key (server-side)
Pass your key in the X-API-Key header:
GET /v1/analyses HTTP/1.1
Host: api.perceive8.com
X-API-Key: pk_live_xxxxxxxxxxxx
Create keys from Audio → Settings → Developer in the dashboard or via POST /v1/keys.
Bearer token (user-scoped)
For browser or user-scoped calls, pass a Supabase JWT:
GET /v1/analyses HTTP/1.1
Host: api.perceive8.com
Authorization: Bearer <supabase-jwt>
WebSocket and SSE endpoints cannot set custom headers, so pass the key or token as a query parameter:
wss://api.perceive8.com/v1/stream?token=pk_live_xxxxxxxxxxxx
Install an SDK
JavaScript / TypeScript
npm install perceive8
Requires Node 18+ or a modern browser.
Python
pip install perceive8
Requires Python 3.10+.
Upload an audio file
JavaScript
import { readFileSync } from "fs";
import { Perceive8Client } from "perceive8";
const client = new Perceive8Client({ apiKey: process.env.PERCEIVE8_API_KEY });
const file = new Blob([readFileSync("meeting.mp3")], { type: "audio/mpeg" });
const { data: analysis } = await client.analyses.upload(file, "meeting.mp3", "en");
let result = analysis;
while (result.status === "pending" || result.status === "processing") {
await new Promise((r) => setTimeout(r, 3000));
const { data } = await client.analyses.get(result.id);
result = data;
}
if (result.status === "completed") {
console.log(result.transcript);
}
Python
from perceive8 import Perceive8Client
import time
client = Perceive8Client(api_key="pk_live_xxxxxxxxxxxx")
with open("interview.mp3", "rb") as f:
result = client.analyses.upload(f, "interview.mp3", language="en")
analysis_id = result["data"]["id"]
while True:
data = client.analyses.get(analysis_id)["data"]
if data["status"] in ("completed", "failed"):
break
time.sleep(3)
print("Status:", data["status"])
if data["status"] == "completed":
print("Transcript:", data.get("transcript"))
Stream live audio
JavaScript (browser)
import { Perceive8Client } from "perceive8";
const client = new Perceive8Client({ apiKey: "pk_live_xxxx" });
const session = await client.stream.live({ language: "en", sampleRate: 16000 });
session.on("transcript_final", (event) => {
console.log("Final:", event.data?.text);
});
const audioCtx = new AudioContext({ sampleRate: 16000 });
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const source = audioCtx.createMediaStreamSource(stream);
const processor = audioCtx.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = (e) => {
const float32 = e.inputBuffer.getChannelData(0);
const int16 = new Int16Array(float32.length);
for (let i = 0; i < float32.length; i++) {
int16[i] = Math.max(-32768, Math.min(32767, float32[i] * 32768));
}
session.sendAudio(int16.buffer);
};
source.connect(processor);
processor.connect(audioCtx.destination);
setTimeout(() => {
session.stop();
session.close();
}, 30_000);
Python (asyncio)
import asyncio
from perceive8 import AsyncPerceive8Client
async def main():
async with AsyncPerceive8Client(api_key="pk_live_xxxxxxxxxxxx") as client:
async with client.stream.live(language="en", sample_rate=16000) as session:
print("Session ID:", session.session_id)
silence = bytes(16000 * 2) # 0.5s of Int16 silence at 16 kHz
await session.send_audio(silence)
async for event in session.events():
print(event)
if event.get("event") == "session_ended":
break
asyncio.run(main())