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.
Search
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}")
}