oruk — Python client for the oruk Speech API
Official Python SDK for oruk, the speech lab building audio models for English transcription, multilabel emotion scores, speaking-style classification, and unified audio analysis.
This SDK calls the file API: send a prerecorded English audio file (WAV, FLAC, MP3, M4A, OGG, or WebM; up to 30 MB / 60 minutes), get structured results back. Resonance is oruk’s flagship speech recognition model. Plans include audio minutes, measured by the second with a one-second minimum. The separate Realtime preview supports 32 locales and phrase-level emotion scores over WebSocket; see the realtime reference.
Install
python -m pip install oruk==0.2.9
Requires Python 3.10 or newer. Versioned wheel mirror.
Quickstart
Create an account at oruk.ai (plans from $12/month, 7-day standard self-serve trial, card required, $0 today) and create an API key in the developer portal.
import os
from oruk import Oruk
with Oruk(api_key=os.environ["ORUK_API_KEY"]) as client:
result = client.analyze("sample.wav", model="oruk-resonance")
print(result["text"]) # English transcript
print(result["emotions"]) # selected model scores; see interpretation below
print(result["styles"]) # selected speaking-style scores; can be empty
Endpoints
| Method | API endpoint | Returns |
|---|---|---|
client.transcribe(file) |
POST /v1/audio/transcriptions |
English transcript |
client.emotions(file) |
POST /v1/audio/emotions |
Selected scores from 15 emotion labels, no transcription |
client.styles(file) |
POST /v1/audio/styles |
Selected scores from 16 speaking-style labels, no transcription |
client.affect(file) |
POST /v1/audio/affect |
emotion + style, no transcript |
client.analyze(file) |
POST /v1/audio/analysis |
transcript, labels, segments, tagged text |
client.proficiency(file, transcript=None) |
POST /v1/audio/proficiency |
Preview: CEFR band, 0–5 score, fluency, transcript |
Every method accepts a path, Path, or binary file object and an optional
request_id=. The first five endpoints use oruk-resonance by default;
oruk-fourier is another file model with its own output scope. Proficiency
uses oruk-proficiency-1, not Resonance or Fourier. A supplied proficiency
transcript= skips built-in transcription. See the endpoint reference
before changing models; their capabilities are not interchangeable.
On the first five endpoints, with model="oruk-resonance", pass diarize=True
(and optionally num_speakers= when you know the speaker count, 1–32) to label speakers: diarization locates the speaker turns,
then Resonance scores each speaker turn, so every segment carries a
speaker field. Other fields follow the endpoint: emotion-only output does
not gain a transcript. Speaker labels are local to the recording, not identities or roles. Diarization is included in plan minutes.
with Oruk(api_key=os.environ["ORUK_API_KEY"]) as client:
result = client.analyze("support-call.wav", model="oruk-resonance", diarize=True)
for seg in result["segments"]:
print(seg["speaker"], seg.get("text"), seg.get("emotions", []))
Emotion only: client.emotions(...) on Resonance runs the encoder and affect
head and never invokes the transcription decoder, so nothing is transcribed,
the result has no transcript. One audio minute uses one plan minute for either emotion-only or unified analysis; calling both separately processes the audio twice.
with Oruk(api_key=os.environ["ORUK_API_KEY"]) as client:
result = client.emotions("support-call.wav", model="oruk-resonance")
print(result["emotions"]) # actual selected labels and scores
print(result.get("text")) # None: no transcript is produced
The client reuses one request ID per call across retries of HTTP 429, 500,
502, 503, and 504 with jittered backoff (two retries by default). Other HTTP
errors are not retried; network errors from httpx propagate to the caller.
A stable request ID helps tracing; it does not promise exactly-once processing. Errors raise OrukAPIError
with status, code, and request_id attributes.
Runnable file workflows
Set ORUK_API_KEY in your environment, download the complete
Python example, and use your own recording:
curl --fail -O https://oruk.ai/examples/analyze-file.py
python analyze-file.py sample.wav --task analysis > result.json
python analyze-file.py support-call.wav --task analysis --diarize > speakers.json
python analyze-file.py speaking-sample.wav --task proficiency > proficiency.json
Each command sends one logical request, with bounded HTTP retries if needed.
Running multiple commands processes the audio separately. --help describes
model selection, known speaker count, and an optional proficiency transcript
file. The program writes the complete API response to stdout and errors to
stderr. It does not fabricate missing labels or assume every proficiency
request was scored. For proficiency, use 30–60 seconds of spontaneous English
and inspect check.status; insufficient_audio does not establish a CEFR
level. A model estimate is not a language certificate.
Interpreting scores and usage
The 15 emotion labels and 16 speaking-style labels are model vocabularies, not a guarantee that every response contains every label. Outputs are selected by model thresholds. If no emotion clears its threshold, the highest-scoring emotion is returned; styles can be empty. Several labels may be high and scores need not sum to one. These thresholds do not establish calibrated probabilities of a person's private feelings. Evaluate representative audio before choosing application thresholds. See label interpretation and the scope of the evaluations.
usage includes measured and billable audio duration and may carry reference
fields such as rate_per_minute_usd, estimated_cost_usd, or pricing_version.
Those reference estimates are not your subscription invoice. Actual charges
follow the plan allowance, overage terms, and billing records. One minute of
audio uses one plan minute per request; separate calls process and meter the
file separately. Keep API keys in server-side code. This SDK's file methods do
not implement the separate realtime WebSocket workflow.
Links
- Documentation and API reference: https://oruk.ai/docs
- Capabilities and scope: https://oruk.ai/capabilities
- Pricing: https://oruk.ai/pricing
- Benchmarks: https://oruk.ai/benchmarks/methodology
- Service status: https://oruk.ai/status
License
MIT
Orukeet
Use model oruk-orukeet for English transcription up to 60 seconds / 4 MiB. It is included in every subscription at $0.00045/minute ($0.027/audio hour). Optional emotion detection and speaker diarization draw from the same Orukeet allowance at their published task rates. Extra usage shares the plan spending cap. See the Orukeet contract for availability, outputs, streaming, and limits.
Release files for oruk 0.2.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| oruk-0.2.9-py3-none-any.whl | Python 3 | none | any | Details |
Release files / oruk-0.2.9-py3-none-any.whl
| Download URL | oruk-0.2.9-py3-none-any.whl |
|---|---|
| Size | 6.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
94ba1ecf021a0dc0d0e62816f07a53c16a5bdd1f25da18d8ead5b96b66cb4e22
|
|
BLAKE2b-256 checksum How to use checksums |
dd0c1470face1ee3a1220ce585d4a3fa07bb7a3e18ec8a849d816694ef68d8e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency log