Skip to main content

Telnyx Other APIs — Full Documentation

Account and billing, video, fax, SETI, OAuth, and platform APIs. Complete page content for the Other APIs section of the Telnyx developer docs (https://developers.telnyx.com). Root index: https://developers.telnyx.com/llms.txt · Lightweight index for this section: https://developers.telnyx.com/development/llms/other-apis-llms-txt.md

Account & Billing

Usage Reports

Source: https://developers.telnyx.com/docs/reporting/usage-reports.md

Overview

The (v2) Usage Reports API is a single endpoint that enables viewing aggregated usage data across all of a customer’s Telnyx products. It is built to be flexible and customizable, so that you have programmatic access to view data in a way that makes sense to your business and use cases. It can be used to efficiently monitor usage trends and costs, as well as to directly integrate with your internal systems.

Query Requirements

Products

A product from the Options response (see next section) must be included. At this time, there is not a way to view usage for all or multiple products at once. Products Supported:
  • Sip-Trunking (sip-trunking)
  • Messaging (messaging)
  • Voice API (call-control)
  • Wireless (wireless)
  • Cloud Storage (cloud-storage)
  • Inference (inference)
  • Verify 2fa (verify-2fa)
  • Fax API (fax-api)
  • WebRTC (webrtc)
  • Calls per Second (cps)
  • Conference (conference)
  • Video API (programmable-video)
  • Call Control Features (call-control-features)
  • Customer Service Record (customer-service-record)
  • Media Streaming (media-streaming)
  • Noise Suppression (noise-suppression)
  • Text to Speech (text-to-speech)
  • Speech to Text (speech-to-text)
  • Recording (recording)
  • Forking (forking)
  • Media Storage (media-storage)
  • Answering Machine Detection (amd)

Dates

The start and end date parameters should be in the format YYYY-MM-DDThh:mm:ssTZD (eg 2022-12-24T19:20:30-05:00). This allows you to specify the timespan in your local time by including the timezone offset. The start_date parameter is inclusive, while the end_date parameter is exclusive - e.g. if you wanted data for all of February, the start_date would be 2023-02-01T00:00:00-00:00 and the end_date would be 2023-03-01T00:00:00-00:00. Billing usage is calculated using UTC. The maximum range supported is 31 days. Another way to specify the timespan you want is to utilize the date literals spelled out in our developer docs - https://developers.telnyx.com/api#date-literals. This can be achieved by replacing start_date & end_date with date_range like this: date_range=last_1_weeks. To see the requested data broken out by day for the timespan selected, there is a date dimension available on all products. Additionally, there’s a breakout by hour available using the date_time dimension.

Format

Specifying a format is optional. The endpoint returns JSON by default. At this time, the API also supports generating a CSV file from the response by specifying format=csv in your query.

Dimensions & Metrics Options Per Product

To view the products with their dimensions and metrics available for reporting, you can make a request to the endpoint below. Metrics are the values you’re interested in, for example, the number of calls attempted or the total cost of your usage. Dimensions are how you want your data broken out, for example, by connection, messaging profile, or the traffic’s direction. Below, you’ll see a sample of the “Options” response for Sip-Trunking. If you already know the product you want and are looking for only its supported dimensions/metrics, you can pass the product parameter as shown in the example. If you want to see all products, simply leave off the product parameter.
Request:
Don’t forget to update YOUR_API_KEY here.
Response:

Product Examples

SIP Trunking

Example 1: Simple SIP Report

Let’s say we’re interested in our sip-trunking usage for the week of January 23rd. And let’s say we want to see the total calls connected versus calls attempted and the total cost. And we need these numbers broken out by direction and country. We first make a query to the Options endpoint listed above to make sure those requirements are all supported and to see how to query for them. These are our requirements shown next to how we’d construct our query for them: Product: sip-trunking product=sip-trunking Date(s): January 23rd - 28th 2024 start_date=2024-01-23T00:00:00-00:00end_date=2024-01-29T00:00:00-00:00 Metrics: calls connected, calls attempted, cotal cost metrics=connected,attempted,cost Broken out by destination countryNote: Since we’re filtering on the direction, we must include it. dimensions=country_code,direction Outbound only filter[direction]=outbound API Response’s Page Size/Number page[number]=1page[size]=20
Request:
Response:
From the response below, we can see that during the week in question, our account only had traffic to the US (country code = 1). Our connected versus attempted is 883,930 vs 1,245,811 calls respectively. And the total cost for those outbound calls was 1911.624 (Note: If you had wanted the currency, that is another dimension that can be added in the query with dimensions=currency).

Example 2: Short Duration Calls

Telnyx enforces automatic surcharges for customer accounts whose short duration calls (greater than 0 and less than or equal to 6 seconds) total 15% or more of their outbound traffic. As someone running SIP traffic, I may want to know if I’m in danger of receiving the surcharge at the end of the month. We have exposed a metric solely for the purpose of this calculation. Product: sip-trunking product=sip-trunking Date(s): January 2024 start_date=2024-01-01T00:00:00-00:00end_date=2024-02-01T00:00:00-00:00 Metrics: calls completed metrics=completed Broken out by SDC (short duration call: true or false)Note: Since we’re filtering on the direction, we must include it. dimensions=short_duration_call,direction Outbound only filter[direction]=outbound API Response’s Page Size/Number page[number]=1page[size]=20
Request:
Response:
From the response below, we can determine the percentage of our traffic that is currently considered short duration: 414515 / (414515 + 522094) = 44%. If we wanted to take this a step further, we could see which connections are the biggest offenders by adding “connection_id” to the dimensions list.

Messaging

Example 1: Simple Messaging Report

In this example, we’ll put together a simple request to view our Messaging usage for a single day. Product: messaging product=messaging Date(s): Today date_range=today Metrics: total cost, total messages sent, total message parts metrics=cost,count,parts Broken out by CarrierNote: Since we’re filtering on the direction, we must include it. dimensions=short_duration_call,direction Outbound only filter[direction]=outbound API Response’s Page Size/Number page[number]=1page[size]=20
Request:
Response (abbreviated):

Example 2: Alphanumeric by MNC/MCC

This example is a little more complex, and lays out a monthly Messaging report of our Alphanumeric traffic per country, broken out by MCC (Mobile Country Code) and MNC (Mobile Network Code). Product: messaging product=messaging Date(s): January 2024 start_date=2024-01-01T00:00:00-00:00end_date=2024-02-01T00:00:00-00:00 Metrics: total cost, total message parts metrics=cost,parts Dimensions: mcc, mnc, destination country, status_v2 dimensions=direction,mcc,mnc,country_iso,product_name,status_v2 Filters: alphanumeric, outbound, billable statuses only filter[product_name]=alphanumeric_idfilter[direction]=outboundfilter[status_v2]=deliveredfilter[status_v2]=delivery_failedfilter[status_v2]=delivery_unconfirmed
Request:
Response (abbreviated):

Session Analysis

Source: https://developers.telnyx.com/docs/reporting/session-analysis.md

Session Analysis API Usage Guide

Understand the full cost and event tree for any Telnyx AI or voice session — from a single inference call to complex multi-product conversations.

What is Session Analysis?

Session Analysis gives you a complete view of costs and events for any usage session on the Telnyx platform:
  • Full event tree — parent events, child events, and their relationships
  • Rollup costs — per-event costs plus cumulative totals across the session
  • Product linkages — how different Telnyx products interacted in a single session
This is especially valuable for AI-powered sessions, where a single call can involve multiple Telnyx products — AI Voice Assistant, inference, speech-to-text, text-to-speech, call control, SIP trunking, and more — all layered into one conversation.

When to Use It


Core Concepts

Record Types

A record type identifies the category of usage event for a Telnyx product. Each record type maps to a specific product and has defined relationships to other record types. Example: ai-voice-assistant is the record type for AI Voice Assistant sessions, which have inference events as children.

Sessions

A session is a tree of related usage events. The root event is the primary event you’re analyzing. Child events are related usage that occurred as part of that session. Example: An AI Voice Assistant call involves a call-session root with a call-control child, which in turn has an ai-voice-assistant child with inference events underneath — each representing one LLM turn in the conversation.

Relationships

Events are connected via relationships: Relationships are defined via field mappings — the child’s local_field matches the parent’s parent_field. For example, inference events link to their ai-voice-assistant parent via the conversation_id field.

Cost Rollup

Each event node includes:
  • event_cost — Cost of this individual event
  • cumulative_cost — This event’s cost plus all descendant costs
The root event’s cumulative_cost equals the total session cost. For AI sessions, this means the call-session cumulative cost includes everything — the AI assistant, each inference turn, STT, TTS, call control, and SIP trunking — rolled up into one number.

Endpoints

1. List All Record Types

Returns all available record types, their relationships, and query parameter options. Response includes:
  • record_types[] — Array of all record types with their parent/child relationships
  • query_parameters — Valid parameters for session analysis queries
  • meta — Total count and last updated timestamp
Example:

2. Get Record Type Details

Returns metadata for a specific record type with additional details:
  • Valid child and parent relationships
  • Example query URLs
  • Recommended max depth for traversal
Example:

3. Get Session Analysis

Retrieves the full session analysis tree for a specific event. Path Parameters: You can find event IDs in the individual webhooks or detail records for the applicable event. Which record type should I use? If you’re analyzing a call made with your AI assistant, start with call-session. This gives you the full picture — AI assistant sessions, inference events, call control, SIP trunking, and all other products in one tree. Use the metadata endpoint to explore other starting points for different products. Query Parameters: Example:

Response Structure

Top-Level Fields

Event Node Structure

Each event in the tree follows this structure:

Relationship Object

For child events, the relationship field explains the connection:
Note: The via fields vary by relationship. AI-related linkages often use conversation_id, while voice/telephony relationships typically use telnyx_session_id or call_session_id.

Example: AI Voice Assistant Session

A customer makes an inbound call to an AI Voice Assistant using the Telnyx Web Dialer. The assistant handles a multi-turn conversation over ~152 seconds. Query:
Session tree:
Summary: Key observations:
  • The call-session root has $0.00 event cost — it’s a container for the session, not a billable event itself.
  • ai-voice-assistant is the dominant cost at 0.18(billedat0.18 (billed at 0.06/min for 3 billed minutes). Its cumulative cost of $0.1921 includes 5 inference events underneath.
  • Each inference event represents a single LLM call during the conversation — one per assistant turn. The cost per turn varies based on the model and token count.
  • call-control has a 0.0052eventcostbuta0.0052 event cost but a 0.1973 cumulative cost — the difference is the ai-voice-assistant subtree rolling up underneath it.
  • recording, webrtc, and sip-trunking are leaf nodes with no children, so their event cost equals their cumulative cost.

Understanding the AI Cost Structure

In an AI-powered call, costs come from multiple layers: Session Analysis rolls all of these into one tree, so you can see exactly where cost accumulates — whether it’s the AI assistant minute rate, the number of inference turns, or the underlying voice transport.

Common Use Cases

Debugging High-Cost AI Sessions

  1. Query the session with max_depth=5 to get the full tree
  2. Look at meta.products to see which products were involved
  3. Compare event_cost across children — if ai-voice-assistant is the driver, check how many inference turns occurred underneath
  4. Check record fields for rate information (rate, rate_measured_in) and duration
  1. Start from any event in the tree
  2. Use relationship.via to understand the field linkage
  3. Query the parent or children directly using their id

Exporting for Analysis

  1. Use expand=none to get just the tree structure without full records
  2. Flatten the tree programmatically for spreadsheet import
  3. Or keep full records and parse specific fields (e.g., rate, duration_sec)

Best Practices

Performance

  • Provide date_time when you know it — this narrows the index search and improves response time
  • Use appropriate max_depth — start with 2, increase only if needed. AI sessions with inference events typically need max_depth=4 or 5 to reach the leaf level.
  • Use expand=none if you only need cost rollups, not full records

Querying

  • Start from the root event — the most complete picture comes from the top-level event
  • Check metadata first/metadata/{record_type} shows expected children and recommended depth
  • Use links.records to get the underlying detail records for deeper analysis

Error Handling


Record Types Reference

AI & Voice Intelligence

Voice & Telephony

Media & Storage

Conferencing

Messaging

Video

Other Products


On-Demand Reports

Source: https://developers.telnyx.com/docs/reporting/on-demand-reports.md
On-Demand Reports lets you query your Telnyx usage data using natural language. Instead of building filters and exporting CSVs, describe the report you want in plain English and the system generates it.

Overview

On-Demand Reports uses AI to translate natural language into structured queries against your Usage Report data. You can request specific chart types, date ranges, groupings, and breakdowns — all from a single text input.

Getting started

  1. Log in to the Mission Control Portal.
  2. Navigate to Reporting > On-Demand Reports.
  3. Type a query describing the report you need and submit it.
On-Demand Reports query interface

Example queries

  • “Daily wireless spend for the last 10 days”
  • “Number of messages by direction for last week as a pie chart”
  • “Weekly total calls last quarter”
  • “Average SIP cost for last 2 weeks as line graph”
  • “SIP usage for the last month as a table”

What you can do


Current limitations

  • Queries run against v2 Usage Report data only. Products and dimensions available in Usage Reports are available here.
  • Not a general knowledge assistant — the system answers questions about your Telnyx usage data, not general questions.
  • This is the first release. Coverage and capabilities will expand over time.

Video

Getting Started

Source: https://developers.telnyx.com/docs/video/get-started.md
Telnyx Video Rooms are enabled using the Rooms API. You can create as many rooms as needed using this API. To access a Telnyx Video Room, a Client Join Token will first need to be generated in JWT form. You can use our HTTPS API and authenticate using the API Key associated with your Mission Control account under API Keys. Find out more about authenticating with API V2 here. Adding Telnyx Rooms functionality to your app can be done using our JS SDK (mobile SDKs coming soon). To gain access to a live Video Rooms sample app, reach out to our sales team today! Check out the full API reference today!

Glossary

Room Resource representing a virtual place where multiple endpoints using one of Telnyx’s Programmable Video SDKs can connect. Room Session Resource representing a moment where multiple Room Participants were communicating within a given Room. Room Participant Resource representing an endpoint using one of Telnyx’s Programmable Video SDKs to connect to a given Room. JWT JSON Web Token. A standard method for representing claims. Client Join Token (JWT) A JWT token which contains grants allowing in the Room usecase to join a Room. Refresh Token (JWT) A JWT token which permits to obtain a new Client Token with same grants. API Key Secret API Key generated via Portal and used to authenticate Telnyx API calls. Video SDK A library used to provide Video features to your application using Telnyx Video platform. Configuration and usage Telnyx Video is enabled using Video Rooms. A Video Room represents communications session among multiple endpoints using one of Telnyx’s Programmable Video SDKs. Connected users (Participants) can share video and audio Tracks with the Room, and receive video and audio Tracks from other Participants in the Room. You can as many Rooms as you want. For example you could create a long lived Room such as “Daily Standup”, or Rooms that you would delete after it’s been used like “1-1 with X”. To create a Video Room you can use the REST API V2 documented{” ”} here. A Video Room can only be joined if the client owns a Client Join Token, you can create it using the REST API V2 documented{” ”} here. The Client Join Token is short lived and you will be able to refresh it using the{” ”} Refresh Token provided with it when you request for a Client Join Token. Once you have a Video Room and an Client Join Token for it, you can then use our Video SDK on your client side to connect your client to the Room you just created.

Concepts

Architecture

Video Rooms is a platform that enables developers to add audio and video capability to Web, Android, and iOS applications. The platform consists of REST APIs, Client SDKs, and our mission control portal that makes it really easily to capture, stream, record, and render live audio and video. A video application built with Video Rooms has to parts:
  • Client: Our client side Javascript, iOS, and Android SDKs used to interact with a Room instance
  • Server: Our REST APIs and portal to create/manage room and session, configuring recording, or leverage our Participants API to moderator participants in a Room.

Terms

Understanding the basic concepts of the video SDK will help you understand how it works. These concepts apply in general across all of our platforms.
  • A Room represents a real time audio/video/screen share session with other people or participants. It is fundamental to building a video application.
  • Room State tracks the state of the room as it changes making it extremely easy to understand what’s happened to a Room.
    • For example: Room State could change due to a Local Participant has started publishing a stream or because a Remote Participant left. A Stream represents the audio/video media streams that are shared by Participants in a Room
  • A Participant represents a person inside a Room. Each Room has one Local Participant and one or more Remote Participants.
  • A Stream represents the audio/video media streams that are shared by Participants in a Room
    • A Stream is indentified by it’s participantId and streamKey
  • A Subscription is used to subscribe to a Stream belonging to a Remote Participant

Dive a bit deeper

Dive a little bit deeper into our Video Rooms platform to get a better understand of what its capable of, and what you can buid. Learn more about our Client SDKs and Server APIs.

Client SDKs

Our Javascript SDK API reference which details the API of our SDK including behaviors of the Room class and the Events that triggers and how they function.

Server APIs

  • Rooms - manage Rooms
  • Client Access Tokens - manage client access tokens needed to interact with a Room
  • Sessions - manage room sessions, end a session, and mute/unmute/kick all participants in a given session.
  • Participants - search for participants based on a number of filters like session id
  • Recordings - manage recordings, including bulk delete.
  • Compositions - create and manage compositions.

Getting Started

Source: https://developers.telnyx.com/docs/video/javascript-sdk.md
The Telnyx Video Client SDK provides all the functionality you need to join and interact with a video room from a browser. npm

Adding Telnyx to your JavaScript client application

Include the @telnyx/video npm module as a dependency: npm install @telnyx/video --save After pasting the above content, Kindly check and remove any new line added Then, import @telnyx/video in your application code.
After pasting the above content, Kindly check and remove any new line added Now you are ready to connect to a video room that you created. In order to connect to a video room you will require a client token that has the necessary grants to join the room.
After pasting the above content, Kindly check and remove any new line added

Understanding the state of the video room

The state_changed event callback contains the state of the SDK at that point in time. This is an immutable object that you can use in most modern UI libraries like React and Vue. The Typescript definition of the State is helpful in understanding the structure of this object.
After pasting the above content, Kindly check and remove any new line added Everytime the state of the SDK changes the state_changed callback is invoked with a new immutable state that represents the current state of the SDK. Since most modern UI libraries are able to compare the two immutable states and render only the components that changed it makes it easier to integrate the SDK with them rather than depending on multiple event callbacks. For e.g., based on how we initialized it in the above code example the initial state of the SDK would result in an object give below. Note that the ID of the local participant is unique and are generated based on UUID v4 standard when you create the local participant.
After pasting the above content, Kindly check and remove any new line added At this point there are no streams being published by the local participant. We will come to that shortly. The participant object follows the TypeScript interface given below.
After pasting the above content, Kindly check and remove any new line added When we called the room.connect() method in the example code the state of the SDK will change to the following …
After pasting the above content, Kindly check and remove any new line added This new state will be available to your application via the state_changed callback. Since state is immutable the only difference between the initial state and the new state is the status property. If you are using a modern UI library like React you can easily rerender the components to show that the application is connecting to the room. When successfully connected the state changes to …
After pasting the above content, Kindly check and remove any new line added Now we are ready to start publishing streams on behalf of the local participant.

Publishing your local camera and mic stream

In order to publish a stream you need to define the constraints of the media. The simplest form of the constraints is …
After pasting the above content, Kindly check and remove any new line added With these constraints the SDK will try to obtain both audio and video from the local participant. In order to publish the stream as the local participant you have to use the publish method available to you via the room object.
After pasting the above content, Kindly check and remove any new line added The first argument to publish is a string that acts as the key that you can use to refer to this specific stream. You can use any valid string for this as long as you are consistent in your application. For e.g. here we’re using ‘self’ for the camera/mic stream but you could use ‘presentation’ as the key for when you publish video of the screen. We will get to how you can publish your screen in a short while. When you make the request to publish a stream, the browser will ask for the necessary permissions required to access the camera and mic. Once the permissions are acquired the SDK will configure and publish the stream to the room you are connected to. At this point you will receive the new state to the state_changed event callback with the newly created stream.
After pasting the above content, Kindly check and remove any new line added The stream object is the most complex object in the state of the SDK. However you don’t have to worry about all of these properties at the moment. As you can see the isPublishing property of the stream is true now. This means that the stream is being published, which involves creating the SDP (Session Description Protocol) and establishing the WebRTC connection. You can’t publish another stream of the same key (“self” in our case) until this stream is published or removed (by unpublishing). Once the SDK acquires the media tracks from the camera and mic of the local participant a new state will be returned using the state_changed callback. This state will contain the audio and video track from the local media devices. The streams object at this point will look like this
After pasting the above content, Kindly check and remove any new line added As you can see at this point you can use the source or the media tracks individually from audioTrack and videoTrack to show the media in your UI. You can also see that the audioActive and videoActive flags are now true indicating the stream is publishing audio and video respectively. Another property that was updated in the new state is the isConfiguring flag. You can ignore this in most use-cases as this indicates if the WebRTC connection is being negotiated. Once the WebRTC connection is negotiated and the stream is successfully published the stream state would look like this
After pasting the above content, Kindly check and remove any new line added At this point the stream will be available to be subscribed by other clients connected to the same room.

Knowing when a new participant joins the room

A video room can have multiple participants and you can get a list of all the participants connected to the room at the time by using the participants property in the state. If the participant is not publishing any streams the streams property of that participant will be an empty object. Let’s imagine that another participant joins the same room from a different browser session with the following context
After pasting the above content, Kindly check and remove any new line added Since the room already contains a participant who is publishing a stream the state once this session is connected would look something like …
After pasting the above content, Kindly check and remove any new line added As you can see there is already a participant in the participants object that maps to the remote particpant from the previous browser session. This remote participant also has a stream with the key “self”. The stream object for “self” has the structure very similar to the one we saw before but has a few new properties. The ones that are particularly interesting are subscription, videoCodec, and audioCodec. The properties for video and audio codec can be used to decide if the browser has the capabilities to decode the video and audio tracks. Then there is subscription.status, which is unpublished at the moment.

Subscribing to a remote stream

At this point we are ready to subscribe to the remote stream published by the participant. In order to do that we use the subscribe method from the room object.
After pasting the above content, Kindly check and remove any new line added This will start the WebRTC negotiation to receive the remote stream. Once successful the subscription.status will change to subscribed. You can use the source property, which is an instance of MediaStream to render the media on the browser. If the remote participant unpublishes this stream the SDK will automatically unsubscibe from the stream and the stream will disappear from the state.

Room and Events

Source: https://developers.telnyx.com/docs/video/javascript-sdk/room-events.md
Telnyx’s video JavaScript SDK lets you manage room events and join/leave notifications. We’ve made it much easier to add video capability to your web application using our Javascript SDK. The Room object and the Events that occur in a Room is the API you will use to build your video application. We’ve extensively documented the interface for the Room and Events objects, below.

Room

Room events


Tutorial

Source: https://developers.telnyx.com/docs/video/javascript-sdk/javascript-video-tutorial.md

In 10 minutes we’ll build

A simple web app in vanilla javascript to make a video with audio from a caller to a callee.

Get an API Key

You need a Telnx account to create an API key so you can interact with our Rooms API
  • If you don’t have one please: Sign up for a free account
  • Navigate to API Keys section and create an API Key by clicking Create API Key button.
  • Copy your API key

Create a Room

Let’s use our Rooms API to create a room. Request Don’t forget to update YOUR_API_KEY here.
Response
Great, grab the response has an id field, this is the id for your newly created Room.

Generate a client token

You’ll need a client access token to join the room. To create one use our REST API rooms/create endpoint. You’ll need to replace ROOM_ID in in the url of the command with your room id, above. As well as YOUR_API_KEY as you have in previous steps. Request
Response
The token field in the response is the client access token you’ll use to join the room.

🏁 Checkpoint - run the app

At this point you should have the following:
  • An API Key
  • A room ID
  • A room client access token
Let’s run the app in a sandbox There’s a README with instructions inside the sandbox. We can use this sandbox as a template to build out the rest of our application.

Let’s write some code

Basic concepts of the video SDK Here are some basic concepts of the SDK that will help you better understand how it works.
  • A Room represents a real time audio/video/screen share session with other people or participants. It is fundamental to building a video application.
  • A Participant represents a person inside a Room. Each Room has one Local Participant and one or more Remote Participants.
  • A Stream represents the audio/video media streams that are shared by Participants in a Room
    • A Stream is indentified by it’s participantId and streamKey
  • A Participant can have one or more Stream’s associated with it.
  • A Subscription is used to subscribe to a Stream belonging to a Remote Participant
Room Events There are a few events trigger on a Room instance that we’ll need to finish building this app that makes a video call.
  • connected - triggers when a room instance has connected to the server
  • participant_joined - triggers when a remote participant joins the room
  • stream_published - triggers when a stream has started being published to the room
  • subscription_started - triggers when subscription to remote stream has started
Handling an event looks like this:

🏁 Checkpoint

It might be helpful to take a look at the full list of Events available on a Room instance.

Connect to the room and get local media

NOTE: We can start implementing our code after the room.initialize block inside the sandbox above. Let’s connect to the room and use the standard WebRTC API to get the audio and video tracks from the device.

Publish the stream and render it

We want to a add/publish a stream the room which consists of the audio and video track we received from the user’s device, above. We’ll give the stream a key of “caller”, which is how the stream is identified.
Render the stream to the DOM Now, that we have the caller’s stream we want to render it to the DOM. The entire room.connected block looks like this:
Great, we’re now publishing the local partipants’/caller’s stream, to the room which the callee can subscribe to.

Subscribe to the callee’s remote stream

As a caller, how do we know when the callee has joined the room or has started publishing a stream? That’s where the participant_joined and the stream_published events that we went over earlier, come into play. We need to listen for teh stream_published event like this:
Understanding how subscriptions work __The stream_published event is triggered for both local and remote streams. __ In our case, we want to know when the callee’s remote stream starts publishing so we can subscribe to it. We already know that the caller has published a “caller” stream so we can ignore that event. Subscribing to a stream When a stream is published in a room it doesn’t mean it’s audio and video tracks are accessible, yet. In order to access a remote stream’s track we must explicitly subscribe to that stream and wait for the subscription_started event.

Render the callee’s remote stream

We’re almost there! Now, we can listen to the subscription_started event and use args from that handler to get the callee’s remote stream and render it to the DOM.

Run the app

To run the app:
  • Open the sandbox, the browser here represents the caller’s app
  • Open the app in another tab, this represents the callee’s application which you’ll need to interact with.
From the caller app
  • Click the call button
  • You should be prompted by the browser for camera/micrphone access please allow.
  • You should also see video from your device’s camera and hear audio from the microphone
  • You should see some console log, if things are working property
From the callee’s app
  • Click the call button
  • Notice in the caller’s app a stream subscription was logged
  • The callee’s video/audio stream is rendered.

Android SDK

Source: https://developers.telnyx.com/docs/video/android-client-sdk.md
The Telnyx Video Android SDK is simple to use and makes it easy to get started with video calling. With this SDK, you can easily add video calling to your app with just a few lines of code. It provides all the functionality you need to join and interact with a Telnyx Room from an Android application. Android SDK

Project structure

  • SDK project: sdk module, containing all Telnyx SDK components as well as tests.
  • Demo application: app module, containing a sample demo application utilizing the sdk module.

Adding the SDK to your Android client application

Add Jitpack.io as a repository within your root level build file:
Add the dependency within the app level build file:
Tag should be replaced with the release version. Then, import the TelnyxVideo SDK into your application code at the top of the class:
The ’*’ symbol will import the whole SDK which will then be available for use within that class. Remember to add and handle INTERNET, RECORD_AUDIO and ACCESS_NETWORK_STATE permissions in order to properly use the SDK.

Before connecting to a Room

Get an API Key

You’ll need an API key which is associated with your Mission Control Portal account under API Keys. You can learn how to do that here. An API key is your credential to access our API. It allows you to:
  • to authenicate to the Rest API
  • to manage your access tokens

Create a Room to join (if it doesn’t exist)

In order to join a room you must create it, if it doesn’t already exist. See our Room Rest API to create one. There’s also additional resources on other endpoints available to perform basic operations on a Room.

Generate an a client token to join a room

In order to join a room you must have a client token for that Room. The client token is short lived and you will be able to refresh it using the refresh token provided with it when you request a client token. Please see the docs here to learn how to create a client token. Now you are ready to connect to a video room that you previously created using the REST API.

Connect to Room

To connect, you’ll need to provide a participantName that will identify your user in that room. You’ll also need to provide an instance of ExternalData that will contain a username of type String and an Integer id. You will also provide your Android application’s context in context

Publish video/audio stream

To publish as video or audio stream, we will need an instance of PublishConfigHelper with the application context, camera direction, streamKey (unique for each stream published), and streamId (unique for each stream published)
New streams can be created via the PublishConfigHelper class for both audio and video. They can be created together or added later independently.
Since stream is already created, it is only necessary to add the video track to PublishConfigHelper, and “update” the stream.

Remove video/audio track

To remove a video or audio track, publishConfigHelper has to be modified in order to remove the unwanted track

Remove stream

By removing the stream, we will remove all tracks added to it.

Video/Audio Observables

The Telnyx Video SDK for android works with mutable live data, and all the information you need to build your UI is provided through observables that will contain the most up to date information of the state of the room, such as current participant list, talking events, stream information, participants added, participants leaving, etc

State Observable

This observable will provide the current state of a room at any given moment. We will receive a State object that will contain:
action -> “val action: String` is the cause of the latest change of State
status -> val status: String is the status of the Room session, when that action happened
participants -> val participants: List is the list of participants present in a room. A Participant is a UI representation in variables, for an attendee to the room session.
streams -> val streams: HashMap this hash map, contains a track of the currently available streams and the id of the publisher streaming them. A stream, will contain tracks for video, audio or both.
publishers -> val publishers: List This will track all publishers in the room. A Publisher is an instance of an attendee or participant sharing some stream content in the room. A single Participant, sharing multiple streams can be also linked to multiple Publisher ids.
subscriptions -> val subscriptions: List Each time a publisher starts streaming information, we will have the option of subscribe/unsubscribe to/from it. This list will track all the subscriptions.

Event observables

Some observables will have a MutableLiveData of Event. Event is a wrapper of LiveData, and provide the means to ensure we only handle an observable once, no matter how many times we’re set to observe it. If the contents have already been handled, we won’t get that content again, unless we peekContent() instead.

Participants Observable

This mutable list will be received as soon as we join a Room session, and contains a list of the participants already present in the room, including yourself. The SDK will keep this list updated but won’t post the changes, so this observer won’t be fired again. See Participant By receiving this list we can initialize a recycler adapter in order to show participants:

Joined Room Observable

This mutable will fire an event as soon as we have connected to a room, and we have retrieved an initial list of Participants It is useful when we want to update UI as soon as we have joined the room sucessfully. This will be different to Status-CONNECTED that will be issued when we have successfully joined our plugins to handle session audio. See Status.

Joined Participant Observable

We receive the participant that has joined the room after client has already joined. We can add the this reference to the list used in our adapter as:

Leaving participant id Observable

We receive the publisherId that has leaved the room, and a reason for its exit (“Left” or “Kicked”).

Connected to room Observable

Receive true when we have opened a webSocket and connected to the room

Participant stream changed Observable

We will receive here an event with the participant that has recently changed its video and/or audio stream status. Mutable list of participants will also be updated with this change, but here the specific individual is received.

Stream status

These status apply for audio, video and shared screen: UNKNOWN : initial status. We don’t have information on whether this participant is sharing audio/video/screen ENABLED : the participant is sharing audio/video/screen and we can subscribe to a stream for it like: DISABLED : the participant is not sharing audio/video/screen. If we were subscribed to that participant audio/video/screen we can unsubscribe from it.

Subscribe to a video stream

In order to subscribe to a video stream, there are 3 actions that needs to be performed:
1 Provide the SDK with the same instance of SurfaceViewRenderer you want to init:
This will use the proper WebRTC Connection to provide an EglContext for the surface to be init 2 Use method addSink() to add a SurfaceViewRenderer instance to the videoTrack provided for a Participant, and set that track to enable videoTrack?.setEnabled(true) 3 Subscribe to the stream a participant is providing
participantId is the participant id that uniquely identifies a single participant in the room streamKey i.e: “SharingSubscriptions” “CameraSubscriptions” streamConfig whether we want to subscribe to audio/video or both. By default we will attempt both.

Remove subscription to a *video stream

To remove a subscription we need to issue
A good practice when handling surfaces is to make sure you remove this surface properly from the rendering context before eliminating or removing the surface from the UI:

Participant Talking Observable

We will receive the participant that has updated its talking status, and the stream key. This information is also modified in the Participants list

Stats

We provide the method getWebRTCStatsForStream() to retrieve WebRTC stats This request brings stats one time only, so if you want to keep receiving stats, you will need to use some sort of runnable or coroutine to recursively request for them such as:
We have to provide participantId, streamKey that is the key that identifies the stream we need the stats from, and callback that is an RTCStatsCollectorCallback we provide to the WebRTC peer connection in order to retrieve the stats. In Kotlin, method call will look like this
We can later parse the information retrieved to obtain the specific information we go after. In our sample app, you will see the models we use for audio and video, both local and remote

Remote Video stats

WEBRTC’s RTCStatsReport can be parsed and mapped to RemoteVideoStreamStats

Local Video stats

WEBRTC’s RTCStatsReport can be parsed and mapped to LocalVideoStreamStats

Remote audio stats

WEBRTC’s RTCStatsReport can be parsed and mapped to RemoteAudioStreamStats

Local audio stats

WEBRTC’s RTCStatsReport can be parsed and mapped to LocalAudioStreamStats

iOS SDK

Source: https://developers.telnyx.com/docs/video/ios-client-sdk.md
The Telnyx Video iOS SDK provides the functionality you need to join and interact with a video room from an iOS application. iOS SDK

If you prefer to jump right in

Have a look at our demo app: Telnyx Meet.

An overview of the Video API

These are important concepts to understand.
  • A Room represents a real time audio/video/screen share session with other people or participants. It is fundamental to building a video application.
  • A Participant represents a person inside a Room. Each Room has one Local Participant and one or more Remote Participants.
  • Room State tracks the state of the room as it changes making it extremely easy to understand what’s happened to a Room.
    • Room State could change due to a Local Participant has started publishing a stream or because a Remote Participantleft.
  • A Stream represents the audio/video media streams that are shared by Participants in a Room
    • A Stream is indentified by it’s participantId and streamKey
  • A Participant can have one or more Stream’s associated with it.
  • A Subscription is used to subscribe to a Stream belonging to a Remote Participant

API of a Room

This should give you high level overview of the Room API and it’s functionality.
After pasting the above content, Kindly check and remove any new line added

Events that are triggered in a Room

Here’s a list of events that will fire as you make API calls.
After pasting the above content, Kindly check and remove any new line added

Understanding the state of the Room

Everything in the SDK centers around the Room object. When the state of the Room changes (e.g. a new participant joins or a remote participant starts publishing a stream) the onStateChanged event is triggered. The event is invoked with a state parameter which contains the current of the state of the Room.
After pasting the above content, Kindly check and remove any new line added

Before getting started

Install the SDK

Currently, the Telnyx iOS Video SDK can be installed using CocoaPods. For instructions on that check out our releases repo for iOS

Get an API Key

You’ll need an API key which is associated with your Mission Control Portal account under API Keys. You can learn how to do that here. An API key is your credential to access our API. It allows you to:
  • to authenicate to the Rest API
  • to manage your access tokens

Create a Room to join (if it doesn’t exist)

In order to join a room you must create it, if it doesn’t already exist. See our Room Rest API to create one. There’s also additional resources on other endpoints available to perform basic operations on a Room.

Generate an a client token to join a room

In order to join a room you must have a client token for that Room. The client token is short lived and you will be able to refresh it using the refresh token provided with it when you request a client token. Please see the docs here to learn how to create a client token.

Code Examples

Enough already let’s get to the code. Here are some code examples to get your wet feet on how to start building something with the iOS video SDK.

Participating in a Room

Connect to a room

First, you’ll need to create a Room instance and then connect to it. Once you’re connected to a room, you can start sharing audio/video streams with other participant in the rooms. Important Note: This simply creates an instance of a Room in code it does not use the Rooms Rest API to create a room, mentioned above in “Create a Room to join”*
After pasting the above content, Kindly check and remove any new line added Once the room is connected you’ve joined the room as it’s local participant. You can see this more clearly by, after connecting, get the local participant. Important Note: Room only has one Local Participant but can have multiple Remote Participants.
After pasting the above content, Kindly check and remove any new line added

What is Room context?

Context is any details you want to include about the LocalParticipant of the Room. For instance, let’s say you want to use context to identify a Participant with fields from an external system. You could pass a userId and username as context, like the code snippet above. These details will be available to all RemoteParticipants in the Room, when they are notified about your presence in the Room.

Working with local media

Publishing audio and/or video from your camera or microphone works by using MediaDevices. MediaDevices is a helper class that we provide for you to make it easy to grab local media from your device.
After pasting the above content, Kindly check and remove any new line added

Setting the quality of the local video

You can set the camera resolution and fps using MediaDevices.
After pasting the above content, Kindly check and remove any new line added Note: If you choose highest resolution and fps, the local video stream will lag if you have poor internet / bandwith

Publishing a stream

Once you have tracks from say, a local media device like video from a camera and/our audio from your micrphone you can use those to create a Stream and publish it in the Room.
After pasting the above content, Kindly check and remove any new line added

Unpublishing a stream

If you can longer want to continue publishing a stream you can unpublish it. Naturally the stream you want to unpublish must be added already.
After pasting the above content, Kindly check and remove any new line added

Working with Remote Participants and Streams

A remote participant who joins or leaves the room

When a remote participant joins a a room you will be notified with the Room.onParticipantJoined event. And similiarly with Room.onParticipantLeaving when a remote participant leaves. You can use these events to keep track of participants in the room.
After pasting the above content, Kindly check and remove any new line added

Remote participants already in the room

When you connect to a Room there may already be remote participants in the Room. To understand who is in the Room after you connect use the onParticipantJoined event.
After pasting the above content, Kindly check and remove any new line added

Display a remote participant’s media

In order to understand how to display a remote participants’ media let’s review on subscriptions work in the API. It might be helpful to review the Video API overview to get a better understanding of how a Room is modeled, especially Stream and Subscription. Major 🔑 about Subscriptions In order to display media from a remote stream you need to subscribe to it. It’s important to understand that your Room doesn’t automatically subscribe to a remote stream being published. It’s your choice to decide whether to subscribe to a given stream.

Subscribing to a stream

So let’s say the app your building has two users - let’s them call them Alice and Bob. First, Alice joins the Room and starts publishing a stream with audio from her microhone and video from her camera like this: NOTE: The app on Alice’s device runs the following code…
After pasting the above content, Kindly check and remove any new line added Bob wants to get Alice’s stream so he can display it. In order to do so he needs to subscribe to Alice’s stream. NOTE: The app on Bob’s device runs the following code…
After pasting the above content, Kindly check and remove any new line added

Handling remote streams that are already publishing in the Room

After you connect to a Room there may be remote participants already in the Room who are publishing streams in the Room. To deal with that use the onStreamPublished event:
After pasting the above content, Kindly check and remove any new line added

Disconnecting from a Room

To disconect from a room do:
After pasting the above content, Kindly check and remove any new line added When you disconnect from a Room all Remote Participant’s will be notified that you’ve left the Room because the Room.onParticipantLeft event will fire on their Room instance.

Fax

Getting Started

Source: https://developers.telnyx.com/docs/programmable-fax/get-started.md

Introduction

Welcome to Telnyx Programmable Fax, a powerful tool that allows you to send and receive faxes seamlessly through HTTP endpoints. This guide will introduce you to the basics of setting up and using the Programmable Fax API.

Prerequisites

Before you begin, you’ll need to:

Core Concepts

  • Programmable Fax Application: Configure inbound traffic and authentication for your phone numbers.
  • Outbound Voice Profile: Manage outbound traffic, billing, and allowed destinations.
  • Webhooks: HTTP callbacks that notify your server about fax events.

Hello World Example

Send Your First Fax Using cURL:
  1. Authenticate Your Request: Include your API key in the header for authentication.
  2. Specify Fax Details: Provide the media URL, connection ID (use your application id), and the ‘to’ and ‘from’ fax numbers in E.164 format.
  3. Send the Fax:
Replace placeholders with your actual data.
  1. Verify the Response: Check for an HTTP 202 response indicating successful fax initiation

Next Steps

  • Explore advanced features like receiving faxes and detailed webhook management.
  • Check out our detailed tutorials for comprehensive guidance.

Additional Resources

  • Visit our API documentation for in-depth understanding.
  • Join our community forums for support and discussion

Feedback

We value your feedback. If you have questions or need help troubleshooting, our support team is ready to assist. Contact us here.

Glossary

  1. Programmable Fax Application: A configuration within the Telnyx platform used to manage inbound and outbound fax traffic. It includes settings for authentication and handling of fax transmissions.
  2. Outbound Voice Profile: A setting in Telnyx that allows users to initiate outbound traffic, including faxes. It includes configurations for billing, traffic management, and permitted destinations.
  3. Fax_id: A unique identifier assigned to each fax transmission. It is used to track and manage specific fax communications within the Telnyx system.
  4. Media_url: The URL pointing to the document you wish to fax, typically in PDF format. This URL is included in the fax command to specify the fax content.
  5. Connection_id: An identifier for your specific application or connection within Telnyx, used to route the fax correctly and associate it with your account.
  6. E.164 Format: An internationally-recognized format for phone numbers, used in specifying the ‘to’ and ‘from’ fields in fax commands.
  7. Failure_reason: A field in the webhook payload that provides the reason for a fax’s failure, helping in troubleshooting and understanding delivery issues.
  8. Ngrok: A tunneling tool used to expose a local server to the internet, often used for testing webhook endpoints in development environments.
  9. cURL: A command-line tool used for sending requests to URLs, commonly used for interacting with APIs like Telnyx’s Programmable Fax API.

Quickstart

Source: https://developers.telnyx.com/docs/programmable-fax/quickstart.md
In this guide, you’ll learn how to get started with Telnyx Programmable Fax within the Telnyx Portal. Just follow these simple steps:
  1. Sign up for a Telnyx Account.
  2. Create a Programmable Fax Application to configure how you connect your calls.
  3. Buy or port a Phone Number.
  4. Assign your number to the Programmable Fax Application.
  5. Create an Outbound Voice Profile to configure your outbound call settings and assign it to your Programmable Fax Application.

Step 1: Sign Up for a Telnyx Mission Control Portal account

Head to telnyx.com/sign-up to sign up for your free Telnyx account. It’ll give you access to our Mission Control Portal where you can buy phone numbers, set up and manage Programmable Fax Applications, and more.

Step 2: Create a programmable fax application in the Telnyx portal

  • Select “Programmable Fax” in the left-hand navigation menu.
  • Click “Add New App”.
  • For testing purposes, you can set the webhook URL using an endpoint you create at https://hookbin.com .

Step 3: Buy a phone number

You can search for, buy, and provision new numbers, or port existing numbers - all within the Numbers section of the Telnyx Portal . Simply click on “Numbers”, then either “Search & Buy Numbers” or “Port Numbers” and follow the prompts.
You can also do this programmatically via our RESTful API. Check out our documentation for number searching and ordering.

Step 4: Assign your phone number to the programmable fax application

Once your number has been purchased or ported, assign it to the Programmable Fax Application that you created in step 2. You can do this via the My Numbers section of the Portal. Docs Images (1)

Step 5: Create an outbound voice profile (not required for Inbound)

To initiate an outbound fax, you must create an Outbound Voice Profile and assign your Programmable Fax Application to it. Select “Outbound Voice Profiles” on the left-hand navigation menu, click “+Add New Profile” and set up your profile name. Add the Programmable Fax Application you just created above, the traffic type, the service plan, and your desired billing method.
You can also do this programmatically via our RESTful API. Check out our documentation for Outbound Voice Profiles.
That’s it. You’re all set to start integrating Telnyx with your applications.

Where to next?

Head over to our tutorials to learn how to send a fax and receive a fax via API. After you setup your development environment you can also dive deeper into sending commands and receiving webhooks.

Receiving Webhooks

Source: https://developers.telnyx.com/docs/programmable-fax/receiving-webhooks.md
When you send a Programmable Fax command and receive a successful response (i.e. 200 OK), you can expect to receive a webhook. The webhook will be delivered to the primary URL specified on the Application associated with the call. If that URL does not resolve, or your application returns a non 200 OK response, the webhook will be delivered to the failover URL, if one has been specified. In order to minimize webhook delivery time, Telnyx:
  • does not enforce the order in which webhooks are delivered
  • retries webhook delivery if your application does not respond within a certain time threshold.
As a result, you may encounter:
  • out-of-order webhooks
  • simultaneous (or near simultaneous) webhooks
  • duplicate webhooks
Duplicate webhooks may cause your application to issue duplicate commands. You can instruct Telnyx to ignore duplicate commands by sending a command_id parameter as part of your commands. Commands with duplicate command_ids within 60 seconds will be ignored.

Example: Receiving a webhook from an outbound fax

When you place an outbound fax, you will receive a number of webhooks indicating the current status of the fax. The first webhook you will receive will have A queued status indicating that Telnyx successfully received the request to send the fax.
FIELD VALUE record_type Description of the record. id unique id for the webhook event_type The type of event occurred_at ISO-8601 datetime of when event occured to Destination number or SIP URI of the call from Number or SIP URI placing the call fax_id Unique ID for the Programmable Fax client_state Configurable state to track commands status Can be one of queued, media.processed, sending.started, delivered, failed

Example: Receiving a webhook on successful fax delivery

Example: Receiving a webhook on failed fax delivery

Possible failure reasons

Inspect the failure_reason field in webhook’s payload to debug failed deliveries of your faxes. The possible failure reasons are:
  • account_disabled
  • connection_channel_limit_exceeded
  • destination_invalid
  • destination_not_in_countries_whitelist
  • destination_not_in_service_plan
  • destination_unreachable
  • fax_initial_communication_timeout
  • fax_signaling_error
  • invalid_ecm_response_from_receiver
  • no_outbound_profile
  • outbound_profile_channel_limit_exceeded
  • outbound_profile_daily_spend_limit_exceeded
  • receiver_call_dropped
  • receiver_communication_error
  • receiver_decline
  • receiver_incompatible_destination
  • receiver_invalid_number_format
  • receiver_no_answer
  • receiver_no_response
  • receiver_recovery_on_timer_expire
  • receiver_unallocated_number
  • service_unavailable
  • unverified_destination_not_allowed
  • unverified_origination_number
  • user_busy
  • user_channel_limit_exceeded

Sending Commands

Source: https://developers.telnyx.com/docs/programmable-fax/sending-commands.md
A Programmable Fax API command is sent with a fax_id. The fax_id allows a user to communicate to Telnyx the fax the user wants to take an action on. The Telnys Programmable Fax API supports PDF files. To initiate sending the fax, we need to send the request to the Telnyx Programmable Fax API endpoint https://api.telnyx.com/v2/faxes.

Authentication

With the request we need to send additional parameters containing authentication information so Telnyx knows which account to send the fax from and information about the destination and file being sent. HEADER DESCRIPTION media_url Authorization: Bearer YOUR_API_KEY connection_id Authorization: Bearer YOUR_API_KEY to Authorization: Bearer YOUR_API_KEY from Authorization: Bearer YOUR_API_KEY Authorization: Bearer The prefix to your API V2 key created in Step 2.

Available commands and their expected Webhooks

Telnyx sends webhooks to update on the status of Programmable Fax. Webhooks will also be sent in response to requests to list and delete faxes. COMMAND ASSOCIATED WEBHOOKS Send a fax fax.queued fax.media.processed fax.sending.started fax.delivered fax.failed

Response when sending command

When you send a Programmable Fax API Command, you will immediately receive an http response. Responses include, but are not limited to: HTTP STATUS CODE MESSAGE DESCRIPTION 202 OK The request succeeded. 403 Forbidden The request was valid, however the user is not authorized to perform this action. 404 Not Found The requested resource could not be found. 422 Invalid Parameters The request has invalid parameters.

Example: Sending commands

To send a fax, send a POST request to the https://api.telnyx.com/v2/faxes endpoint as shown in the example below.

WITH A API V2 KEY

After pasting the above content, Kindly check and remove any new line added

Send a fax via API

Source: https://developers.telnyx.com/docs/programmable-fax/send-a-fax-api.md
The Telnyx Programmable Fax API lets you send, receive, and manage faxes through a set of easy-to-use HTTP endpoints. In this guide, you’ll learn how to send a fax using the Programmable Fax API in four simple steps.

Step 1: Setting up with Telnyx

Setup a Telnyx account, phone number, and programmable fax application

First, follow our Quickstart guide to create a Telnyx account, phone number, and Fax Application.

Step 2: API authentication

If you already have a Telnyx V2 API Authentication key, skip to Step 3.
  1. In the Telnyx Mission Control Portal , in the left menu bar navigate to ” API Keys ”.
  2. Ensure, API V2 is selected in the horizontal menu bar.
  3. Click “Create API key”
  4. Copy the API key and save it somewhere safe.

Step 3: Send a PDF with the programmable fax API using curl

The Telnyx Programmable Fax API supports PDF files. To initiate sending a fax, we need to send the request to the Telnyx Programmable Fax API endpoint https://api.telnyx.com/v2/faxes. We need to send additional parameters containing authentication information with the request, so Telnyx knows which account to send the fax from and information about the destination and file being sent. Header Description media_url The URL of the PDF used for the fax’s media. connection_id The app ID or connection ID to send the fax with. to The fax enabled phone number (in E.164 format), or SIP URI, the fax will be sent to. from The phone number, in E.164 format, the fax will be sent from. Authorizaton: Bearer The prefix to your API V2 key created in Step 2. Now that we know what we need to include in our request, we can use a number of different methods to structure and send it. In this example, we are going to use curl straight from the command line. You can also use a client such as Postman to structure your request.
After pasting the above content, Kindly check and remove any new line added Simply copy the above code into your favorite text editor, paste in your parameters from the table in place of the existing data, and execute the command.

Step 4: Verify HTTP response and receive webhooks

If you have successfully structured your command and the fax has begun sending, the Programmable Fax API will respond with HTTP 202. If you do not receive a HTTP 202 response, double-check your request and try again. Explanations of other response codes can be found in our API reference. Once the request to send the fax has been successfullly received by Telnyx, you should begin receiving a series of webhooks to the URL that you specified in your Fax Application. The webhooks you should receive are:
  • fax.queued
  • fax.media.processed
  • fax.sending.started
  • fax.delivered
  • fax.failed
That’s it! Once you’ve received a fax.delivered webhook, your fax has been delivered to its destinaion.

Webhook examples

On successful delivery

After pasting the above content, Kindly check and remove any new line added

On failed delivery

After pasting the above content, Kindly check and remove any new line added

Possible failure reasons

Inspect the failure_reason field in webhook’s payload to debug failed deliveries of your faxes. The possible failure reasons are:
  • account_disabled
  • connection_channel_limit_exceeded
  • destination_invalid
  • destination_not_in_countries_whitelist
  • destination_not_in_service_plan
  • destination_unreachable
  • fax_initial_communication_timeout
  • fax_signaling_error
  • invalid_ecm_response_from_receiver
  • no_outbound_profile
  • outbound_profile_channel_limit_exceeded
  • outbound_profile_daily_spend_limit_exceeded
  • receiver_call_dropped
  • receiver_communication_error
  • receiver_decline
  • receiver_incompatible_destination
  • receiver_invalid_number_format
  • receiver_no_answer
  • receiver_no_response
  • receiver_recovery_on_timer_expire
  • receiver_unallocated_number
  • service_unavailable
  • user_busy
  • user_channel_limit_exceeded

Where to next?

Continue to our next tutorial to learn how to receive inbound faxes via API.

Receive a fax via API

Source: https://developers.telnyx.com/docs/programmable-fax/receive-a-fax-api.md
The Telnyx Programmable Fax API lets you send, receive and manage faxes through a set of easy-to-use HTTP endpoints. In this guide, you’ll learn how to handle receiving a fax using the Programmable Fax API.

Step 1: Setup with Telnyx

Setup a Telnyx account, phone number, and programmable fax application

First, follow our Quickstart guide to create a Telnyx account, phone number, and Fax Application. The phone number that you select and associate with the Programmable Fax Application will receive incoming fax calls. You can also port an existing number to Telnyx and use it for Programmable Fax.

Step 2: Receiving Webhooks

In order for the webhooks in this tutorial to work, Telnyx must be able to send your web application an HTTP request over the Internet. That means your application needs to have a URL or IP address that Telnyx can reach. Telnyx sends webhooks to the URL or IP address to notify your application of incoming faxes. For the purpose of this tutorial, we’re using ngrok , a popular tunneling tool used to expose a locally running application to the internet. ngrok gives you a public URL for a local port on your development machine, which you can use to configure your Telnyx webhooks as described above. Download and install ngrok, then use it at the command line to create a tunnel to whatever port your web application is running on. For example, this command will create a public URL for a web application listening on port 3000.
After executing that command, you will see that ngrok has given your application a public URL that you can use in your webhook connection configuration in the Telnyx Mission Control Portal . Send and receive fax using Telnyx Programmable Fax API Grab your ngrok public URL and head back to the Programmable Fax Application you configured earlier. Now in the field under “Send a webhook to the URL” enter your new ngrok URL from either of the “Forwarding” URLs ngrok provided us with depending on if you want to use HTTP or HTTPS. You’re now all set up to receive webhooks for events related to inbound faxes. If you use the same Programmable Fax Application for sending faxes, you will receive events to the same ngrok URL you just created.

Example Webhooks

If you have set everything up correctly, any time an inbound fax is received you can expect to receive the following webhooks: Webhook Name Description fax.receiving.started The fax has begun transmitting to Telnyx successfully. fax.media.processing.started Telnyx has received the fax and is generating the digital PDF file. fax.received The PDF has been generated and the file is ready to be downloaded. fax.failed Transmission of the fax failed. Check the <code>failure_reason</code> for more details.

Fax has begun transmitting to Telnyx

Fax transmission is complete and Telnyx is converting to PDF

PDF has been generated and is ready for download

The media_url field contains a signed AWS link to a PDF of the received fax. This URL is valid for 10 minutes before the file is no longer accessible so be sure to download the file if you wish to keep it!

Uh oh, something has gone wrong and the fax failed

Inbound faxes can fail for a variety of reasons. Some of the most common reasons are that the sending party hung up before the fax was finished transmitting or didn’t send anything at all.

Where to next?

Go back to our previous tutorial to learn how to send outbound faxes via API.

Email to fax

Source: https://developers.telnyx.com/docs/programmable-fax/email-to-fax.md
⏱ 60 minutes build time. __🧰 Clone the sample application from our GitHub repo __ In this tutorial, you’ll learn how to use the Telnyx Fax API to receieve faxes to your email in Python. Our Programmable Fax API, combined with our Numbers API, provides everything you need to build a robust call tracking application: The Numbers API enables you to search the Telnyx phone number inventory in real time; filtering by Area Code, City/State, and more to find the perfect local number for your use-case. Call Control enables you to quickly setup dynamic forwarding numbers, toggle dual-channel recording, join/leave dynamic conferences, and pull post-call analytics. By following this tutorial, you’ll be able to:
  1. Configure a Telnyx portal account.
  2. Set up a Telnyx Fax profile and an outbound voice profile.
  3. How to send a fax to your email using Telnyx.
  4. How to send a fax using your email and to Telnyx Fax profile.

What you’ll need to get started with email to fax

  1. A Telnyx account- take a minute to sign up to our self-service portal.
  2. A Telnyx phone number that’s enabled with a Telnyx Fax Appliction and a Telnyx Outbound Voice profile .
  3. Ability to receive webhooks (with something like ngrok)
  4. Python and PIP installed
  5. An AWS Account setup with proper profiles and groups with IAM for S3. Check out the Quickstart for more information.
  6. Finally you’ll need a Mailgun account . If you’re planning on using this guide to build an email to fax application you’ll need an account with the ability to setup inbound routes .

Create a Telnyx Mission Control Portal account

To get started, you’ll need to create an account . Verify your email address and you can log into the Mission Control Portal to get started.

Usage

The following environmental variables need to be set: Variable Description TELNYX_API_KEY Your Telnyx API Key TELNYX_PUBLIC_KEY Telnyx Public Key TELNYX_S3_BUCKET The name of the bucket to upload the media attachments TELNYX_FAX_CONNECTION_ID The connection ID for your Fax Applications MAILGUN_API_KEY Your Mailgun API Key MAILGUN_DOMAIN Your Mailgun Domain. PORT Defaults to 8000 The port the app will be served

.env file

This app uses the excellent python-dotenv package to manage environment variables. Make a copy of .env.sample and save as .env and update the variables to match your creds. TELNYX_PUBLIC_KEY=“+kWXUag92mcUMFQopVlff7ctD/m2S/IoXv+AlI1/5a0=” TELNYX_API_KEY=“KEYI” TELNYX_S3_BUCKET=telnyx-mms-demo TELNYX_FAX_CONNECTION_ID=36092346987 MAILGUN_API_KEY=“123-432-123” MAILGUN_DOMAIN=“sandbox367c5ec1512d458e95f5e5c60f5fe97a.mailgun.org” PORT=8000

Callback URLs for Telnyx application

Callback Type URL Fax Callbacks {ngrok-url}/faxes Email Callbacks {ngrok-url}/email/inbound

Install

Run the following commands to get started: $ git clone https://github.com/team-telnyx/demo-python-telnyx.git

Ngrok

This application is served on the port defined in the runtime environment (or in the .env file). Be sure to launch ngrok for that port: ./ngrok http 8000 ngrok by @inconshreveable (Ctrl+C to quit) Session Status online Account Little Bobby Tables (Plan: Free) Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://your-url.ngrok.io -> http://localhost:8000 Forwarding https://your-url.ngrok.io -> http://localhost:8000 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00 At this point you can point your application to generated ngrok URL + path: (Example: http://{your-url}.ngrok.io/faxes).

Run

High level code overview

Receiving fax, sending email

  1. Receive the webhook from Telnyx indicating fax is incoming
  2. We only only care about the fax.received webhook for inbound faxes
  3. Extract the to/from and other information about the fax
  4. Download the attachment and save locally
  5. Lookup the association between phone_number and email
  6. Create and send an email via Mailgun with downloaded media as an attachment

Sending fax

  1. Receive webhook from mailgun for incoming email
  2. Extract the prefix of the email (19198675309@MAILGUN_DOMAIN.com, we want 19198675309) and prepend the +
  3. Lookup the association between email and phone_number to determine the from phone number.
  4. Save the first attachment locally
  5. Upload the attachment to S3
  6. Create and send a fax to the phone number extracted above

Update “DB”

The app as provided uses a dumb-hard-coded database to minimize dependencies for the sake of examples. There is an in memory database defined at the top that associates an email to a Telnyx number.
  • phone_number is a Telnyx phone number
  • email is the email to associate with that phone number

Receiving faxes

Sending faxes

Launch the app and update callbacks

Start the server python app.py When you are able to run the server locally, the final step involves making your application accessible from the Internet. So far, we’ve set up a local web server. This is typically not accessible from the public internet, making testing inbound requests to web applications difficult. The best workaround is a tunneling service. They come with client software that runs on your computer and opens an outgoing permanent connection to a publicly available server in a data center. Then, they assign a public URL (typically on a random or custom subdomain) on that server to your account. The public server acts as a proxy that accepts incoming connections to your URL, forwards (tunnels) them through the already established connection and sends them to the local web server as if they originated from the same machine. The most popular tunneling tool is ngrok. Check out the ngrok setup walkthrough to set it up on your computer and start receiving webhooks from inbound faxes to your newly created application. Once you’ve set up ngrok or another tunneling service you can add the public proxy URL to your Inbound Settings in the Mission Control Portal. To do this, click the edit symbol [✎] next to your Fax Profile. In the “Inbound Settings” > “Webhook URL” field, paste the forwarding address from ngrok into the Webhook URL field. Add faxes to the end of the URL to direct the request to the webhook endpoint in your server. For now you’ll leave “Failover URL” blank, but if you’d like to have Telnyx resend the webhook in the case where sending to the Webhook URL fails, you can specify an alternate address in this field. Once everything is setup, you should now be able to:
  • Fax your phone number and receive an email
  • Email {19198675309}@domain.com an attachment to send a fax to {19198675309}

Fax follow-Ons

Now that you’ve successfully sent a fax to your email and phone number, you can explore more fax features and discover ideas to build new applications. Our developer Slack community is full of Python developers like you - be sure to join to see what your fellow developers are building!

API Reference (Other APIs)

AutoRechargePreferences

Notifications

Addresses

Billing

Authentication Providers

IP Addresses

IP Ranges

Managed Accounts

Organization Users

Billing Groups

Detail Records

MDR Detailed Reports

CDR Reports

MDR Usage Reports

Telco Data Usage Reports

Speech to text Usage Reports

  • Get speech to text usage report: Generate and fetch speech to text usage report synchronously. This endpoint will both generate and fetch the speech to text report over a specified time period.

CDR Usage Reports

Usage Reports (BETA)

Speech to Text Batch Reports

MDR Detail Reports

WDR Detail Reports

Session Analysis

  • Get metadata overview: Returns all available record types and supported query parameters for session analysis.
  • Get record type metadata: Returns detailed metadata for a specific record type, including relationships and examples.
  • Get session analysis: Retrieves a full session analysis tree for a given event, including costs, child events, and product linkages.

Webhooks

Audit Logs

  • List Audit Logs: Retrieve a list of audit log entries. Audit logs are a best-effort, eventually consistent record of significant account-related changes.

User Tags

UserAddresses

Integration Secrets

Room Compositions

Room Participants

Room Recordings

Room Sessions

Rooms

Rooms Client Tokens

  • Create Client Token to join a room.: Synchronously create an Client Token to join a Room. Client Token is necessary to join a Telnyx Room. Client Token will expire after token_ttl_secs, a Refres…
  • Refresh Client Token to join a room.: Synchronously refresh an Client Token to join a Room. Client Token is necessary to join a Telnyx Room. Client Token will expire after token_ttl_secs.

SETI Observability

Programmable Fax Applications

  • List all Fax Applications: This endpoint returns a list of your Fax Applications inside the ‘data’ attribute of the response. You can adjust which applications are listed by using filter…
  • Creates a Fax Application: Creates a new Fax Application based on the parameters sent in the request. The application name and webhook URL are required. Once created, you can assign phon…
  • Retrieve a Fax Application: Return the details of an existing Fax Application inside the ‘data’ attribute of the response.
  • Update a Fax Application: Updates settings of an existing Fax Application based on the parameters of the request.
  • Deletes a Fax Application: Permanently deletes a Fax Application. Deletion may be prevented if the application is in use by phone numbers.

Programmable Fax Commands

  • View a list of faxes
  • Send a fax: Send a fax. Files have size limits and page count limit validations. If a file is bigger than 50MB or has more than 350 pages it will fail with `file_size_limi…
  • View a fax
  • Delete a fax
  • Cancel a fax: Cancel the outbound fax that is in one of the following states: queued, media.processed, originated or sending
  • Refresh a fax: Refreshes the inbound fax’s media_url when it has expired

Callbacks

OAuth Discovery

OAuth Protocol

OAuth Clients

OAuth Grants