@capsiynau/sdk-transcribe
v1.1.1
Published
Node SDK for the Capsiynau transcription API. Wraps POST /v1/transcribe, job polling, and typed errors. Welsh and English first-class. Browser support follows once the token-mint endpoint ships.
Maintainers
Readme
@capsiynau/sdk-transcribe
Node SDK for the Capsiynau transcription API. Wraps POST /v1/transcribe,
job polling, and typed errors. Welsh and English first-class.
Status: stable. v1.0.0 published 2026-05-19. v1.0 scope is intentionally tight (Node + API key, transcription only). Browser support and voice-notes are deferred to sibling packages - see DESIGN.md §7 and the Roadmap below.
Note for repo maintainers: this package has no repo-internal consumers by design. It is an npm-publishable SDK (
publishConfig.access: publicin package.json) consumed by external integrators against the hosted API; it is not wired into the app bundle and never will be. The app's own marketing and developer pages reference the npm package name (src/components/landing/APISection.jsx,src/pages/Developers.jsx,src/data/v1Spec.js) but do not import the code. Do not flag or delete it as dead code.
Why this exists
Capsiynau's /v1/transcribe endpoint already powers PMA, Nodiadau, and
internal apps. Third-party integrators currently hit raw HTTP, parse a
non-uniform error envelope, and re-implement job polling. This SDK is
the shared, opinionated Node-side wrapper.
Welsh is a first-class citizen. The language parameter is required (no
autodetect — a Capsiynau P0 lesson, see DESIGN.md), and
Welsh fixtures appear in at least half the documented examples.
Install
npm install @capsiynau/sdk-transcribeRequires Node >=18. ESM-only.
30-second sketch
import { TranscriptionClient } from '@capsiynau/sdk-transcribe'
const client = new TranscriptionClient({
apiKey: process.env.CAPSIYNAU_API_KEY,
})
// Submit a transcription job. The project must already exist in
// Capsiynau (or pass an assetId - same shape).
const job = await client.submit({
projectId: '00000000-0000-0000-0000-000000000000',
fileUrl: 'https://example.com/audio.mp3',
language: 'cy', // required; never autodetected
})
// job: { jobId, projectId, status: 'queued', ... }
await client.waitFor(job.jobId, { timeoutMs: 600_000 })
// Resolves when the job reaches a terminal status ('done' or
// 'completed' - both accepted). The SDK handles jittered backoff and
// transient errors.
const transcript = await client.getTranscript(job.projectId)
// { project_id, title, source_language, segments: [...] }
console.log(transcript.segments[0].text)What's in the box (v1.0)
| Module | Purpose |
|--------|---------|
| TranscriptionClient | Wraps POST /v1/transcribe, job polling (GET /v1/status), transcript retrieval (GET /v1/export?format=json), and retry policy. |
| Typed errors | AuthError, QuotaError, PlanGateError, NetworkError, ValidationError, ServerError. Parsed from today's { error: '<string>' } envelope; will upgrade to structured codes once the server-side normaliser middleware ships. |
| SignAvatarClient (experimental) | Wraps /v1/sign-avatar/*. Phrase-to-animation router for live captioning. Response shapes may change; not yet covered by the v1 stability contract. See Sign Avatar (experimental) below. |
Surface and rationale in DESIGN.md.
What this SDK does not do
- No browser usage in v1.0. Browser path requires the
/v1/auth/tokenshort-lived mint endpoint, which is on the roadmap but not built server-side. Node-only for now. - No autodetect of source language. Caller passes
language. Period. - No exposed AI knobs.
engineselection is server-side; the SDK always sends the platform default. AI infrastructure is invisible. - No voice recording, no timecode helpers, no in-place transcript
edits. Those live in a planned sibling package
@capsiynau/sdk-voice-notes(not yet started) and depend on a/v1/notesresource that does not exist server-side today. - No live streaming mode. Live captions today go through the
worker's relay on
feature/phase-15-live-relay, which is not yet bracketed under a v1 wire contract.
Sign Avatar (experimental)
SignAvatarClient wraps the experimental /api/v1/sign-avatar/*
routes. This is a phrase-to-animation router, not a sign-language
translation system. It exists to prove the architecture: one live
transcript pipeline feeding multiple accessibility outputs. Real
production use requires Deaf/BSL consultant validation and proper
animation assets - neither of which ship with the POC.
Stability: the routes are tagged experimental in
docs/api-versioning.md. Response
shapes may change without a /v2 bump until the routes are promoted.
import { SignAvatarClient } from '@capsiynau/sdk-transcribe'
const client = new SignAvatarClient({ apiKey: process.env.CAPSIYNAU_API_KEY })
const instruction = await client.resolve({
text: 'Please scan the QR code to ask a question',
language: 'en',
})
// { normalisedText, signLanguage: 'prototype',
// glossSequence: ['PLEASE','SCAN','QR-CODE','QUESTION'],
// animations: [...], fallback: false, warnings: [], latency_ms: 4 }Dictionary management (admin role required server-side):
const { entries } = await client.listDictionary({ language: 'cy' })
await client.upsertPhrase({
phrase: 'Sganiwch y cod QR',
gloss: ['PLEASE','SCAN','QR-CODE'],
animationIds: ['please','scan','qr-code'],
language: 'cy',
})Unmatched phrase log (drives future dictionary growth):
await client.logUnmatched({ text: 'lanyard', language: 'en' })
const { entries } = await client.listUnmatched({ limit: 100 })For background on why this is a phrase router and not a BSL translator,
see docs/sign-avatar-poc.md.
Cross-package notes
- Welsh language utilities (normalisation, mutations, digraphs, glossary
helpers) live in
@capsiynau/intelligence. The two packages stay separate by design. Re-exportingintelligencesymbols throughsdk-transcribewould drag every consumer's bundle up with Welsh-specific code they may not need, couple release cadence, and frame Welsh as mandatory rather than supported. Consumers who need Welsh-aware text handling alongside transcripts depend on both packages explicitly. @capsiynau/sdk-voice-noteswill be a future sibling once the/v1/notesresource exists server-side. The two SDKs share auth, errors, and language conventions but not transport implementations.- The Capsiynau live-relay worker is the server counterpart for any
future live mode. Edits there land on
feature/phase-15-live-relay, not main (branch invariant).
Roadmap
- v1.0 —
TranscriptionClient(Node, API key auth). Submit + poll. Typed errors against the current{ error: '<string>' }envelope. - v1.1 — Browser support via
/v1/auth/tokenshort-lived token mint (depends on the server-side mint endpoint; see DESIGN.md §1 and §9). - v1.2 — Correction-signal emit
(
POST /v1/transcripts/:id/correctionsor equivalent; endpoint does not exist today). Wires Nodiadau-style edits into the@capsiynau/intelligenceglossary loop. - v2.x — Live mode WebSocket, once the worker relay is bracketed under a v1 contract.
License
MIT
