Elixir SDK for the sf-voice media API.
build a client with new/2, then call the public functions to ingest,
query, and search media.
quick start
client = SfVoiceMedia.new("sk-...")
# 1. ingest a media file — returns immediately with a task id
{:ok, %{task_id: tid}} =
SfVoiceMedia.ingest(client, %{source: :url, url: "https://example.com/clip.mp4"})
# 2. wait for indexing to complete — raises on failure or timeout
task = SfVoiceMedia.poll_task!(client, tid)
# 3. search across your indexed media with natural language
{:ok, %{results: results}} =
SfVoiceMedia.search(client, %{query: "product roadmap discussion"})
# results carry timestamps so you can jump to the exact moment
Enum.each(results, fn r ->
IO.puts("#{r.asset_id} at #{r.start_ms}ms — #{r.match_type}")
end)all functions return {:ok, result} or {:error, %SfVoiceMedia.Error{}}.
poll_task!/3 raises SfVoiceMedia.Error on timeout or task failure.
Summary
Functions
Soft-deletes an asset so it is excluded from list results while the backend retains the record.
Retrieve a library asset by its ID.
Fetches the current state of an ingestion task.
Submit a media file for ingestion from a URL or an S3 key.
lists assets in the library, paginated.
Builds a SfVoiceMedia.Client preconfigured with the given API key and optional settings.
Polls an ingestion task until its status becomes "ready" or "failed".
Run a semantic search over indexed media.
Functions
@spec delete_asset(SfVoiceMedia.Client.t(), String.t()) :: :ok | {:error, SfVoiceMedia.Error.t()}
Soft-deletes an asset so it is excluded from list results while the backend retains the record.
Returns :ok if the deletion was successful (HTTP 204), {:error, %SfVoiceMedia.Error{}} otherwise.
Examples
:ok = SfVoiceMedia.delete_asset(client, "ast_abc123")
@spec get_asset(SfVoiceMedia.Client.t(), String.t()) :: {:ok, SfVoiceMedia.Types.asset()} | {:error, SfVoiceMedia.Error.t()}
Retrieve a library asset by its ID.
Returns {:ok, asset} when the asset is found, or {:error, %SfVoiceMedia.Error{}} on failure.
@spec get_task(SfVoiceMedia.Client.t(), String.t()) :: {:ok, SfVoiceMedia.Types.task()} | {:error, SfVoiceMedia.Error.t()}
Fetches the current state of an ingestion task.
Returns {:ok, task} where task is a map describing the task (includes a "status" field), or {:error, %SfVoiceMedia.Error{}} on failure.
Examples
{:ok, %{status: "ready", asset_id: aid}} = SfVoiceMedia.get_task(client, "task_abc123")
@spec ingest(SfVoiceMedia.Client.t(), SfVoiceMedia.Types.ingest_request()) :: {:ok, SfVoiceMedia.Types.ingest_response()} | {:error, SfVoiceMedia.Error.t()}
Submit a media file for ingestion from a URL or an S3 key.
Returns immediately with a task identifier that can be inspected with get_task/2 or awaited with poll_task/3.
Returns
{:ok, response}— successful response containing at leasttask_idand optionallyasset_idand other task metadata.{:error, %SfVoiceMedia.Error{}}— request failed; contains error details.
@spec list_assets(SfVoiceMedia.Client.t(), SfVoiceMedia.Types.list_assets_params()) :: {:ok, SfVoiceMedia.Types.asset_list_response()} | {:error, SfVoiceMedia.Error.t()}
lists assets in the library, paginated.
examples
{:ok, %{items: items, page_info: info}} =
SfVoiceMedia.list_assets(client, %{page: 1, limit: 20})
# no params — uses server defaults
{:ok, %{items: items}} = SfVoiceMedia.list_assets(client)
@spec new( String.t(), keyword() ) :: SfVoiceMedia.Client.t()
Builds a SfVoiceMedia.Client preconfigured with the given API key and optional settings.
Options
:base_url— API base URL; defaults to "https://api.sf-voice.com". A trailing/is removed.:http_opts— keyword list forwarded to Req for every request; defaults to[].
Examples
client = SfVoiceMedia.new("sk-my-api-key")
client = SfVoiceMedia.new("sk-my-api-key",
base_url: "https://staging.api.sf-voice.com",
http_opts: [receive_timeout: 10_000]
)
Polls an ingestion task until its status becomes "ready" or "failed".
polls get_task/2 at a fixed interval. returns the final task map when
the task reaches "ready". raises SfVoiceMedia.Error if the task fails
or the timeout is exceeded.
options
:interval_ms— milliseconds to wait between polls (default: 1_500):timeout_ms— maximum total wait in milliseconds (default: 120_000)
examples
task = SfVoiceMedia.poll_task!(client, tid)
task = SfVoiceMedia.poll_task!(client, tid, interval_ms: 2_000, timeout_ms: 60_000)
@spec search(SfVoiceMedia.Client.t(), SfVoiceMedia.Types.search_request()) :: {:ok, SfVoiceMedia.Types.search_response()} | {:error, SfVoiceMedia.Error.t()}
Run a semantic search over indexed media.
The request map must include a :query string and may include optional parameters such as :types (list of asset types), :threshold (similarity threshold), and :limit (maximum results). Returns the API response wrapped in {:ok, result} or {:error, %SfVoiceMedia.Error{}}.
Examples
{:ok, %{results: results}} =
SfVoiceMedia.search(client, %{query: "product roadmap discussion"})
{:ok, %{results: results}} =
SfVoiceMedia.search(client, %{
query: "quarterly targets",
types: [:conversation],
threshold: 0.7,
limit: 10
})