Control plane
Discover hubs and create client identities.
Copy-paste Thalovant SDK examples for control-plane calls, identities, runtime requests, events, and context.
Use this page when you want to build with the SDK, not memorize every method name.
Start with the quick example, then copy the recipe closest to your task. Each recipe shows the same idea in Python, Node.js, Go, and Rust where the SDKs expose it. The Quick Start, Sign In, and Create A Client Identity recipes also show Kotlin, Swift, and C#; for the full surface of those SDKs, use the Kotlin, Swift, and .NET SDK pages.
Every call is shown in each language that has it, so you can compare one operation across SDKs without opening five pages.
| If you are… | Open |
|---|---|
| Getting a client and signing in | Signing in and creating a client |
| Looking up or creating hubs | Finding and provisioning hubs |
| Issuing a client identity | Client identities and protocols |
| Asking a hub something | Talking to a hub |
| Listening for events, or debugging | Events, context, and diagnostics |
This example signs in, creates a client identity for one hub, connects, sends one request, and prints the reply.
from thalovant import ThalovantClient, ThalovantControlPlane
api = ThalovantControlPlane()
result = api.create_client_identity( "hub-id", name="python-demo-client", preferred_protocols=("wss", "https", "mqtt"),)
with ThalovantClient(result.identity, protocol="wss") as client: reply = client.ask("Tell me a short clean joke.") print(reply.text)import { ThalovantClient, ThalovantControlPlane } from "@thalovant/sdk";
const api = new ThalovantControlPlane();
const result = await api.createClientIdentity("hub-id", { name: "node-demo-client", preferredProtocols: ["wss", "https", "mqtt"],});
const client = new ThalovantClient(result.identity, { protocol: "wss" });try { const reply = await client.ask("Tell me a short clean joke."); console.log(reply.text);} finally { await client.close();}package main
import ( "context" "fmt" "log"
thalovant "github.com/thalovant/thalovant-go-sdk")
func main() { ctx := context.Background() api := thalovant.NewDefaultControlPlane("")
log.Fatal(err) }
result, err := api.CreateClientIdentityForHubID(ctx, "hub-id", thalovant.BootstrapIdentityOptions{ Name: "go-demo-client", PreferredProtocols: []thalovant.HubProtocol{thalovant.ProtocolWSS, thalovant.ProtocolHTTPS, thalovant.ProtocolMQTT}, }) if err != nil { log.Fatal(err) }
client, err := thalovant.NewClientWithOptions(result.Identity, thalovant.ClientOptions{Protocol: thalovant.ProtocolWSS}) if err != nil { log.Fatal(err) } defer client.Close(ctx)
reply, err := client.Ask(ctx, "Tell me a short clean joke.", thalovant.RequestOptions{}) if err != nil { log.Fatal(err) } fmt.Println(reply.Text)}use thalovant::{BootstrapIdentityOptions, Client, ControlPlane, HubProtocol, RequestOptions};
#[tokio::main]async fn main() -> thalovant::Result<()> { let mut api = ControlPlane::default();
let result = api .create_client_identity_for_hub_id( "hub-id", BootstrapIdentityOptions { name: "rust-demo-client".into(), preferred_protocols: vec![HubProtocol::Wss, HubProtocol::Https, HubProtocol::Mqtt], ..Default::default() }, ) .await?;
let client = Client::with_protocol(result.identity.clone(), HubProtocol::Wss)?; let reply = client.ask("Tell me a short clean joke.", RequestOptions::default()).await; let closed = client.close().await; let reply = reply?; closed?; println!("{}", reply.text);
Ok(())}import com.thalovant.sdk.CreateClientIdentityOptionsimport com.thalovant.sdk.ThalovantClientimport com.thalovant.sdk.ThalovantControlPlaneimport kotlinx.coroutines.runBlocking
fun main() = runBlocking { val api = ThalovantControlPlane()
val result = api.createClientIdentity( "hub-id", CreateClientIdentityOptions(name = "kotlin-demo-client"), )
val client = ThalovantClient(result.identity) try { val reply = client.ask("Tell me a short clean joke.") println(reply.text) } finally { client.close() }}import ThalovantSDK
let api = ThalovantControlPlane()
let result = try await api.createClientIdentity( hubId: "hub-id", options: CreateClientIdentityOptions(name: "swift-demo-client"))
let client = try ThalovantClient(identity: result.identity)do { try await client.connect() let reply = try await client.ask("Tell me a short clean joke.") print(reply.text) await client.close()} catch { await client.close() throw error}using Thalovant;
var api = new ThalovantControlPlane();
var result = await api.CreateClientIdentityAsync( "hub-id", new CreateClientIdentityOptions("dotnet-demo-client"));
using var client = new ThalovantClient(result.Identity);await client.ConnectAsync();var reply = await client.AskAsync("Tell me a short clean joke.");Console.WriteLine(reply.Text);await client.CloseAsync();The Kotlin, Swift, and C# clients connect over WSS only, so they take no protocol argument here. These examples require the current v3-compatible SDK versions.
Expected result:
Why did the hub keep good logs? It wanted every punchline to be traceable.Control plane
Discover hubs and create client identities.
Identity
Load saved credentials and choose a protocol.
Runtime client
Connect, ask, emit events, and send structured input.
Events and context
Listen for hub events and attach session metadata.
Use this table only when you already know the task and need the language-specific name.
| Task | Python | Node.js | Go | Rust |
|---|---|---|---|---|
| Create API client | ThalovantControlPlane() | new ThalovantControlPlane() | NewDefaultControlPlane(token) | ControlPlane::default() |
| Sign in | login(email, password) | login(email, password) | Login(ctx, email, password, scope) | login(email, password, scope) |
| Sign in with MFA | login(..., otp_code=..., recovery_code=...) | login(..., { otpCode, recoveryCode }) | LoginWithOptions(ctx, email, password, options) | login_with_options(email, password, options) |
| Sign in without a password | login_with_browser(...) | loginWithBrowser(options) | LoginWithBrowser(ctx, options) | login_with_browser(options) |
| Use an API token | ThalovantControlPlane(access_token=...) | new ThalovantControlPlane(url, { accessToken }) | NewDefaultControlPlane(token) | ControlPlane::with_access_token(token) |
| List public hubs | list_public_hubs(...) | listPublicHubs(...) | ListPublicHubs(ctx, limit, cursor) | list_public_hubs(limit, cursor) |
| Get public hub | get_public_hub(ref) | getPublicHub(ref) | GetPublicHub(ctx, ref) | get_public_hub(ref) |
| List visible hubs | list_hubs(...) | listHubs(...) | ListHubs(ctx, limit, cursor, ownerID) | list_hubs(limit, cursor, owner_id) |
| Get hub | get_hub(hub_id) | getHub(hubId) | GetHub(ctx, hubID) | get_hub(hub_id) |
| Get operation | get_operation(operation_id) | getOperation(operationId) | GetOperation(ctx, operationID) | get_operation(operation_id) |
| Create identity | create_client_identity(...) | createClientIdentity(...) | CreateClientIdentityForHubID(...) | create_client_identity_for_hub_id(...) |
| List hub skills | list_hub_skills(hub_id) | listHubSkills(hubId) | ListHubSkills(ctx, hubID) | list_hub_skills(hub_id) |
| List hub skill history | list_hub_skill_history(hub_id, limit=50) | listHubSkillHistory(hubId, { limit: 50 }) | ListHubSkillHistory(ctx, hubID, 50) | list_hub_skill_history(hub_id, 50) |
| Install hub skill | install_hub_skill(hub_id, skill, version=, wait=) | installHubSkill(hubId, skill, { version, wait }) | InstallHubSkill(ctx, hubID, skill, version, options) | install_hub_skill(hub_id, skill, version, options) |
| Update hub skill | update_hub_skill(hub_id, skill, version=, wait=) | updateHubSkill(hubId, skill, { version, wait }) | UpdateHubSkill(ctx, hubID, skill, version, options) | update_hub_skill(hub_id, skill, version, options) |
| Remove hub skill | remove_hub_skill(hub_id, skill, wait=) | removeHubSkill(hubId, skill, { wait }) | RemoveHubSkill(ctx, hubID, skill, options) | remove_hub_skill(hub_id, skill, options) |
Hub skill calls and history are available in all seven managed SDKs at the current versions. The provisioning calls have their own naming table on Provision Hubs.
| Task | Python | Node.js | Go | Rust |
|---|---|---|---|---|
| Load identity from config | ThalovantIdentity.from_config(...) | ThalovantIdentity.fromConfig(...) | IdentityFromConfig(path, profile) | Identity::from_config(profile) |
| Load identity file | ThalovantIdentity.from_file(path) | ThalovantIdentity.fromFile(path) | IdentityFromFile(path) | Identity::from_file(path) |
| Load client from file | ThalovantClient.from_identity_file(path) | ThalovantClient.fromIdentityFile(path) | NewClientFromFile(path) | Client::from_file(path) |
| Load client from config | ThalovantClient.from_config(...) | ThalovantClient.fromConfig(...) | NewClientFromConfig(path, profile) | Client::from_config(profile) |
| Load client from env | ThalovantClient.from_env() | ThalovantClient.fromEnv() | NewClientFromEnv() | Client::from_env() |
| Enabled protocols | enabled_protocols() | enabledProtocols() | EnabledProtocols() | enabled_protocols() |
| Endpoint for protocol | endpoint_for(protocol) | endpointFor(protocol) | EndpointFor(protocol) | endpoint_for(protocol) |
| Check protocol | supports_protocol(protocol) | supportsProtocol(protocol) | SupportsProtocol(protocol) | supports_protocol(protocol) |
| MQTT credentials | identity.mqtt | identity.mqtt | Identity.MQTT | identity.mqtt |
| Task | Python | Node.js | Go | Rust |
|---|---|---|---|---|
| Create protocol client | ThalovantClient(identity, protocol="wss") | new ThalovantClient(identity, { protocol }) | NewClientWithOptions(identity, ClientOptions{Protocol: ...}) | Client::with_protocol(identity, protocol) |
| Connect | connect() | connect() | Connect(ctx) | connect() |
| Close | close() | close() | Close(ctx) | close() |
| Health | healthcheck() | healthcheck() | Healthcheck() | healthcheck() |
| Ask | ask(text, ...) | ask(text, options) | Ask(ctx, text, options) | ask(text, options) |
| Emit raw event | emit(event, data, context) | emit(event, data, context) | Emit(ctx, event, data, context) | emit(event, data, context) |
| Send utterance | send_utterance(text, ...) | sendUtterance(text, options) | SendUtterance(ctx, text, options) | send_utterance(text, options) |
| Send action | send_action(payload, ...) | sendAction(payload, options) | SendAction(ctx, payload, options) | send_action(payload, options) |
| Send code | send_code(value, ...) | sendCode(value, options) | SendCode(ctx, value, options) | send_code(value, options) |
| Conversation | conversation(...) | conversation(options) | Conversation(options) | conversation(options) |
| Intent inventory | intents(languages, ...) | intents(languages) | Intents(ctx, languages, options) | intents(languages, options) |
| List intents | list_intents(lang, ...) | listIntents(lang) | ListIntents(ctx, lang, options) | list_intents(lang, options) |
| Describe intent | describe_intent(skill_id, intent_name, lang, ...) | describeIntent(skillId, intentName, lang) | DescribeIntent(ctx, skillID, intentName, lang, options) | describe_intent(skill_id, intent_name, lang, options) |
| Policy refusal | ThalovantPolicyDeniedError | ThalovantPolicyDeniedError | PolicyDeniedError | ThalovantError::PolicyDenied |
The intent rows are published in every SDK. The SDKs page lists the version each one shipped them in, and the Kotlin, Swift, .NET, and embedded C spellings are on their own SDK pages.
| Task | Python | Node.js | Go | Rust |
|---|---|---|---|---|
| Wait for event | wait_for_event(name, ...) | waitForEvent(name, options) | WaitForEvent(ctx, name, options) | wait_for_event(name, options) |
| Stream events | listen(name, ...) | on(name, handler, options) | Listen(ctx, name, options) | listen(name, options) |
| Diagnostics | doctor() | healthcheck() | Healthcheck() | healthcheck() |
| Build context | build_client_context(...) | buildClientContext(...) | BuildClientContext(...) | build_client_context(...) |
| Response text | reply.text | reply.text | reply.Text | reply.text |
| Display items | reply.display_items(...) | reply.displayItems(...) | reply.DisplayItems(...) | reply.display_items(...) |
| Event text | event.text | event.text | event.Text() | event.text() |
Hub-addressed skill helpers are now available in all seven managed SDKs, including history and optional operation waiting. They operate on the attached runtime group; every hub sharing it is affected. See each SDK reference for its method names. Embedded C has no provisioning HTTP client.