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.

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.com as the production base URL and authenticate with Authorization: Bearer <token>. Error responses use the JSON shape { error: { code, message } }.
  • Site URL for accounts and billing: https://privocio.com.

Under five minutes

Quickstart

  1. Sign up and open the dashboard.
  2. Create an API key (paid plans include programmatic transcription access).
  3. Call GET https://api.privocio.com/healthz to verify connectivity.
  4. POST an audio file to /v1/transcriptions or 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.

PlanAudio / 4 weeksAPI keysRequestsConcurrencyMax audio / requestUpload size
Free3 hours of audio / 4 weeksNo API key access3 RPM13 min10 MB
Go400 hours of audio / 4 weeks1 active key30 RPM215 min100 MB
Pro800 hours of audio / 4 weeks1 active key30 RPM215 min100 MB
EnterpriseCustom10 active keysCustomCustomCustomCustom

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.

Auth: None
Auth: Bearer token
Auth: Bearer token
Auth: Bearer token
Auth: Bearer token
Auth: Bearer token
Auth: Bearer token or API key
Auth: Bearer token or API key
Auth: Bearer token or API key

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.

StatusCodeDescription
400bad_requestInvalid request body or parameters
401unauthorizedMissing or invalid auth token
403forbiddenInsufficient permissions or invalid org context
404not_foundResource not found
413payload_too_largeFile exceeds the upload size limit
502runtime_unavailableWhisper runtime could not be reached