# API
`kcode-audio-ingress` durably accepts complete WAV byte buffers and
automatically runs its integrated transcription pipeline. The caller supplies
an already configured transcriber and one persistence-root path. The library
derives its database and retained-original locations beneath that root.
```rust
pub struct AudioInput {
pub bytes: Vec<u8>,
pub recorded_at: chrono::DateTime<chrono::Utc>,
pub original_filename: Option<String>,
}
pub struct Submission {
pub recording_id: uuid::Uuid,
pub deduplicated: bool,
}
pub struct Status {
pub recordings: Vec<RecordingStatus>,
}
pub struct RecordingStatus {
pub id: uuid::Uuid,
pub sha256: String,
pub original_filename: String,
pub size_bytes: u64,
pub recorded_at: chrono::DateTime<chrono::Utc>,
pub received_at: chrono::DateTime<chrono::Utc>,
pub transcription_model: String,
pub reconciliation_model: String,
pub reconciliation_reasoning: String,
pub state: RecordingState,
}
pub enum RecordingState {
Queued,
Processing {
attempt: u8,
progress: TranscriptionStatus,
},
Complete {
transcript: String,
},
Failed {
attempts: u8,
error: String,
retryable: bool,
},
}
pub enum ErrorKind {
InvalidInput,
NotFound,
Conflict,
Internal,
}
pub struct Error {
// private fields
}
pub struct AudioIngress {
// private fields
}
impl Error {
pub fn kind(&self) -> ErrorKind;
}
impl AudioIngress {
pub async fn open(
persistence_root: impl AsRef<std::path::Path>,
transcriber: AudioTranscriber,
) -> Result<AudioIngress, Error>;
pub async fn submit(&self, input: AudioInput) -> Result<Submission, Error>;
pub fn status(&self) -> Result<Status, Error>;
pub fn retry(&self, recording_id: uuid::Uuid) -> Result<(), Error>;
}
```
The merged transcriber API remains available from this crate:
```rust
pub struct AudioTranscriber;
impl AudioTranscriber {
pub fn new(
gemini: kcode_gemini_api::Gemini,
codex: kcode_codex_runtime::Codex,
) -> AudioTranscriber;
pub fn transcribe(&self, audio: Vec<u8>) -> TranscriptionJob;
}
impl TranscriptionJob {
pub fn status(&self) -> TranscriptionStatus;
}
```
`TranscriptionStatus`, `JobState`, `Step`, `StepState`, `StepStatus`, and
`StepError` retain the former transcriber library's fields, serialization, and
semantics. `AudioTranscriber::transcribe` is still available for callers that
want an in-memory job without ingress persistence.
## Operation
- `AudioIngress::open` creates or opens `<root>/state.sqlite3`, creates
`<root>/originals/`, applies compatible schema migrations, recovers
interrupted attempts, and starts the background worker. It requires an
active Tokio runtime.
- `submit` rejects an empty buffer, computes its SHA-256 identity, retains the
exact bytes in content-addressed storage, commits the recording row, and
returns only after the original and metadata are durable. Repeated bytes
return the existing recording with `deduplicated: true`.
- `status` returns one complete snapshot ordered by recording time, newest
first. A completed state contains the canonical reconciled Markdown
transcript. Processing progress never contains a transcript body.
- `retry` applies only to a failed recording. It clears the previous attempt
budget and schedules a fresh automatic five-attempt budget. Retrying an
unknown identifier returns `NotFound`; retrying any nonfailed recording
returns `Conflict`.
The library automatically retries a retryable full transcription job at most
five times. Non-retryable input or provider failures stop immediately.
Exhausted work remains failed until `retry` is called. Active dependency jobs
are in memory; after process restart the library starts a new job from the
durable original.
Each completed audio chunk's validated structured transcript is inserted into
SQLite before its progress step becomes complete. Piece rows are keyed by
recording, full-job attempt, and chronological index. A failed or interrupted
attempt therefore retains every piece it completed, and a later retry cannot
overwrite that history. These rows are intentionally internal so the existing
ingress API and status JSON remain unchanged.
The library has no HTTP, multipart, streaming-input, storage-quota, transcript
delivery, Kmap, Chatend, or application-framework API.