Client SDKs
Koldan ships client libraries for the most popular programming languages, so you can integrate with the Koldan API in minutes with full type safety and idiomatic APIs.
How these SDKs are built
REST SDKs are generated directly from our OpenAPI 3.1.0 specification and released in lockstep with the server. Streaming SDKs are distributed with the same documentation release so the client you download matches the deployed API version.
Downloads
Pick the package for your stack. Each archive contains the compiled client, source code, and a language-specific README.md with installation instructions.
REST API SDKs
REST API SDKs are generated from the OpenAPI specification and cover file upload, batch transcription, session history, model discovery, administration APIs, and other HTTP endpoints.
-
Java
Maven/Gradle-ready artifact published as
koldan-sdk. -
JavaScript
Browser- and Node-compatible build, distributed as
koldan-sdk. -
TypeScript
Fully typed
koldan-sdkpackage with first-class editor autocomplete. -
Python
pip-installablekoldan-sdkpackage supporting Python 3.9+. -
C#
NuGet package
Koldan.Sdktargeting .NET Standard 2.0+. -
Go
Idiomatic Go module
koldan-sdkcompatible with Go 1.18+. -
C
Portable C99 client library built with CMake and libcurl.
-
C++
C++17 client library using the C++ REST SDK (Casablanca).
WebSocket SDKs
WebSocket SDKs are separate packages focused on streaming speech recognition: sending live PCM audio, receiving partial and final transcripts, and handling the streaming session lifecycle.
-
C#
Package
Koldan.WebSocket.Sdkfor real-time speech recognition over WebSocket.Download
koldan-websocket-sdk-csharp-9.0.4.zipC# WebSocket SDK
OpenAPI Specification
Prefer to generate your own client, import the API into Postman, or drive it from a tool like openapi-generator? Download the raw contract directly:
- api-docs.yaml — OpenAPI 3.1.0 specification
Getting Started
Integrating a Koldan REST API SDK always follows the same three steps, regardless of language:
- Install the SDK using your language's standard package manager.
- Configure the API client with the Koldan base URL and your API key.
- Call an API class to perform operations such as uploading files, starting transcriptions, and reading results.
Authentication
REST API SDKs accept an API key through the apiKey security scheme. See Authentication and API Keys for how to create and rotate keys.
For live microphone or PCM streaming, use a separate WebSocket SDK such as the C# WebSocket SDK.
Installation
Example: Uploading And Transcribing A Speech File
The snippets below authenticate against Koldan, call the generated upload-and-transcribe operation, poll the transcription job until it finishes, and then print the final transcript.
import os
import time
import koldan_sdk
from koldan_sdk.api.speech_transcriptions_api import SpeechTranscriptionsApi
from koldan_sdk.models.speech_service_diarization_options import SpeechServiceDiarizationOptions
from koldan_sdk.models.speech_service_transcription_language_options import SpeechServiceTranscriptionLanguageOptions
from koldan_sdk.models.speech_service_transcription_options import SpeechServiceTranscriptionOptions
from koldan_sdk.models.transcription_job_status import TranscriptionJobStatus
config = koldan_sdk.Configuration(host=os.environ["KOLDAN_BASE_URL"])
config.api_key["apiKey"] = os.environ["KOLDAN_API_KEY"]
with koldan_sdk.ApiClient(config) as client:
api = SpeechTranscriptionsApi(client)
with open(os.environ["KOLDAN_FILE_PATH"], "rb") as source:
transcription_options = SpeechServiceTranscriptionOptions(
model="general",
language=SpeechServiceTranscriptionLanguageOptions(),
punctuation=False,
capitalization=False
)
diarization_options = SpeechServiceDiarizationOptions(
enabled=False
)
response = api.upload_and_transcribe(
name="meeting-recording",
transcription=transcription_options.to_json(),
file=(os.path.basename(source.name), source.read()),
diarization=diarization_options.to_json(),
)
job = response.job
while True:
job = api.get_job(job.id)
print(f"Job status: {job.status}")
if job.status in {TranscriptionJobStatus.COMPLETED, TranscriptionJobStatus.FAILED, TranscriptionJobStatus.CANCELLED}:
break
time.sleep(2)
if job.status == TranscriptionJobStatus.COMPLETED:
print(job.result.text)
else:
print(job.errors)
const fs = require("fs");
const KoldanSdk = require("koldan-sdk");
const TERMINAL_STATUSES = new Set(["COMPLETED", "FAILED", "CANCELLED"]);
async function main() {
const client = KoldanSdk.ApiClient.instance;
client.basePath = "https://koldan.dixilang.com";
client.authentications["apiKey"].apiKey = "YOUR_API_KEY";
const api = new KoldanSdk.SpeechTranscriptionsApi(client);
const response = await api.uploadAndTranscribe("meeting-recording", JSON.stringify({
model: "general",
language: { defaultLanguageCode: "he" },
punctuation: false,
capitalization: false,
}), {
file: fs.createReadStream("sample-audio.wav"),
path: "/incoming-audio/",
metadata: JSON.stringify({ source: "upload", type: "meeting-recording" }),
diarization: JSON.stringify({ enabled: false }),
tags: JSON.stringify(["meeting", "transcription"]),
});
let job = response.job;
while (!TERMINAL_STATUSES.has(job.status)) {
await new Promise((resolve) => setTimeout(resolve, 2000));
job = await api.getJob(job.id);
}
console.log(job.status === "COMPLETED" ? job.result.text : job.errors);
}
main();
import { readFile } from "node:fs/promises";
import path from "node:path";
import { Configuration, SpeechTranscriptionsApi, TranscriptionJobStatus } from "koldan-sdk";
const TERMINAL_STATUSES = new Set([TranscriptionJobStatus.Completed, TranscriptionJobStatus.Failed, TranscriptionJobStatus.Cancelled]);
async function main(): Promise<void> {
const config = new Configuration({
basePath: "https://koldan.dixilang.com",
apiKey: "YOUR_API_KEY",
});
const file = new File(
[await readFile("sample-audio.wav")],
path.basename("sample-audio.wav")
);
const api = new SpeechTranscriptionsApi(config);
const response = await api.uploadAndTranscribe({
name: "meeting-recording",
file,
path: "/incoming-audio/",
metadata: JSON.stringify({ source: "upload", type: "meeting-recording" }),
transcription: JSON.stringify({
model: "general",
language: { defaultLanguageCode: "he" },
punctuation: false,
capitalization: false,
}),
diarization: JSON.stringify({ enabled: false }),
tags: JSON.stringify(["meeting", "transcription"]),
});
let job = response.job!;
while (!job.status || !TERMINAL_STATUSES.has(job.status)) {
await new Promise((resolve) => setTimeout(resolve, 2000));
job = await api.getJob({ id: job.id! });
}
console.log(job.status === TranscriptionJobStatus.Completed ? job.result?.text : job.errors);
}
main();
import com.dixilang.koldan.sdk.ApiClient;
import com.dixilang.koldan.sdk.Configuration;
import com.dixilang.koldan.sdk.api.SpeechTranscriptionsApi;
import com.dixilang.koldan.sdk.auth.ApiKeyAuth;
import com.dixilang.koldan.sdk.model.TranscriptionJobStatus;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.io.File;
import java.util.Set;
public class Example {
private static final Set<TranscriptionJobStatus> TERMINAL_STATUSES = Set.of(TranscriptionJobStatus.COMPLETED, TranscriptionJobStatus.FAILED, TranscriptionJobStatus.CANCELLED);
public static void main(String[] args) {
System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://koldan.dixilang.com");
ApiKeyAuth apiKey = (ApiKeyAuth) client.getAuthentication("apiKey");
apiKey.setApiKey("YOUR_API_KEY");
SpeechTranscriptionsApi api = new SpeechTranscriptionsApi(client);
try {
var response = api.uploadAndTranscribe(
"meeting-recording",
"{\"model\":\"general\",\"language\":{\"defaultLanguageCode\":\"he\"},\"punctuation\":false,\"capitalization\":false}",
null,
new File("sample-audio.wav"),
null,
"Team meeting recording for transcription",
"/incoming-audio/",
"{\"source\":\"upload\",\"type\":\"meeting-recording\"}",
"{\"enabled\":false}",
null,
null,
"[\"meeting\",\"transcription\"]"
);
var job = response.getJob();
while (!TERMINAL_STATUSES.contains(job.getStatus())) {
Thread.sleep(2000);
job = api.getJob(job.getId());
}
System.out.println(TranscriptionJobStatus.COMPLETED.equals(job.getStatus()) ? job.getResult().getText() : job.getErrors());
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"time"
koldan "koldan-sdk"
)
func main() {
cfg := koldan.NewConfiguration()
cfg.Servers[0].URL = "https://koldan.dixilang.com"
client := koldan.NewAPIClient(cfg)
ctx := context.WithValue(context.Background(), koldan.ContextAPIKeys, map[string]koldan.APIKey{
"apiKey": {Key: "YOUR_API_KEY"},
})
f, _ := os.Open("sample-audio.wav")
defer f.Close()
resp, _, _ := client.SpeechTranscriptionsAPI.UploadAndTranscribe(ctx).
Name("meeting-recording").
Transcription(`{"model":"general","language":{"defaultLanguageCode":"he"},"punctuation":false,"capitalization":false}`).
Diarization(`{"enabled":false}`).
File(f).
Execute()
job := resp.GetJob()
for {
jobResp, _, _ := client.SpeechTranscriptionsAPI.GetJob(ctx, job.GetId()).Execute()
job = *jobResp
if job.GetStatus() == koldan.COMPLETED || job.GetStatus() == koldan.FAILED || job.GetStatus() == koldan.CANCELLED {
break
}
time.Sleep(2 * time.Second)
}
if job.GetStatus() == koldan.COMPLETED {
result := job.GetResult()
fmt.Println(result.GetText())
} else {
errs, _ := json.Marshal(job.GetErrors())
fmt.Println(string(errs))
}
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "apiClient.h"
#include "SpeechTranscriptionsAPI.h"
int main(void) {
apiClient_t *client = apiClient_create_with_base_path("https://koldan.dixilang.com", NULL, NULL);
apiClient_setApiKey(client, "YOUR_API_KEY");
upload_and_transcribe_200_response_t *resp =
SpeechTranscriptionsAPI_uploadAndTranscribe(
client, "meeting-recording",
"{\"model\":\"general\",\"language\":{\"defaultLanguageCode\":\"he\"},\"punctuation\":false,\"capitalization\":false}",
NULL, "sample-audio.wav", NULL, NULL, NULL,
"{\"enabled\":false}", NULL, NULL, NULL);
job_t *job = resp->job;
while (1) {
job = SpeechTranscriptionsAPI_getJob(client, job->id);
if (strcmp(job->status, "COMPLETED") == 0 ||
strcmp(job->status, "FAILED") == 0 ||
strcmp(job->status, "CANCELLED") == 0) break;
sleep(2);
}
if (strcmp(job->status, "COMPLETED") == 0)
printf("%s\n", job->result->text);
else
printf("Job did not complete successfully.\n");
apiClient_free(client);
return 0;
}
#include <iostream>
#include <fstream>
#include <thread>
#include <chrono>
#include "ApiClient.h"
#include "api/SpeechTranscriptionsApi.h"
using namespace com::dixilang::koldan::sdk::api;
using namespace com::dixilang::koldan::sdk::model;
int main() {
auto config = std::make_shared<ApiConfiguration>();
config->setBaseUrl(utility::conversions::to_string_t("https://koldan.dixilang.com"));
config->setApiKey(utility::conversions::to_string_t("apiKey"), utility::conversions::to_string_t("YOUR_API_KEY"));
auto apiClient = std::make_shared<ApiClient>(config);
SpeechTranscriptionsApi api(apiClient);
auto httpContent = std::make_shared<HttpContent>();
httpContent->setData(std::make_shared<std::ifstream>("sample-audio.wav", std::ios::binary));
httpContent->setContentType(utility::conversions::to_string_t("audio/wav"));
auto response = api.uploadAndTranscribe(
utility::conversions::to_string_t("meeting-recording"),
utility::conversions::to_string_t(R"({"model":"general","language":{"defaultLanguageCode":"he"},"punctuation":false,"capitalization":false})"),
boost::none, boost::optional<std::shared_ptr<HttpContent>>(httpContent),
boost::none, boost::none, boost::none,
boost::optional<utility::string_t>(utility::conversions::to_string_t(R"({"enabled":false})")),
boost::none, boost::none, boost::none, boost::none
).get();
using eStatus = TranscriptionJobStatus::eTranscriptionJobStatus;
auto job = response->getJob();
while (true) {
job = api.getJob(job->getId()).get();
const auto status = job->getStatus()->getValue();
if (status == eStatus::COMPLETED || status == eStatus::FAILED || status == eStatus::CANCELLED) break;
std::this_thread::sleep_for(std::chrono::seconds(2));
}
if (job->getStatus()->getValue() == eStatus::COMPLETED)
std::cout << utility::conversions::to_utf8string(job->getResult()->getText()) << std::endl;
else
std::cout << "Job did not complete successfully." << std::endl;
return 0;
}
using System.Text.Json;
using System.Text.Encodings.Web;
using Koldan.Sdk.Api;
using Koldan.Sdk.Client;
using Koldan.Sdk.Model;
var config = new Configuration
{
BasePath = "https://koldan.dixilang.com",
};
config.AddApiKey("X-API-Key", "YOUR_API_KEY");
var terminalStatuses = new HashSet<TranscriptionJobStatus>
{
TranscriptionJobStatus.COMPLETED,
TranscriptionJobStatus.FAILED,
TranscriptionJobStatus.CANCELLED
};
var api = new SpeechTranscriptionsApi(config);
using var stream = File.OpenRead("sample-audio.wav");
var response = api.UploadAndTranscribe(
name: "meeting-recording",
transcription: JsonSerializer.Serialize(new
{
model = "general",
language = new { defaultLanguageCode = "he" },
punctuation = false,
capitalization = false
}),
file: stream,
path: "/incoming-audio/",
metadata: "{\"source\":\"upload\",\"type\":\"meeting-recording\"}",
diarization: "{\"enabled\":false}",
tags: "[\"meeting\",\"transcription\"]"
);
var job = response.Job!;
while (job.Status == null || !terminalStatuses.Contains(job.Status.Value))
{
await Task.Delay(TimeSpan.FromSeconds(2));
job = api.GetJob(job.Id!.Value);
}
var jsonOptions = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
Console.WriteLine(job.Status == TranscriptionJobStatus.COMPLETED
? JsonSerializer.Serialize(job.Result?.Text, jsonOptions)
: JsonSerializer.Serialize(job.Errors, jsonOptions));
Versioning and Support
Keep your SDK in sync
SDK archives are tagged with the same version as the Koldan server that produced them. When you upgrade the server, re-download the matching SDK to pick up new endpoints, models, and bug fixes.
Need a language that isn't listed?
The OpenAPI specification can be used with openapi-generator or any compatible tool to produce clients for Rust, PHP, Ruby, Swift, Kotlin, and many more. If you build one, we'd love to hear about it.