Telnyx Voice and Webhooks
Use the Elsa Telnyx extension for voice workflows and webhook triggers in Elsa 3.8.0.
The Elsa.Telnyx extension adds server-side activities for Telnyx Call Control and triggers for Telnyx webhook events. Use it when a workflow needs to receive an inbound call, place or control a call, play audio, collect DTMF input, speak text, record a call, look up a number, or react to a call event.
The extension runs in the Elsa Server process. Elsa Studio can design a workflow with the descriptors supplied by that server, but Studio does not store Telnyx credentials, receive webhooks, or call the Telnyx API itself.
Install and configure the server
Install the package in the application that executes workflows:
dotnet add package Elsa.Telnyx --version 3.8.0Enable the module and configure the API key. ApiUrl defaults to https://api.telnyx.com; CallControlAppId is required by activities that create an outbound call, such as Dial and Dial and Wait.
using Elsa.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddElsa(elsa =>
{
elsa.UseTelnyx(telnyx =>
{
telnyx.ConfigureTelnyxOptions = options =>
{
options.ApiKey = builder.Configuration["Telnyx:ApiKey"]!;
options.CallControlAppId = builder.Configuration["Telnyx:CallControlAppId"];
};
});
});Keep ApiKey and the Call Control App ID in deployment configuration or a secret store. The module sends the API key as a bearer token on its Refit HTTP clients. ConfigureHttpClientBuilder and HttpClientFactory are available on the feature when the host needs custom HTTP handlers, proxies, or transport behavior.
Map the Telnyx webhook endpoint
The extension does not map an endpoint automatically. Map a POST endpoint in the Elsa Server application after building the app:
UseWorkflows() is not required for this endpoint; add it separately only when the same host also uses Elsa's HTTP workflow activities.
The default route is telnyx-hook; pass a route pattern to choose a clearer public URL. The endpoint reads the JSON body as a TelnyxWebhook, deserializes the event payload into the release's known payload type, and publishes a TelnyxWebhookReceived notification using Elsa's background notification strategy. Matching handlers then start or resume workflows through stimuli.
The released endpoint has no built-in authentication, authorization, replay protection, or Telnyx signature verification. Put the route behind the authentication and network controls required by your deployment, or add a front-door component that verifies the provider's webhook authenticity before the request reaches UseTelnyxWebhooks. Do not expose the sample route publicly without that additional boundary.
Choose an activity
The activity picker receives the descriptors from the server after UseTelnyx runs. Choose the activity based on the call lifecycle you need.
Start and control calls
Incoming Call is a trigger. Match one or more
FromorTophone numbers, or setCatch Allto match any inbound call. Its result is aCallInitiatedPayload.Dial places an outbound call and returns a
DialResponse. Its requiredToinput accepts a phone number or SIP URI.From, caller display name, answering-machine detection, and recording are optional inputs.Dial and Wait places an outbound call and waits for either
AnsweredorHangup. Use its result when the next workflow step depends on that event.Answer Call answers an incoming call and waits for the
call.answeredevent. LeaveCall Control IDempty only when the ambient inbound call is the call you intend to answer.Hangup Call ends a call. The flow variant exposes
DoneandDisconnectedoutcomes.Transfer Call transfers a call to another destination and waits through the initiated, answered, or hangup events. It accepts destination, caller identity, optional audio, answering-machine, timeout, and time-limit inputs.
Bridge Calls joins two call legs. Both call control IDs are required; the activity waits for bridged events for both legs before completing.
Get Call Status returns a Boolean and exposes
Alive,Dead, andDoneoutcomes.Lookup Number returns Telnyx number, carrier, caller-name, and portability information for a phone number.
The Flow... variants of Answer, Bridge, Hangup, Play Audio, Speak Text, Start Recording, and Stop Audio Playback are the flowchart-oriented forms. They expose explicit outcomes such as Connected, Bridged, Done, or Disconnected so a Flowchart can branch on the call result.
Play audio, speak, and gather DTMF
Play Audio takes a call control ID and an audio URL.
Loopaccepts a number orinfinity;Overlaymixes audio with existing playback; andTarget Legscan beself,opposite, orboth. The activity waits forcall.playback.started.Speak Text converts a text or SSML payload to speech. Configure
Language,Voice,Payload, optionalPayload Type(textorssml), and optionalService Level. It waits forcall.speak.ended.Gather Using Audio plays an audio prompt and collects DTMF digits. Use its audio URL, valid digits, minimum and maximum digits, terminating digit, retry count, and timeout inputs. It branches to
Valid input,Invalid input, orDisconnected.Gather Using Speak speaks a prompt and collects DTMF digits. It has the same gathering controls as the audio form plus language, voice, payload, payload type, and service level.
Start Recording starts a call recording and waits for
call.recording.saved; the flow form exposesRecording finishedandDisconnected.Stop Recording stops recording for a call and exposes
Recording stoppedorDisconnected.Stop Audio Playback stops playback for a call. Its
Stopinput defaults toall; the flow form exposesDoneandDisconnected.
Audio URLs are resolved by Telnyx, not downloaded by the Elsa activity. Make the URL reachable by Telnyx and use HTTPS where appropriate. The server still needs network access to the Telnyx API for every call-control operation.
Design an inbound call workflow
A common designer sequence is:
Add Incoming Call and match the Telnyx number in
To, the caller inFrom, or all calls withCatch All.Add Answer Call and bind its
Call Control IDto the incoming trigger result when it is not using the ambient call.Add Speak Text, Play Audio, or a gather activity and bind the same call control ID.
Use the activity outcomes to branch, then finish with Hangup Call or another call-control action.
Publish the workflow only after the webhook route is reachable from Telnyx and protected by the host's webhook security boundary.
The extension creates a base64-encoded Telnyx client_state containing the workflow execution ID; operations that pass an activity ID include that as well. Later webhook handlers use the available client state and call control ID to target the corresponding workflow or bookmark. This is why a call-control activity should normally be allowed to create and wait for its own callback before a later step tries to use the resulting call state.
Use webhook event triggers
The module supplies three direct call triggers:
Incoming Call, which filters
call.initiatedevents by phone number;Call Answered, which waits for
call.answeredfor one or more call control IDs; andCall Hangup, which waits for
call.hangupfor one or more call control IDs.
It also creates browsable, typed trigger descriptors from the payload types annotated by the release. These event triggers are:
Call Bridged —
call.bridgedCall DTMF Received —
call.dtmf.receivedCall Gather Ended —
call.gather.endedCall Machine Greeting Ended —
call.machine.greeting.endedCall Machine Premium Detection Ended —
call.machine.premium.detection.endedCall Machine Premium Greeting Ended —
call.machine.premium.greeting.endedCall Playback Ended —
call.playback.endedCall Playback Started —
call.playback.startedCall Recording Saved —
call.recording.saved
The typed event triggers expose the corresponding payload as their result. Activities such as Dial and Wait, Play Audio, Speak Text, and the gathering activities use the same webhook pipeline internally: they create a bookmark and resume it when a matching event arrives. An event without a known payload type is deserialized as the release's unsupported payload and does not create one of the typed event descriptors.
Do not confuse a webhook trigger with a webhook endpoint. The trigger is a workflow activity; UseTelnyxWebhooks is the server route that receives the provider request and feeds the trigger pipeline.
Operational boundaries
Server ownership: install and configure
Elsa.Telnyxon every process that executes these activities or receives the webhook route. Installing it only in Studio does not make the activities executable.Studio: the release Studio repositories contain no Telnyx-specific client, settings page, credential store, webhook administration, or provider integration. Studio displays descriptors returned by the connected server.
Persistence and scaling: call bookmarks and workflow instances use the persistence and runtime coordination configured for the Elsa host. Use the same durable stores and coordination model required by the rest of a multi-node deployment; the Telnyx module does not provide a separate call state store.
Retries: Telnyx requests and call-control mutations are external side effects. A retry after an ambiguous timeout can repeat a dial, transfer, or media command. Design idempotency and reconciliation around the provider's call identifiers.
Sensitive data: call payloads can contain phone numbers, caller data, client state, and recording URLs. Avoid writing raw webhook bodies or API keys to logs and limit who can inspect workflow inputs and outputs.
Release scope: the module contains the call-control and webhook activities described here; it does not provide a Studio phone-number provisioning UI or a general Telnyx resource-management API.
Troubleshooting checklist
Confirm
Elsa.Telnyxis installed in the workflow execution host and.UseTelnyx(...)runs during startup.Check that
ApiKeyis present and thatApiUrlpoints to the intended Telnyx API endpoint.For Dial and Dial and Wait, confirm
CallControlAppIdis set and the Telnyx application is configured for the webhook URL you mapped.Confirm Telnyx can reach the exact route passed to
UseTelnyxWebhooks(...), including any reverse-proxy path prefix.If Studio cannot find an activity, verify that it is connected to the server where
UseTelnyxis enabled and that the server exposes activity descriptors.If a workflow remains waiting, inspect the received event type, call control ID, and the bookmark's correlation/client-state values. A
call.answeredorcall.hangupevent must match the call ID stored by the waiting activity.If an audio or speech operation fails, verify the call is still active, the audio URL is reachable by Telnyx, and the input values satisfy Telnyx's constraints.
Add provider-aware webhook authentication and replay protection before diagnosing application behavior with a publicly exposed endpoint.
Release source
This page is validated against the release/3.8.0 source: Extensions a44e2b09af1202ff4936f493756e114c357eff81, Core dff7d9f987394c3c2ba8003e6f9c803e97194fbc, and Studio b008a52cc02840928824018056ca8299518f04b9.
Last updated