# Hosted audio transcription

Turn one stored audio asset into a reviewed transcript with word timings.

# Hosted audio transcription

Use `runtime: "capability"` and `operation: "audio.transcribe"` to turn one persistent StillMade audio asset into reviewed text with word-level timings. The Block declares the work; the trusted host reads the selected owner-scoped file and performs the provider request. Package code and custom interfaces never receive an API key, filesystem path, network access, or provider response outside the typed result.

## Complete contract

The manifest must declare exactly one `audio` input, one `text` language input, and one `transcript` output. Include an asset control so the Block can be used directly, and give language a default such as `auto`.

```json
{
  "manifest": {
    "schemaVersion":1,"sdkVersion":"0.1.0",
    "id":"example.transcribe-audio","version":"1.0.0",
    "name":"Transcribe audio","description":"Turn one stored audio file into reviewed text with word timings.",
    "kind":"task","runtime":"capability","entry":"src/capability.json","license":"MIT",
    "provenance":{"notice":"Include the complete applicable license notice."},
    "inputs":{"audio":{"type":"audio","primary":true},"language":{"type":"text","default":"auto"}},
    "outputs":{"transcript":{"type":"transcript","primary":true}},
    "permissions":{"project":[],"capabilities":["audio.transcribe"],"network":[],"filesystem":[],"secrets":[]},
    "ui":[{"control":"asset","port":"audio"},{"control":"select","port":"language","options":["auto","en","es","fr","de","it","pt","ja","ko","zh"]}]
  },
  "capability":{"schemaVersion":1,"operation":"audio.transcribe","audio":{"$input":"audio"},"language":{"$input":"language"},"output":"transcript"},
  "tests":[{"name":"English speech","input":{"audio":{"kind":"audio","assetId":"fixture-audio","versionId":"version-1","url":"/api/media/fixture/audio.mp3","mimeType":"audio/mpeg"},"language":"en"},"expectations":{"transcript":{"kind":"transcript","minWords":1,"maxWords":5000}}}]
}
```

The capability descriptor has exactly `schemaVersion`, `operation`, `audio`, `language`, and `output`. Both inputs use exact `$input` bindings. The output names the single declared transcript port. Language is `auto` or a lowercase two-letter ISO 639-1 code. The audio value must be a persistent typed reference with `kind:"audio"`, nonblank `assetId`, `versionId`, and `url`; an in-memory blob or arbitrary remote URL is not sufficient.

The result is exactly:

```json
{"schemaVersion":1,"text":"Hello world.","words":[{"text":"Hello","start":0,"end":0.4},{"text":"world.","start":0.4,"end":0.9}]}
```

Times are finite seconds in ascending word order, from 0 through 86,400. Results allow at most 100,000 words and one million transcript characters. Fixture expectations contain exactly `kind:"transcript"`, `minWords`, and `maxWords`; they test useful bounds rather than invented provider text.

## Host execution and review

The host offers two selections. **StillMade transcription** runs the app's own transcription (Groq Whisper Large v3 Turbo, with fal Whisper fallbacks) and is paid with StillMade credits at the app's upload-transcription price, quoted per fixture and sample before anything runs. **OpenAI Whisper** (`whisper-1`) uses the account owner's connected OpenAI key, spends zero StillMade credits, and OpenAI bills the connected account directly. Both accept supported audio up to 25 MB, request word timestamps, validate the response size and shape, and return only the normalized transcript. Uploading, validating, quoting, or previewing the package does not send audio.

Before dispatch, StillMade binds the package source and version, exact inputs, owner, project, provider, model, payment method, and zero-credit quote. It checks project access and key availability, then checks account suspension again immediately before reading media and before provider dispatch. It reads only an owner-scoped StillMade media key. An uncertain provider submission is not automatically repeated, avoiding duplicate external charges.

Offline validation does not need a key and cannot claim a live transcription. Import is Upload → validation and security/license checks → fixture/sample review → Install. In a project, the user chooses an audio asset and language, reviews the request, runs it, and accepts the timed transcript. The output can connect to any compatible `transcript` input.

## Package and validate

The downloaded SDK includes `packages/block-sdk/transcription-example.js` and `examples/transcribe-audio.stillmade.json`. Use your own namespace and include the real license and provenance for adapted source.

```sh
node packages/block-cli/cli.js validate examples/transcribe-audio.stillmade.json
node packages/block-cli/cli.js pack examples/transcribe-audio.stillmade.json transcribe-audio.stillmade-block
node packages/block-cli/cli.js validate transcribe-audio.stillmade-block
```

Before returning an artifact, confirm that it has one exact operation, usable generated controls, realistic fixtures, complete attribution, no embedded credentials or provider choices, no ambient permissions, and passes the same packaged validator used by StillMade.
