Overview
A dispatch rule determines which room each inbound SIP caller joins. You can send each caller to a dedicated room, put all callers in one room, or route them to a specific room by name or other criteria. When an inbound call reaches your SIP trunk and is handed off to LiveKit, the SIP service finds a matching dispatch rule and uses it to add the caller as a SIP participant to the appropriate room (creating the room if needed).
Create a dispatch rule using the CreateSIPDispatchRule API. By default, a dispatch rule matches all your trunks and makes a caller's phone number visible to others in the room. You can modify these defaults with dispatch rule options. For a full list of available options, see the CreateSIPDispatchRule API reference.
Dispatch rules are long-lived configuration objects meant to be reused. Create your dispatch rules once and reuse them for every call. Creating a new rule for each call adds unnecessary load and can degrade reliability at scale. To give each caller a unique room, rely on room naming within a single rule: an individual dispatch rule adds a random suffix per caller, and a callee dispatch rule names the room after the number that was dialed.
Dispatch to an agent
Use an individual dispatch rule to place each caller in their own room, and include the roomConfig option so your agent joins those rooms. See Agent dispatch for roomConfig parameters.
Individual dispatch rule
An SIPDispatchRuleIndividual rule creates a new room for each caller. The name of the created room is the phone number of the caller plus a random suffix. You can optionally add a specific prefix to the room name by using the roomPrefix option.
The following examples dispatch callers into individual rooms prefixed with call-, and dispatches an agent named inbound-agent to newly created rooms:
{"dispatch_rule":{"rule": {"dispatchRuleIndividual": {"roomPrefix": "call-"}},"name": "My dispatch rule","roomConfig": {"agents": [{"agentName": "inbound-agent","metadata": "job dispatch metadata"}]}}}
import {LiveKitAPI,SipDispatchRuleIndividual,CreateSipDispatchRuleOptions,} from 'livekit-server-sdk';import { RoomConfiguration, RoomAgentDispatch } from '@livekit/protocol';const api = new LiveKitAPI();const rule: SipDispatchRuleIndividual = {roomPrefix: 'call-',type: 'individual',};const options: CreateSipDispatchRuleOptions = {name: 'My dispatch rule',roomConfig: new RoomConfiguration({agents: [new RoomAgentDispatch({agentName: 'inbound-agent',metadata: 'job dispatch metadata',}),],}),};const dispatchRule = await api.sip.createSipDispatchRule(rule, options);console.log('created dispatch rule', dispatchRule);
from livekit import apilkapi = api.LiveKitAPI()# Create a dispatch rule to place each caller in a separate roomrule = api.SIPDispatchRule(dispatch_rule_individual = api.SIPDispatchRuleIndividual(room_prefix = 'call-',))request = api.CreateSIPDispatchRuleRequest(dispatch_rule = api.SIPDispatchRuleInfo(rule = rule,name = 'My dispatch rule',trunk_ids = [],room_config=api.RoomConfiguration(agents=[api.RoomAgentDispatch(agent_name="inbound-agent",metadata="job dispatch metadata",)])))dispatch = await lkapi.sip.create_sip_dispatch_rule(request)print("created dispatch", dispatch)await lkapi.aclose()
require 'livekit'lkapi = LiveKit::LiveKitAPI.newrule = LiveKit::Proto::SIPDispatchRule.new(dispatch_rule_individual: LiveKit::Proto::SIPDispatchRuleIndividual.new(room_prefix: "call-",))resp = lkapi.sip.create_sip_dispatch_rule(rule,name: "My dispatch rule",room_config: LiveKit::Proto::RoomConfiguration.new(agents: [LiveKit::Proto::RoomAgentDispatch.new(agent_name: "inbound-agent",metadata: "job dispatch metadata",)]))puts resp
package mainimport ("context""fmt""github.com/livekit/protocol/livekit"lksdk "github.com/livekit/server-sdk-go/v2")func main() {rule := &livekit.SIPDispatchRule{Rule: &livekit.SIPDispatchRule_DispatchRuleIndividual{DispatchRuleIndividual: &livekit.SIPDispatchRuleIndividual{RoomPrefix: "call-",},},}request := &livekit.CreateSIPDispatchRuleRequest{DispatchRule: &livekit.SIPDispatchRuleInfo{Name: "My dispatch rule",Rule: rule,RoomConfig: &livekit.RoomConfiguration{Agents: []*livekit.RoomAgentDispatch{{AgentName: "inbound-agent",Metadata: "job dispatch metadata",},},},},}api, err := lksdk.NewLiveKitAPI()if err != nil {fmt.Println(err)return}// Execute the requestdispatchRule, err := api.SIP().CreateSIPDispatchRule(context.Background(), request)if err != nil {fmt.Println(err)} else {fmt.Println(dispatchRule)}}
import io.livekit.server.LiveKitAPIimport io.livekit.server.SipDispatchRuleIndividualimport io.livekit.server.CreateSipDispatchRuleOptionsimport livekit.LivekitRoom.RoomConfigurationimport livekit.LivekitAgentDispatchval api = LiveKitAPI.createClient(host = System.getenv("LIVEKIT_URL"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"))val rule = SipDispatchRuleIndividual(roomPrefix = "call-")val roomConfig = RoomConfiguration.newBuilder().addAgents(LivekitAgentDispatch.RoomAgentDispatch.newBuilder().setAgentName("inbound-agent").setMetadata("job dispatch metadata").build()).build()val response = api.sip.createSipDispatchRule(rule = rule,options = CreateSipDispatchRuleOptions(name = "My dispatch rule",roomConfig = roomConfig)).execute()if (response.isSuccessful) {val dispatchRule = response.body()println("Dispatch rule created: ${dispatchRule}")}
use livekit_api::services::sip::CreateSIPDispatchRuleOptions;use livekit_api::services::LiveKitApi;use livekit_protocol as proto;#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {// host is required; API key and secret are read from// LIVEKIT_API_KEY and LIVEKIT_API_SECRET.let api = LiveKitApi::new("https://<your-subdomain>.livekit.cloud")?;let rule = proto::sip_dispatch_rule::Rule::DispatchRuleIndividual(proto::SipDispatchRuleIndividual {room_prefix: "call-".to_owned(),..Default::default()},);let options = CreateSIPDispatchRuleOptions {name: "My dispatch rule".to_owned(),// Dispatch an agent into each room created by this rule.room_config: Some(proto::RoomConfiguration {agents: vec![proto::RoomAgentDispatch {agent_name: "inbound-agent".to_owned(),metadata: "job dispatch metadata".to_owned(),..Default::default()}],..Default::default()}),..Default::default()};let dispatch_rule = api.sip().create_sip_dispatch_rule(rule, options).await?;println!("created dispatch rule {:?}", dispatch_rule);Ok(())}
Sign in to the LiveKit Cloud dashboard .
Select Telephony → Dispatch rules .
Select Create new dispatch rule.
Select the JSON editor tab.
Full parameter accessYou can also use the Dispatch rule details tab to create a dispatch rule. However, the JSON editor allows you to configure all available parameters.
Copy and paste the following JSON:
{"rule": {"dispatchRuleIndividual": {"roomPrefix": "call-"}},"name": "My dispatch rule","roomConfig": {"agents": [{"agentName": "inbound-agent","metadata": "job dispatch metadata"}]}}Select Create.
When you omit the trunk_ids field, the dispatch rule matches calls from all inbound trunks.
Agent dispatch
Use the roomConfig parameter on a dispatch rule to specify which agents are dispatched to a room when it's created. The agents parameter for roomConfig is an array of agent dispatch entries. Each entry can include the following fields:
agentName: Name of the agent to dispatch (required).metadata: Optional string metadata passed to the agent job.
Your agent receives the metadata string as job metadata. Access it in the entrypoint function using ctx.job.metadata. This is useful for routing or customizing agent behavior based on the dispatch rule. For example, you can route calls to different data stores or workflows:
import json@server.rtc_session(agent_name="inbound-agent")async def my_agent(ctx: JobContext):metadata = json.loads(ctx.job.metadata)store_id = metadata.get("store_id")# Route to the correct store based on dispatch metadata
export default {async entry(ctx: JobContext) {const metadata = JSON.parse(ctx.job.metadata);const storeId = metadata.storeId;// Route to the correct store based on dispatch metadata},};
To learn more, see Job metadata.
For the full set of room configuration options, see RoomConfiguration in the SIP API reference. For agent dispatch behavior and configuration, see Agent dispatch.
Dispatch to rooms
The following rule types dispatch callers to shared rooms. Use them when you want all callers in the same room or when room assignment is based on the called number.
A direct dispatch rule with a static roomName, or a callee dispatch rule with randomize set to false, routes unrelated callers into the same room, where they can hear each other. For production telephony where each caller should be isolated, use an individual dispatch rule or a callee rule with the default randomize=true so each call gets a unique room.
Direct dispatch rule
A direct dispatch rule places all callers into a specified room. You can optionally protect room access by adding a pin in the pin field:
In the following examples, all calls are immediately connected to room open-room on LiveKit.
Create a file named
dispatch-rule.jsonand add the following:{"dispatch_rule":{"rule": {"dispatchRuleDirect": {"roomName": "open-room"}},"name": "My dispatch rule"}}Create the dispatch rule using
lk:lk sip dispatch create dispatch-rule.json
import {LiveKitAPI,SipDispatchRuleDirect,CreateSipDispatchRuleOptions,ServerError,} from 'livekit-server-sdk';const api = new LiveKitAPI();// Dispatch all callers to the same roomconst rule: SipDispatchRuleDirect = {roomName: 'open-room',type: 'direct',};const options: CreateSipDispatchRuleOptions = {name: 'My dispatch rule',};try {const dispatchRule = await api.sip.createSipDispatchRule(rule, options);console.log(dispatchRule);} catch (e) {if (e instanceof ServerError) {console.error(`${e.code} error: ${e.message}`);} else {throw e;}}
import asynciofrom livekit import apiasync def main():livekit_api = api.LiveKitAPI()# Create a dispatch rule to place all callers in the same roomrule = api.SIPDispatchRule(dispatch_rule_direct = api.SIPDispatchRuleDirect(room_name = 'open-room',))request = api.CreateSIPDispatchRuleRequest(dispatch_rule = api.SIPDispatchRuleInfo(rule = rule,name = 'My dispatch rule',))try:dispatchRule = await livekit_api.sip.create_sip_dispatch_rule(request)print(f"Successfully created {dispatchRule}")except api.ServerError as e:print(f"{e.code} error: {e.message}")await livekit_api.aclose()asyncio.run(main())
require 'livekit'name = "My dispatch rule"room_name = "open-room"lkapi = LiveKit::LiveKitAPI.newrule = LiveKit::Proto::SIPDispatchRule.new(dispatch_rule_direct: LiveKit::Proto::SIPDispatchRuleDirect.new(room_name: room_name,))beginresp = lkapi.sip.create_sip_dispatch_rule(rule,name: name,)puts resprescue LiveKit::ServerError => eputs "#{e.code} error: #{e.message}"end
package mainimport ("context""errors""fmt""github.com/livekit/protocol/livekit"lksdk "github.com/livekit/server-sdk-go/v2")func main() {// Specify rule type and optionsrule := &livekit.SIPDispatchRule{Rule: &livekit.SIPDispatchRule_DispatchRuleDirect{DispatchRuleDirect: &livekit.SIPDispatchRuleDirect{RoomName: "open-room",},},}// Create requestrequest := &livekit.CreateSIPDispatchRuleRequest{DispatchRule: &livekit.SIPDispatchRuleInfo{Rule: rule,Name: "My dispatch rule",},}api, err := lksdk.NewLiveKitAPI()if err != nil {fmt.Println(err)return}// Execute the requestdispatchRule, err := api.SIP().CreateSIPDispatchRule(context.Background(), request)if err != nil {var se lksdk.ServerErrorif errors.As(err, &se) {fmt.Printf("%s error: %s\n", se.Code(), se.Msg())} else {fmt.Println(err)}} else {fmt.Println(dispatchRule)}}
import io.livekit.server.LiveKitAPIimport io.livekit.server.SipDispatchRuleDirectimport io.livekit.server.CreateSipDispatchRuleOptionsimport io.livekit.server.ServerErrorval api = LiveKitAPI.createClient(host = System.getenv("LIVEKIT_URL"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"))val rule = SipDispatchRuleDirect(roomName = "open-room")val response = api.sip.createSipDispatchRule(rule = rule,options = CreateSipDispatchRuleOptions(name = "My dispatch rule")).execute()if (response.isSuccessful) {val dispatchRule = response.body()println("Dispatch rule created: ${dispatchRule}")} else {val error = ServerError.from(response)println("${error?.code} error: ${error?.message}")}
use livekit_api::services::sip::CreateSIPDispatchRuleOptions;use livekit_api::services::LiveKitApi;use livekit_protocol as proto;#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {// host is required; API key and secret are read from// LIVEKIT_API_KEY and LIVEKIT_API_SECRET.let api = LiveKitApi::new("https://<your-subdomain>.livekit.cloud")?;// Dispatch all callers to the same roomlet rule = proto::sip_dispatch_rule::Rule::DispatchRuleDirect(proto::SipDispatchRuleDirect {room_name: "open-room".to_owned(),..Default::default()});let options = CreateSIPDispatchRuleOptions {name: "My dispatch rule".to_owned(),..Default::default()};match api.sip().create_sip_dispatch_rule(rule, options).await {Ok(dispatch_rule) => println!("{:?}", dispatch_rule),Err(e) => eprintln!("failed to create dispatch rule: {e}"),}Ok(())}
Sign in to the LiveKit Cloud dashboard .
Select Telephony → Dispatch rules .
Select Create new dispatch rule.
Select the JSON editor tab.
Form editorYou can also use the Dispatch rule details tab for this example by selecting Direct for Rule type.
Copy and paste the following JSON:
{"rule": {"dispatchRuleDirect": {"roomName": "open-room"}},"name": "My dispatch rule"}Select Create.
Pin-protected room
Add a pin to a room to require callers to enter a pin to connect to a room in LiveKit. The following example requires callers to enter 12345# on the phone to enter safe-room:
{"dispatch_rule":{"trunk_ids": [],"rule": {"dispatchRuleDirect": {"roomName": "safe-room","pin": "12345"}},"name": "My dispatch rule"}}
Callee dispatch rule
This creates a dispatch rule that puts callers into rooms based on the called number. The name of the room is the called phone number plus an optional prefix (if roomPrefix is set). You can optionally add a random suffix for each caller by setting randomize to true, making a separate room per caller.
{"dispatch_rule":{"rule": {"dispatchRuleCallee": {"roomPrefix": "number-","randomize": false}},"name": "My dispatch rule"}}
For an executable example, replace the rule in the Direct dispatch rule example with the following rule:
import { SipDispatchRuleCallee } from 'livekit-server-sdk';// Create a dispatch rule to place callers to the same phone number in the same roomconst rule: SipDispatchRuleCallee = {roomPrefix: 'number-',randomize: false,type: 'callee',};
For an executable example, replace the rule in the Direct dispatch rule example with the following rule:
from livekit import api# Create a dispatch rule to place callers to the same phone number in the same roomrule = api.SIPDispatchRule(dispatch_rule_callee = api.SIPDispatchRuleCallee(room_prefix = 'number-',randomize = False,))
For an executable example, replace the rule in the Direct dispatch rule example with the following rule:
rule = LiveKit::Proto::SIPDispatchRule.new(dispatch_rule_callee: LiveKit::Proto::SIPDispatchRuleCallee.new(room_prefix: 'number-',randomize: false,))
For an executable example, replace the rule in the Direct dispatch rule example with the following rule:
rule := &livekit.SIPDispatchRule{Rule: &livekit.SIPDispatchRule_DispatchRuleCallee{DispatchRuleCallee: &livekit.SIPDispatchRuleCallee{RoomPrefix: "number-",Randomize: false,},},}
For an executable example, replace the rule in the Direct dispatch rule example with the following rule:
import io.livekit.server.SipDispatchRuleCallee// Create a dispatch rule to place callers to the same phone number in the same roomval rule = SipDispatchRuleCallee(roomPrefix = "number-",randomize = false,)
For an executable example, replace the rule in the Direct dispatch rule example with the following rule:
let rule = proto::sip_dispatch_rule::Rule::DispatchRuleCallee(proto::SipDispatchRuleCallee {room_prefix: "number-".to_owned(),randomize: false,..Default::default()});
Sign in to the LiveKit Cloud dashboard .
Select Telephony → Dispatch rules .
Select Create new dispatch rule.
Select the JSON editor tab.
Form editorYou can also use the Dispatch rule details tab for this example by selecting Callee for Rule type.
Copy and paste the following JSON:
{"rule": {"dispatchRuleCallee": {"roomPrefix": "number-","randomize": false}},"name": "My dispatch rule"}Select Create.
Setting custom attributes on inbound SIP participants
LiveKit participants have an attributes field that stores key-value pairs. You can add custom attributes for SIP participants in the dispatch rule. These attributes are inherited by all SIP participants created by the dispatch rule.
To learn more, see SIP participant attributes.
The following examples add two attributes to SIP participants created by this dispatch rule:
{"dispatch_rule":{"attributes": {"<key_name1>": "<value1>","<key_name2>": "<value2>"},"rule": {"dispatchRuleIndividual": {"roomPrefix": "call-"}},"name": "My dispatch rule"}}
For an executable example, replace options in the Direct dispatch rule example with the following options:
const options: CreateSipDispatchRuleOptions = {name: 'My dispatch rule',attributes: {"<key_name1>": "<value1>","<key_name2>": "<value2>"},};
For an executable example, replace request in the Direct dispatch rule example with the following options:
request = api.CreateSIPDispatchRuleRequest(dispatch_rule = api.SIPDispatchRuleInfo(rule = rule,name = 'My dispatch rule',attributes = {"<key_name1>": "<value1>","<key_name2>": "<value2>",}))
For an executable example, use the Direct dispatch rule example with the following options:
resp = lkapi.sip.create_sip_dispatch_rule(rule,name: name,attributes: {"<key_name1>" => "<value1>","<key_name2>" => "<value2>",},)
For an executable example, replace request in the Direct dispatch rule example with the following code:
// Create a requestrequest := &livekit.CreateSIPDispatchRuleRequest{DispatchRule: &livekit.SIPDispatchRuleInfo{Rule: rule,Name: "My dispatch rule",Attributes: map[string]string{"<key_name1>": "<value1>","<key_name2>": "<value2>",},},}
For an executable example, modify the parameters for CreateSipDispatchRuleOptions in the Direct dispatch rule example to include the attributes parameter:
val response = api.sip.createSipDispatchRule(rule = rule,options = CreateSipDispatchRuleOptions(name = "My dispatch rule",attributes = mapOf("<key_name1>" to "<value1>","<key_name2>" to "<value2>"))).execute()
For an executable example, replace options in the Direct dispatch rule example with the following options:
use std::collections::HashMap;let options = CreateSIPDispatchRuleOptions {name: "My dispatch rule".to_owned(),attributes: HashMap::from([("<key_name1>".to_owned(), "<value1>".to_owned()),("<key_name2>".to_owned(), "<value2>".to_owned()),]),..Default::default()};
Sign in to the LiveKit Cloud dashboard .
Select Telephony → Dispatch rules .
Select Create new dispatch rule.
Select the JSON editor tab.
Attributes parameter availabilityThe
attributesparameter is only available in the JSON editor tab.Copy and paste the following text into the editor:
{"name": "My dispatchrule","attributes": {"<key_name1>": "<value1>","<key_name2>": "<value2>"},"rule": {"dispatchRuleIndividual": {"roomPrefix": "call-"}}}Select Create.
Setting custom metadata on inbound SIP participants
LiveKit participants have a metadata field that can store arbitrary data for your application (typically JSON). It can also be set on SIP participants created by a dispatch rule. Specifically, metadata set on a dispatch rule will be inherited by all SIP participants created by it.
The following examples add the metadata, {"is_internal": true}, to all SIP participants created from an inbound call by this dispatch rule:
{"dispatch_rule": {"metadata": "{\"is_internal\": true}","rule": {"dispatchRuleIndividual": {"roomPrefix": "call-"}},"name": "My dispatch rule"}}
For an executable example, replace options in the Direct dispatch rule example with the following options:
const options: CreateSipDispatchRuleOptions = {name: 'My dispatch rule',metadata: "{\"is_internal\": true}",};
For an executable example, replace request in the Direct dispatch rule example with the following options:
request = api.CreateSIPDispatchRuleRequest(dispatch_rule = api.SIPDispatchRuleInfo(rule = rule,name = 'My dispatch rule',metadata = "{\"is_internal\": true}",))
For an executable example, use the Direct dispatch rule example with the following options:
resp = lkapi.sip.create_sip_dispatch_rule(rule,name: name,metadata: "{\"is_internal\": true}",)
For an executable example, replace request in the Direct dispatch rule example with the following options:
// Create a requestrequest := &livekit.CreateSIPDispatchRuleRequest{DispatchRule: &livekit.SIPDispatchRuleInfo{Rule: rule,Name: "My dispatch rule",Metadata: "{\"is_internal\": true}",},}
For an executable example, modify the parameters for CreateSipDispatchRuleOptions in the Direct dispatch rule example to include the metadata parameter:
val response = api.sip.createSipDispatchRule(rule = rule,options = CreateSipDispatchRuleOptions(name = "My dispatch rule",metadata = "{\"is_internal\": true}")).execute()
For an executable example, replace options in the Direct dispatch rule example with the following options:
let options = CreateSIPDispatchRuleOptions {name: "My dispatch rule".to_owned(),metadata: "{\"is_internal\": true}".to_owned(),..Default::default()};
Sign in to the LiveKit Cloud dashboard .
Select Telephony → Dispatch rules .
Select Create new dispatch rule.
Select the JSON editor tab.
Metadata parameter availabilityThe
metadataparameter is only available in the JSON editor tab.Copy and paste the following text into the editor:
{"name": "My dispatch rule","metadata": "{\"is_internal\": true}","rule": {"dispatchRuleIndividual": {"roomPrefix": "call-"}}}Select Create.
Update dispatch rule
Use the UpdateSIPDispatchRule API to update specific fields of a dispatch rule or replace a dispatch rule with a new one.
Update specific fields of a dispatch rule
The UpdateSIPDispatchRuleFields API allows you to update specific fields of a dispatch rule without affecting other fields.
Create a file named dispatch-rule.json with the following content:
{"name": "My updated dispatch rule","rule": {"dispatchRuleCallee": {"roomPrefix": "number-","randomize": false,"pin": "1234"}}}
Update the dispatch rule using lk. You can update the trunks parameter to a comma-separated string of trunks IDs if the rule matches specific trunks.
lk sip dispatch update --id <dispatch-rule-id> \--trunks "[]" \dispatch-rule.json
import { LiveKitAPI } from 'livekit-server-sdk';import { ListUpdate } from '@livekit/protocol';const api = new LiveKitAPI();const ruleId = '<dispatch-rule-id>';const updatedRuleFields = {name: 'My updated dispatch rule',trunkIds: new ListUpdate({ add: ["<trunk-id1>", "<trunk-id2>"] }), // Add trunk IDs to the dispatch rulemetadata: "{\"is_internal\": false}",};const rule = await api.sip.updateSipDispatchRuleFields(ruleId,updatedRuleFields,);console.log(rule);
import asynciofrom livekit import apifrom livekit.protocol.models import ListUpdateasync def main():"""Use the update_sip_dispatch_rule_fields method to update specific fields of a dispatch rule."""rule_id = '<dispatch-rule-id>'livekit_api = api.LiveKitAPI()dispatchRule = Nonetry:dispatchRule = await livekit_api.sip.update_sip_dispatch_rule_fields(rule_id=rule_id,trunk_ids=ListUpdate(add=["<trunk-id1>", "<trunk-id2>"]), # Add trunk IDs to the dispatch rulemetadata="{\"is_internal\": false}",attributes={"<updated_key1>": "<updated_value1>","<updated_key2>": "<updated_value2>",})print(f"Successfully updated {dispatchRule}")except api.ServerError as e:print(f"{e.code} error: {e.message}")await livekit_api.aclose()return dispatchRuleasyncio.run(main())
require 'livekit'lkapi = LiveKit::LiveKitAPI.newrule_id = "<dispatch-rule-id>"update = LiveKit::Proto::SIPDispatchRuleUpdate.new(name: "My updated dispatch rule",trunk_ids: LiveKit::Proto::ListUpdate.new(set: ["<trunk-id1>", "<trunk-id2>"]),metadata: "{\"is_internal\": false}")resp = lkapi.sip.update_sip_dispatch_rule_fields(rule_id, update)puts resp
package mainimport ("context""fmt""github.com/livekit/protocol/livekit"lksdk "github.com/livekit/server-sdk-go/v2")func main() {ruleId := "<dispatch-rule-id>"// Update dispatch rulename2 := "My updated dispatch rule"request := &livekit.UpdateSIPDispatchRuleRequest{SipDispatchRuleId: ruleId,Action: &livekit.UpdateSIPDispatchRuleRequest_Update{Update: &livekit.SIPDispatchRuleUpdate{Name: &name2,TrunkIds: &livekit.ListUpdate{Set: []string{"<trunk-id1>", "<trunk-id2>"},},},},}api, err := lksdk.NewLiveKitAPI()if err != nil {fmt.Println(err)return}updated, err := api.SIP().UpdateSIPDispatchRule(context.Background(), request)if err != nil {fmt.Println(err)} else {fmt.Println(updated)}}
The following updates the dispatch rule created in the Direct dispatch rule example. To update an individual dispatch rule, pass in a SipDispatchRuleIndividual object instead of a SipDispatchRuleDirect object.
import io.livekit.server.LiveKitAPIimport io.livekit.server.SipDispatchRuleDirectimport io.livekit.server.UpdateSipDispatchRuleOptionsval api = LiveKitAPI.createClient(host = System.getenv("LIVEKIT_URL"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"))val response = api.sip.updateSipDispatchRule(sipDispatchRuleId = "<rule-id>",options = UpdateSipDispatchRuleOptions(name = "My updated dispatch rule",metadata = "{'key1': 'value1', 'key2': 'value2'}",rule = SipDispatchRuleDirect(roomName = "new-room"))).execute()if (response.isSuccessful) {val dispatchRule = response.body()println("Dispatch rule updated: ${dispatchRule}")}
use livekit_api::services::LiveKitApi;use livekit_protocol as proto;#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {// host is required; API key and secret are read from// LIVEKIT_API_KEY and LIVEKIT_API_SECRET.let api = LiveKitApi::new("https://<your-subdomain>.livekit.cloud")?;let update = proto::SipDispatchRuleUpdate {name: Some("My updated dispatch rule".to_owned()),metadata: Some("{\"key1\": \"value1\", \"key2\": \"value2\"}".to_owned()),rule: Some(proto::SipDispatchRule {rule: Some(proto::sip_dispatch_rule::Rule::DispatchRuleDirect(proto::SipDispatchRuleDirect { room_name: "new-room".to_owned(), ..Default::default() },)),}),..Default::default()};let dispatch_rule =api.sip().update_sip_dispatch_rule("<rule-id>".to_owned(), update).await?;println!("Dispatch rule updated: {:?}", dispatch_rule);Ok(())}
Update and replace functions are the same in the LiveKit Cloud dashboard. For an example, see the replace dispatch rule section.
Replace dispatch rule
The UpdateSIPDispatchRule API allows you to replace an existing dispatch rule with a new one using the same dispatch rule ID.
The instructions for replacing a dispatch rule are the same as for updating a dispatch rule.
import { LiveKitAPI } from 'livekit-server-sdk';import {SIPDispatchRule,SIPDispatchRuleDirect,SIPDispatchRuleInfo,} from '@livekit/protocol';const api = new LiveKitAPI();async function replaceDispatchRule(ruleId: string) {const ruleInfo = new SIPDispatchRuleInfo({name: 'My replaced dispatch rule',trunkIds: ['<trunk-id1>', '<trunk-id2>'],hidePhoneNumber: false,metadata: '{"is_internal": true}',rule: new SIPDispatchRule({rule: {case: 'dispatchRuleDirect',value: new SIPDispatchRuleDirect({ roomName: 'caller-room', pin: '1212' }),},}),});const updatedRule = await api.sip.updateSipDispatchRule(ruleId, ruleInfo);return updatedRule;}await replaceDispatchRule('<dispatch-rule-id>');
import asynciofrom livekit import apiasync def main():"""Use the update_sip_dispatch_rule function to replace a dispatch rule."""livekit_api = api.LiveKitAPI()# Dispatch rule ID of rule to replace.rule_id = '<dispatch-rule-id>'# Dispatch rule type.rule = api.SIPDispatchRule(dispatch_rule_direct = api.SIPDispatchRuleDirect(room_name = "caller-room",pin = '1212'))ruleInfo = api.SIPDispatchRuleInfo(rule = rule,name = 'My replaced dispatch rule',trunk_ids = ["<trunk-id1>", "<trunk-id2>"],hide_phone_number = True,metadata = "{\"is_internal\": false}",attributes = {"<replaced_key_name1>": "<replaced_value1>","<replaced_key_name2>": "<replaced_value2>",},)dispatchRule = Nonetry:dispatchRule = await livekit_api.sip.update_sip_dispatch_rule(rule_id,ruleInfo)print(f"Successfully replaced {dispatchRule}")except api.ServerError as e:print(f"{e.code} error: {e.message}")await livekit_api.aclose()return dispatchRuleasyncio.run(main())
require 'livekit'lkapi = LiveKit::LiveKitAPI.newrule_id = "<dispatch-rule-id>"rule = LiveKit::Proto::SIPDispatchRuleInfo.new(name: "My replaced dispatch rule",trunk_ids: ["<trunk-id1>", "<trunk-id2>"],hide_phone_number: false,metadata: "{\"is_internal\": true}",rule: LiveKit::Proto::SIPDispatchRule.new(dispatch_rule_direct: LiveKit::Proto::SIPDispatchRuleDirect.new(room_name: "caller-room",pin: "1212")))resp = lkapi.sip.update_sip_dispatch_rule(rule_id, rule)puts resp
package mainimport ("context""fmt""github.com/livekit/protocol/livekit"lksdk "github.com/livekit/server-sdk-go/v2")func main() {ruleId := "<dispatch-rule-id>"// Replace dispatch rulerule := &livekit.SIPDispatchRuleInfo{Name: "My replaced dispatch rule",TrunkIds: []string{"<trunk-id1>", "<trunk-id2>"},Rule: &livekit.SIPDispatchRule{Rule: &livekit.SIPDispatchRule_DispatchRuleDirect{DispatchRuleDirect: &livekit.SIPDispatchRuleDirect{RoomName: "my-room",},},},}request := &livekit.UpdateSIPDispatchRuleRequest{SipDispatchRuleId: ruleId,Action: &livekit.UpdateSIPDispatchRuleRequest_Replace{Replace: rule,},}api, err := lksdk.NewLiveKitAPI()if err != nil {fmt.Println(err)return}updated, err := api.SIP().UpdateSIPDispatchRule(context.Background(), request)if err != nil {fmt.Println(err)} else {fmt.Println(updated)}}
Use updateSipDispatchRule with a new rule to replace an existing dispatch rule:
import io.livekit.server.LiveKitAPIimport io.livekit.server.SipDispatchRuleDirectimport io.livekit.server.UpdateSipDispatchRuleOptionsval api = LiveKitAPI.createClient(host = System.getenv("LIVEKIT_URL"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"))val response = api.sip.updateSipDispatchRule(sipDispatchRuleId = "<dispatch-rule-id>",options = UpdateSipDispatchRuleOptions(name = "My replaced dispatch rule",trunkIds = listOf("<trunk-id1>", "<trunk-id2>"),metadata = "{\"is_internal\": true}",rule = SipDispatchRuleDirect(roomName = "caller-room"))).execute()if (response.isSuccessful) {val dispatchRule = response.body()println("Dispatch rule replaced: ${dispatchRule}")}
use livekit_api::services::LiveKitApi;use livekit_protocol as proto;#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {// host is required; API key and secret are read from// LIVEKIT_API_KEY and LIVEKIT_API_SECRET.let api = LiveKitApi::new("https://<your-subdomain>.livekit.cloud")?;// Replace a dispatch rule entirely.let rule = proto::SipDispatchRuleInfo {name: "My replaced dispatch rule".to_owned(),trunk_ids: vec!["<trunk-id1>".to_owned(), "<trunk-id2>".to_owned()],hide_phone_number: false,metadata: "{\"is_internal\": true}".to_owned(),rule: Some(proto::SipDispatchRule {rule: Some(proto::sip_dispatch_rule::Rule::DispatchRuleDirect(proto::SipDispatchRuleDirect { room_name: "caller-room".to_owned(), ..Default::default() },)),}),..Default::default()};let dispatch_rule = api.sip().update_sip_dispatch_rule_replace("<dispatch-rule-id>".to_owned(), rule).await?;println!("Dispatch rule replaced: {:?}", dispatch_rule);Ok(())}
Sign in to the LiveKit Cloud dashboard .
Select Telephony → Dispatch rules .
Navigate to the Dispatch rules section and find the dispatch rule you want to update.
Select the more (⋮) menu → select Edit.
Select the JSON editor tab and copy and paste the following text into the editor:
{"name": "My replaced dispatch rule","rule": {"dispatchRuleIndividual": {"roomPrefix": "caller-room"}},"trunkIds": ["<trunk-id1>", "<trunk-id2>"],"hidePhoneNumber": false,"metadata": "{\"is_internal\": true}","attributes": {"<replaced_key_name1>": "<replaced_value1>","<replaced_key_name2>": "<replaced_value2>",}}Select Update.
List dispatch rules
Use the ListSIPDispatchRule API to list all dispatch rules.
lk sip dispatch list
import { LiveKitAPI } from 'livekit-server-sdk';const api = new LiveKitAPI();const rules = await api.sip.listSipDispatchRule();console.log(rules);
import asynciofrom livekit import apiasync def main():livekit_api = api.LiveKitAPI()rules = await livekit_api.sip.list_sip_dispatch_rule(api.ListSIPDispatchRuleRequest())print(f"{rules}")await livekit_api.aclose()asyncio.run(main())
require 'livekit'lkapi = LiveKit::LiveKitAPI.newresp = lkapi.sip.list_sip_dispatch_rule()puts resp.items
package mainimport ("context""fmt""github.com/livekit/protocol/livekit"lksdk "github.com/livekit/server-sdk-go/v2")func main() {api, err := lksdk.NewLiveKitAPI()if err != nil {fmt.Println(err)return}// List dispatch rulesdispatchRules, err := api.SIP().ListSIPDispatchRule(context.Background(), &livekit.ListSIPDispatchRuleRequest{})if err != nil {fmt.Println(err)} else {fmt.Println(dispatchRules)}}
import io.livekit.server.LiveKitAPIval api = LiveKitAPI.createClient(host = System.getenv("LIVEKIT_URL"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"))val response = api.sip.listSipDispatchRule().execute()if (response.isSuccessful) {val dispatchRules = response.body()println("Number of dispatch rules: ${dispatchRules?.size}")}
use livekit_api::services::sip::ListSIPDispatchRuleFilter;use livekit_api::services::LiveKitApi;#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {// host is required; API key and secret are read from// LIVEKIT_API_KEY and LIVEKIT_API_SECRET.let api = LiveKitApi::new("https://<your-subdomain>.livekit.cloud")?;let rules = api.sip().list_sip_dispatch_rule(ListSIPDispatchRuleFilter::All).await?;println!("{:?}", rules);Ok(())}
- Sign in to the LiveKit Cloud dashboard .
- Select Telephony → Dispatch rules .
- The Dispatch rules section lists all dispatch rules.
Additional resources
The following resources provide additional details about the topics covered in this guide.