Writing local policy scripts

Local policy scripts are configured as part of a policy profile and allow you to manipulate service configuration, some participant properties, and media location data. This topic explains how to write a jinja2 script to control Pexip Infinity's call behavior.

Using local policy requires proficient scripting skills. For large production environments we recommend that you contact your Pexip authorized representative.

We recommend that you test your policy scripts carefully with a variety of different inputs. We will attempt to maintain backwards compatibility in future releases of the Pexip Infinity platform but the introduction of new features may affect the behavior of existing scripts. We strongly recommend that you test your scripts in a lab environment before using them in a production system, particularly after an upgrade to the Pexip Infinity software.

This topic covers:

You can also use the Administrator interface's built-in facility for Testing local policy scripts, and refer to our Example local policy scripts and our guide to Using filters in local policy scripts.

Types of configuration data

The following table shows the types of configuration data that can be modified via local policy, and when that data is requested by Pexip Infinity:

Type of data Purpose
Service configuration

The configuration details of a service. Pexip Infinity typically requires this data when it:

  • receives an incoming call request
  • needs to place a call to a given alias
Participant properties

This allows some of the participant's call properties, such as their display name or role, to be changed before they join the conference. This allows you, for example, to anonymize a participant's name or modify their role based on other properties of the call or their associated Identity Provider.

  • For WebRTC participants it is applied after any PIN entry or SSO steps (and hence has access to Identity Provider attributes).
  • For SIP/H.323 endpoints, it is applied before any PIN entry steps.

Participant policy is applied after any service configuration policy, and before media location policy.

Media location

The system location to use for media allocation. A Conferencing Node assigned to that location will handle the media for the participant. A media location request is often made after a service configuration data request (and after any participant policy).

You may see multiple service configuration, participant and media location requests when handling Connect app participants.

Writing a jinja2 script to control call behavior

Your scripts are configured as part of a policy profile (Call control > Policy profiles), and that profile is then assigned to one or more system locations.

Pexip Infinity's local policy scripts use a subset of the jinja2 templating language (see Template Designer Documentation).

These scripts/templates consist of the following elements:

  • literal text that you want to add to the output or result
  • variables that are substituted with values from the source request (call_info and participant), or that contain the existing configuration data supplied by external policy or the Pexip Infinity database (service_config and suggested_media_overflow_locations)
  • filters that can manipulate text or modify the content of variables or text strings, such as pex_update or pex_to_json
  • delimiters such as {{...}} and pipes | which are used to define filter expressions
  • jinja statements and control structures (see Jinja Control Structures)

All scripts are subject to a maximum length of 49152 characters. If your scripts are getting close to this limit, we recommend that you consider using external policy instead.

For more reference information and to see where else jinja2 templates are used within Pexip Infinity, see Jinja2 templates and filters.

Getting started in constructing a script

Local policy allows you to manipulate the service configuration, participant and media location data that has already been fetched from Pexip Infinity's own database, provided by the caller, or has been supplied via the external policy API. In the case of service configuration data, there may be no existing data available — for example if a call attempt was made to an alias that does not exist.

This existing data that can be manipulated is held in three variables:

  • service_config for service configuration policy,
  • participant for participant policy, and
  • suggested_media_overflow_locations for media location policy.

Your local policy script will typically use filters to modify some elements of these variables, or replace the contents of those variables with completely different data, based on certain conditions, or it can choose to pass through the existing data unchanged. Those conditions will typically involve references to that existing data or to the original call information that led to the request to provide service configuration, participant and media location data. That existing call information is held in the call_info variable (which cannot be modified) and is explained in Supported variables below.

The objective of the script is to return the service configuration, participant or media location data to Pexip Infinity. That response — the output/result of the script — must be a JSON object that fully defines the service or media location i.e. it must include all of the mandatory response fields as a minimum.

An example basic response containing service configuration data is shown below. It simply returns the basic minimum set of configuration fields for a VMR (which has a service_type of "conference"). All other properties of the service will use Pexip Infinity's default values:

"action": "continue",
"result": {
  "service_type": "conference",
  "name": "Alice Jones",
  "service_tag": "abcd1234"

A more typical script is likely to modify one or more elements of the existing service configuration data, for example:

  {% if service_config %}
    "action": "continue",
    "result": {{service_config|pex_update({"enable_chat": "no", "enable_overlay_text": True})|pex_to_json}}
  {% else %}
    "action": "reject",
    "result": {}
  {% endif %}

This script first checks if there is some existing service configuration data (which is held in the service_config variable) and then updates that data by disabling chat messages and turning on the display of participant names; otherwise (if there is no existing data) it rejects the request and returns null data. Note how the script uses the pex_update and the pex_to_json filters to update and then format the elements of the service_config data variable — you should use this as the model for your own scripts.

For full details of what may be contained in the policy response, see Service configuration data responses and Media location data responses.

To help you construct and test your scripts, Pexip Infinity has a built-in script testing facility, and there are some example scripts that illustrate how to structure your scripts.

Supported variables

There is a limited set of system variables (Configuration variables, Call information variables and Participant properties variables) that you can use within your script. Capitalization of variable names is important. The variables must be spelled exactly as shown.

Note that these variables are represented in a Python dictionary format (which is very similar, but not identical, to JSON). This is why the pex_to_json filter is required if you want to return the content of the configuration variables as the response to a service configuration or media location request.

Configuration variables

The service configuration and media location data that has already been fetched from Pexip Infinity's own database or has been supplied via the external policy API is held in the following variables:

Variable name Description and example usage

The service_config variable holds the existing service configuration data. This variable can be used in all local policy scripts (service configuration, participant and media policy).

  • When referring to specific service configuration data elements, you must use the service_config prefix. For example, use service_config.pin to refer to the service PIN, and service_config.service_type to refer to the type of service (either "conference" or "lecture" for a Virtual Meeting Room or Virtual Auditorium, "gateway" for an Infinity Gateway call, "two_stage_dialing" for a Virtual Reception, "media_playback" for a Media Playback Service, or "test_call" for a Test Call Service).
  • If no service configuration data has been retrieved — for example if a call attempt was made to an alias that does not exist, this variable will be null, but it can still be updated to contain the required configuration data.
  • See Service configuration data responses for the full set of service configuration elements within the service_config variable. (Note that if you use the pex_debug_log filter to log the content of the service_config variable, you may see additional fields reported to those listed here. Those additional fields are for information only and may change in future releases.)

Example service_config data (displayed here in JSON format):

"service_config": {
  "allow_guests": true, 
  "automatic_participants": [
    "description": "Dial out to VMR owner", 
    "local_alias": "meet.alice@example.com", 
    "local_display_name": "Alice's VMR", 
    "protocol": "sip", 
    "remote_alias": "sip:alice@example.com", 
    "role": "chair", 
    "system_location_name": "London"
  "description": "Alice Jones personal VMR", 
  "enable_overlay_text": true, 
  "guest_pin": "5678", 
  "name": "Alice Jones", 
  "pin": "1234", 
  "service_tag": "abcd1234", 
  "service_type": "conference"


The suggested_media_overflow_locations variable holds the existing media location data. This variable only applies to scripts run as media location policy. When referring to specific media location data elements, you must use the suggested_media_overflow_locations prefix followed by the element name — either location, primary_overflow_location or secondary_overflow_location which respectively refer to the principal location and the primary and secondary overflow locations that will handle the call media, for example suggested_media_overflow_locations.location.

Example suggested_media_overflow_locations data (displayed here in JSON format):

"suggested_media_overflow_locations": {
  "location": "New York", 
  "primary_overflow_location": "Paris", 
  "secondary_overflow_location": "Peckham"

Call information variables

The following table shows the call information variables that may be available to your script. These variables contain facts about the call and thus the data in these variables cannot be changed by policy.

For each variable the table indicates if it is available to service configuration data requests and/or media location data requests. When using these variables you must use the "call_info." prefix. For example to refer to the location associated with the Conferencing Node making the request, use call_info.location and to refer to the call protocol use call_info.protocol. (Note that the call_info variables are the same as those used in external policy API requests.)

Available call_info variables Description Service config Participant config Media location
bandwidth The maximum requested bandwidth for the call. It is present on both inbound and outbound call requests but is meaningful only for inbound calls.

breakout_uuid The uuid of a breakout room (if applicable).


The direction of the call that triggered the request. Values can be:

  • "dial_in": calls in to Pexip Infinity
  • "dial_out": calls dialed out from Pexip Infinity
  • "non_dial": when policy is triggered by other requests that are not related to incoming or outgoing call setup, such as when an H.323 LRQ or a SIP SUBSCRIBE or OPTIONS request is received.

call_tag An optional call tag that is assigned to a participant.


Indicates the result of a prior external policy request for that request type.

  • For service configuration requests it can be either "CONTINUE", "REJECT" or "REDIRECT".
  • For participant requests it can be "CONTINUE" or "REJECT".

Note that it is only provided if external policy is enabled, the request was successful, and returned a valid action.



Boolean indicating if the participant's display name was provided and authenticated by an Identity Provider.

idp_uuid The UUID of the Identity Provider who provided and authenticated the participant's display name, and provided any idp_attributes in participant policy.


In the context of service and participant configuration requests, this is the incoming alias (typically the alias that the endpoint has dialed). This is the primary item of information that the policy script will use to return appropriate service configuration data.

For media location and participant avatar requests this contains the originally-dialed incoming alias for the associated service.

location The name of the Pexip Infinity system location associated with the Conferencing Node making the request/notification.


The sender's subnet address.

Note that the value of "ms_subnet" is formatted as a JSON list, for example: [""]

node_ip The IP address of the Conferencing Node making the request.


The authenticated identity of the user sending the SIP message.

Note that the value of "p_asserted_identity" is formatted as a JSON list, for example: ['"Alice"<sip:alice@example.com>']


The call protocol.

Values: "api", "webrtc", "sip", "rtmp", "h323" or "mssip".

(Note that the protocol is always reported as "api" when a Connect app dials in to Pexip Infinity.)


The address of the Proxying Edge Node that is handling the call, if applicable.



The system location of the Proxying Edge Node that is handling the call, if applicable.


pseudo_version_id The Pexip Infinity software build number.

registered Boolean indicating whether the remote participant is registered or not.

remote_address The IP address of the remote participant.

remote_alias The name of the user or the registered alias of the endpoint. The remote_alias may include scheme information, for example sip:alice@example.com.

remote_display_name The display name of the remote participant.

remote_port The IP port of the remote participant.

service_name The service name. This will match the name field returned by the policy script from the original service configuration request.

service_tag †† The service tag associated with the service_name parameter.

supports_direct_media Boolean indicating if the service supports direct media or not.

teams_tenant_id Contains the Microsoft Teams tenant ID on an inbound Teams call to Pexip Infinity for Teams Rooms SIP/H.323 calling.

telehealth_request_id The telehealth call id.


The trigger for the policy request.

Values: "web", "web_avatar_fetch", "invite", "options", "subscribe", "setup", "arq", "lrq" or "unspecified".


The unique name used by Pexip Infinity to identify the service:

  • For "gateway" services this is the matching rule name followed by a unique identifier (so as to distinguish between separate calls that match the same rule).
  • For all other services, this is the same as the service_name parameter.

vendor System details about the remote participant, such as manufacturer name and version number for hard endpoints, or browser and operating system details for soft clients.

version_id The Pexip Infinity software version number.

† Only included if the request was triggered by a SIP message, and the parameter is included as a field in the SIP message header. Note that the ms_subnet and p_asserted_identity fields use only underscores and lower case characters in their names when used in local policy (normally they are referenced as ms-subnet and p_Asserted-Identity).

‡ Only included in outbound call requests and for breakout rooms.

†† Only included in outbound call requests.

◊ Only included in Epic telehealth calls.

For example, the call_info variable could contain the following data (displayed here in JSON format):

"call_info": {
  "bandwidth": 0, 
  "call_direction": "dial_in",
  "call_tag": "wxyz789",
  "local_alias": "meet.alice.vmr@example.com", 
  "location": "New York", 
  "node_ip": "", 
  "protocol": "api",
  "pseudo_version_id": "36358.0.0", 
  "remote_address": "", 
  "remote_alias": "bob@example.com", 
  "remote_display_name": "Bob T. User", 
  "remote_port": 64703,
  "trigger": "web",
  "vendor": "Mozilla/5.0 (X11; Linux x86_64) Chrome/54.0.2840.100 Safari/537.36", 
  "version_id": "16"

Participant properties variables

The participant variable holds the details of the participant who is attempting to join a service. This variable only applies to scripts run as participant policy.

Note that it contains the remote_alias and remote_display_name fields, which are also included in the call_info variable. However, the content of these fields in the participant variable could have been modified by external policy. The original values, as supplied by the endpoint, are contained in the call_info variable.

The following table shows the participant configuration variables that are available to your script. These variables contain information about the participant, however the following fields can be changed by your local policy script: preauthenticated_role, remote_alias and remote_display_name. This allows you to change the participant's role or anonymize their identity during the conference.

When using these variables you must use the "participant." prefix. For example to refer to the display name associated with the participant making the request, use participant.remote_display_name. (Note that the participant variables are the same as those used in external policy API requests.)

Available participant variables Description
call_uuid A unique identifier for the participant's call.

This contains any custom Identity Provider attributes for that participant.

All of the attributes are available within an idp_attributes dictionary, for example:

"idp_attributes": {
  "group": "super-admin",
  "locale": "en_GB"

Thus, a custom attribute of "locale" would be referenced by participants.idp_attributes.locale

Note that if an attribute name contains a hyphen or spaces you must reference it via .get(), for example participant.idp_attributes.get("X-wing pilot")

Custom attributes for use in participant policy are assigned to Identity Providers in the Advanced options settings when configuring the Identity Provider (Users & Devices > Identity Providers > Advanced options).


The participant type: It can be:

  • "standard": used for most types of calls.
  • "api": when a WebRTC client joins there are normally two requests to policy. The first is for the API participant which has the "api" type. Normally, immediately after the "api" request, a "standard" participant request is made.
  • "api_host": this is a variation of the normal "api" type which also starts the conference if the participant is a Host.
participant_uuid The uuid associated with the participant.

The participant's role, either "guest", "chair" or null (note that in any jinja statements you need to test for: is None). You should consider the sequence of events that could determine the role's value provided here:

  • For WebRTC participants, participant policy is applied after any PIN entry or SSO steps (which may determine the participant's role).
  • For SIP/H.323 endpoints, participant policy is applied before any PIN entry steps.
  • Local policy is applied after any external policy (which may have modified the role).
remote_alias The name of the user or the registered alias of the endpoint. The remote_alias may include scheme information, for example sip:alice@example.com.
remote_display_name The display name of the remote participant.

Example participant data (displayed here in JSON format):

  "call_uuid": "69434387-e444-411c-afd4-dcc25bf328d3",
  "idp_attributes": {
    "group": "super-admin",
    "locale": "en_GB"
  "participant_type": "standard",
  "participant_uuid": "91664d87-28e4-444b-b6f1-a3816547290",
  "preauthenticated_role": "chair",
  "remote_alias": "alice.jones@example.com",
  "remote_display_name": "Alice Jones"

Response formats

The response to Pexip Infinity i.e. the output/result of the script, must be a JSON object.

The following sections explain how that response must be structured for service configuration data, participant data, and for media location data. Note that the fields in a JSON object can be supplied in any order, and that the returned data takes the same format as the responses to external policy API requests.

Dialing out from conference

Pexip Infinity makes a service configuration request if it dials out from a conference to invite a participant to join (where the call_direction parameter will be dial_out). In these cases, the response to the service configuration request must match the existing service data (i.e. the same name, service_type and so on).

When dialing out, the only configuration you can control via policy is:

  • The prefer_ipv6 setting in the service configuration response.
  • The media location — you can do this in the response to the media location request that follows the service configuration request.