Static Documentation

Voice Provider Configuration

Version latest · Updated 2026-08-17
Interactive docs View on GitHub

Voice Provider Configuration#

Main IncidentRelay configuration#

IncidentRelay reads voice provider settings from the main config file.

Example:

[voice]
provider = stub
providers_dir = /usr/local/lib/incidentrelay/voice_providers
callback_secret =
text_template = IncidentRelay alert {alert_id}. {title}. Severity {severity}. {message}. Press 1 to acknowledge. Press 2 to resolve.
dtmf_actions = {"1": "acknowledge", "2": "resolve"}

[voice_provider]
api_url = https://voice.example.com/api
api_token = ${VOICE_API_TOKEN}
timeout = 10

Settings#

provider#

Default provider name.

A notification channel may override this value in its own config:

{
  "provider": "mango"
}

providers_dir#

Directory where custom provider modules are stored.

Recommended value:

/usr/local/lib/incidentrelay/voice_providers

callback_secret#

Optional dedicated secret for voice callbacks. If empty, IncidentRelay falls back to the application secret. A dedicated random value is recommended.

The secret is passed to providers as request.callback_secret and must be sent back in the Authorization: Bearer ... header (or X-IncidentRelay-Callback-Secret). It must never be embedded in the callback URL. Providers should use request.callback_url exactly as supplied by IncidentRelay.

Provider file names#

Provider file names must contain only letters, numbers and underscore.

Valid examples:

mango.py
zadarma.py
internal_pbx.py
voice_gateway_1.py

Invalid examples:

mango-provider.py
my.provider.py
provider backup.py

The provider name used in channel config is the file name without .py.

Example file:

/usr/local/lib/incidentrelay/voice_providers/mango.py

Provider name:

"provider": "mango"

Channel configuration#

Example voice channel config:

{
  "provider": "example_http",
  "call_on_severities": ["critical", "high"],
  "test_phone": "+77001234567",
  "callback_secret": "change-me-channel-secret",
  "text_template": "IncidentRelay alert {alert_id}. {title}. Severity {severity}. {message}. Press 1 to acknowledge. Press 2 to resolve.",
  "dtmf_actions": {
    "1": "acknowledge",
    "2": "resolve"
  },
  "provider_config": {
    "api_url": "https://voice.example.com/api",
    "api_token": "${VOICE_API_TOKEN}",
    "from": "+77000000000",
    "timeout": 10
  }
}

Channel config fields#

provider#

Name of the provider module.

"provider": "mango"

call_on_severities#

List of severities that should trigger a phone call.

"call_on_severities": ["critical", "high"]

If this list is empty, IncidentRelay will not call anyone for real alerts.

phone#

Optional fallback phone number.

For real alerts, IncidentRelay usually uses the assigned user's phone number.

"phone": "+77001234567"

test_phone#

Phone number used for test calls.

"test_phone": "+77001234567"

callback_secret#

Optional per-channel callback secret.

If omitted, IncidentRelay uses global config:

[voice]
callback_secret =

text_template#

Template for the spoken message.

Supported placeholders:

{alert_id}
{event_type}
{title}
{message}
{severity}
{status}
{team}
{assignee}
{source}

Example:

"text_template": "Alert {alert_id}. {title}. Severity {severity}. Press 1 to acknowledge. Press 2 to resolve."

dtmf_actions#

Maps phone keypad digits to IncidentRelay actions.

"dtmf_actions": {
  "1": "acknowledge",
  "2": "resolve"
}

Supported actions:

acknowledge
resolve

provider_config#

Provider-specific settings.

IncidentRelay passes this object to the provider constructor.

"provider_config": {
  "api_url": "https://voice.example.com/api",
  "api_token": "${VOICE_API_TOKEN}",
  "from": "+77000000000",
  "timeout": 10
}

Secrets should be stored in environment variables and referenced as ${ENV_NAME}.

"api_token": "${VOICE_API_TOKEN}"

Config validation#

A provider may define validate_config().

This method is called before the provider is used.

class Provider(BaseVoiceProvider):
    name = "mango"

    @classmethod
    def validate_config(cls, config):
        """Validate required provider settings."""

        required_fields = ["api_url", "api_token"]

        missing = [
            field
            for field in required_fields
            if not config.get(field)
        ]

        if missing:
            raise RuntimeError(
                f"mango provider config requires: {', '.join(missing)}"
            )

Use this method to check required fields early.

Good validation errors are important because they are shown in logs and help users fix channel configuration faster.