Developer reference
Privocio API documentation
Documentation for the Privocio API, including authentication, transcription endpoints, streaming responses, and integration examples. Base URL https://api.privocio.com.
On this page
Start here
Overview
Privocio exposes a versioned HTTP API for account metadata, API keys, usage summaries, and Whisper-based transcription. All paths below are relative to https://api.privocio.com.
- Start with Quickstart, Authentication, and Endpoints to make your first transcription request.
- Use
https://api.privocio.comas the production base URL and authenticate withAuthorization: Bearer <token>. Error responses use the JSON shape{ error: { code, message } }. - Site URL for accounts and billing: https://privocio.com.
Under five minutes
Quickstart
- Sign up and open the dashboard.
- Create an API key (paid plans include programmatic transcription access).
- Call
GET https://api.privocio.com/healthzto verify connectivity. - POST an audio file to
/v1/transcriptionsor the OpenAI-compatible/v1/audio/transcriptions.
Full cURL recipes are in the cURL section below.
Credentials
Authentication & API keys
Authenticated routes expect an Authorization header:
Authorization: Bearer <YOUR_API_KEY_OR_SESSION_TOKEN>
Create and revoke keys from the dashboard (API keys). The plaintext secret is shown once when a key is created — store it in a secret manager or environment variable.
Management endpoints (/v1/api-keys, /v1/me) require a user session token from login. Transcription endpoints accept either a session token or a dedicated API key.
curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.privocio.com/v1/me
Transcription shaping
Output modes (Raw, Clean, Agent)
Privocio supports multiple transcription output modes so you can balance verbatim fidelity, readability, and downstream LLM token cost.
- Raw — closest to classic Whisper-style text; maximal fidelity for archival or legal workflows.
- Clean — light normalization for readable paragraphs and fewer filler artifacts.
- Agent — structured, token-efficient JSON for workflow automation and downstream application logic.
Configure output mode from the dashboard or product UI where your deployment exposes it; transcription HTTP parameters above remain the same.
Quotas
Rate limits & fair use
Technical limits depend on your subscription tier and match the limits enforced by the API.
| Plan | Audio / 4 weeks | API keys | Requests | Concurrency | Max audio / request | Upload size |
|---|---|---|---|---|---|---|
| Free | 3 hours of audio / 4 weeks | No API key access | 3 RPM | 1 | 3 min | 10 MB |
| Go | 400 hours of audio / 4 weeks | 1 active key | 30 RPM | 2 | 15 min | 100 MB |
| Pro | 800 hours of audio / 4 weeks | 1 active key | 30 RPM | 2 | 15 min | 100 MB |
| Enterprise | Custom | 10 active keys | Custom | Custom | Custom | Custom |
Audio-hour quotas reset every 4 weeks. Enterprise limits are configured by contract; backend global safeguards may still apply.
Drop-in routing
OpenAI SDK compatibility
The route POST /v1/audio/transcriptions follows the same multipart shape and response conventions as OpenAI's Whisper endpoint. Point the official OpenAI SDK at Privocio by setting baseURL to https://api.privocio.com/v1 and supplying your Privocio API key as apiKey.
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.PRIVOCIO_API_KEY!,
baseURL: "https://api.privocio.com/v1",
});
const file = await fs.openAsBlob("recording.wav");
const transcript = await openai.audio.transcriptions.create({
model: "whisper-1",
file,
language: "en",
});
console.log(transcript.text);from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.privocio.com/v1",
)
with open("recording.wav", "rb") as audio_file:
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
language="en",
)
print(transcript.text)Reference
Endpoints
Expand a row for method, path, auth requirements, and example payloads. All paths are relative to https://api.privocio.com.
Shell
cURL examples
# Health check (no auth) curl -sS https://api.privocio.com/healthz | jq . # Who am I (session or API key) curl -sS -H "Authorization: Bearer YOUR_API_KEY" \ https://api.privocio.com/v1/me | jq . # Transcribe an audio file (batch — waits for full result) curl -X POST https://api.privocio.com/v1/transcriptions \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "file=@recording.wav" \ -F "model=whisper-1" \ -F "language=en" # OpenAI-compatible path (drop-in for OpenAI Whisper clients) curl -X POST https://api.privocio.com/v1/audio/transcriptions \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "file=@recording.wav" \ -F "model=whisper-1" # Dedicated streaming route (SSE — segments in real time) curl -N -X POST https://api.privocio.com/v1/transcriptions/stream \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "file=@recording.wav" \ -F "model=whisper-1" # Or use stream=true on the standard transcription endpoint curl -N -X POST https://api.privocio.com/v1/transcriptions \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "file=@recording.wav" \ -F "model=whisper-1" \ -F "stream=true"
httpx
Python examples
Batch transcription with httpx (install: pip install httpx).
import httpx
API_BASE = "https://api.privocio.com"
API_KEY = "YOUR_API_KEY"
with open("recording.wav", "rb") as audio_file:
files = {"file": ("recording.wav", audio_file, "audio/wav")}
data = {"model": "whisper-1", "language": "en"}
response = httpx.post(
f"{API_BASE}/v1/transcriptions",
headers={"Authorization": f"Bearer {API_KEY}"},
files=files,
data=data,
timeout=600.0,
)
response.raise_for_status()
print(response.json())fetch
JavaScript / TypeScript examples
Browser or Node 18+ with native fetch and FormData.
const API_BASE = "https://api.privocio.com";
const API_KEY = process.env.PRIVOCIO_API_KEY!;
const form = new FormData();
form.append("file", audioBlob, "recording.wav");
form.append("model", "whisper-1");
form.append("language", "en");
const res = await fetch(`${API_BASE}/v1/transcriptions`, {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
body: form,
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(JSON.stringify(err));
}
const data = await res.json();
console.log(data.text);Real-time segments
Streaming (Server-Sent Events)
Use POST /v1/transcriptions/stream or stream=true on /v1/transcriptions. Parse SSE blocks separated by blank lines; each block has event: and data: lines.
const form = new FormData();
form.append("file", audioFile);
form.append("model", "whisper-1");
const res = await fetch("https://api.privocio.com/v1/transcriptions/stream", {
method: "POST",
headers: { Authorization: "Bearer YOUR_API_KEY" },
body: form,
});
const reader = res.body!.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
while (buffer.includes("\n\n")) {
const idx = buffer.indexOf("\n\n");
const block = buffer.slice(0, idx);
buffer = buffer.slice(idx + 2);
const match = block.match(/^event: (.+)\ndata: (.+)$/s);
if (!match) continue;
const [, event, data] = match;
const parsed = JSON.parse(data);
if (event === "segment") {
console.log(parsed.text);
}
}
}HTTP & codes
Error handling
Error bodies share one JSON envelope:
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid Authorization header"
}
}Inspect HTTP status, then read error.code for stable programmatic branching.
| Status | Code | Description |
|---|---|---|
| 400 | bad_request | Invalid request body or parameters |
| 401 | unauthorized | Missing or invalid auth token |
| 403 | forbidden | Insufficient permissions or invalid org context |
| 404 | not_found | Resource not found |
| 413 | payload_too_large | File exceeds the upload size limit |
| 502 | runtime_unavailable | Whisper runtime could not be reached |