Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sf-voice.sh/llms.txt

Use this file to discover all available pages before exploring further.

com.sfvoice:sf-voice-media-kotlin — coroutine-native Kotlin client built on Ktor. All methods are suspend functions. Use this SDK in Kotlin services where cancellation should follow coroutine scope.

Install

// build.gradle.kts
dependencies {
    implementation("com.sfvoice:sf-voice-media-kotlin:0.1.1")
}

Create a client

import com.sfvoice.media.SfVoiceMediaClient

val client = SfVoiceMediaClient(
    apiKey = System.getenv("SF_VOICE_API_KEY"),
    baseUrl = "https://api.sf-voice.com"
)

Ingest

import com.sfvoice.media.IngestRequest

val resp = client.ingest(
    IngestRequest(
        source = "url",
        assetId = "call_001",
        assetClass = "customer_acme",
        url = "https://storage.example.com/calls/001.mp3",
        mediaType = "audio",
        types = listOf("audio", "transcript")
    )
)
val taskId = resp.taskId

Poll until ready

import com.sfvoice.media.SfVoiceMediaException

val task = client.pollTask(taskId, intervalMs = 2_000, timeoutMs = 120_000)

if (task.status == "failed") {
    error("indexing failed: ${task.error}")
}
pollTask throws SfVoiceMediaException on API errors or timeout.
import com.sfvoice.media.SearchBody

val resp = client.search(
    SearchBody(
        query = "customer asks about pricing",
        assetClass = "customer_acme",
        types = listOf("transcript"),
        threshold = 0.7f,
        limit = 10
    )
)

resp.results.forEach { r ->
    println("${r.assetId} ${r.startMs}${r.endMs}ms (${r.score})")
}

Assets

// list
val resp = client.listAssets(page = 1, limit = 20)

// get one
val asset = client.getAsset("call_001")

// delete
client.deleteAsset("call_001")

Errors

import com.sfvoice.media.SfVoiceMediaException

try {
    client.search(SearchBody(query = "...", assetClass = "customer_acme"))
} catch (e: SfVoiceMediaException) {
    println("${e.code} ${e.status}: ${e.message}")
}