Skip to main content

📌 Getting Detailed Price Summaries about Calls


This snippet will show how you can utilize the List Calls Endpoint to pull detailed call reports within a specific date range! The results will include some helpful summary stats about total calls, inbound vs outbound, total cost, and total duration. We will also export further detail on a per-call record basis to a CSV for record-keeping or extra review.

To quickly run this code, check out our recipe below and replace the variables with your own! Or, keep reading for an in-depth walkthrough.

🦉 Open Recipe: How to Get Price Summaries for Voice


What do I need to run this code?

For the following code to work, you will need to have pandas, DateTime, and the SignalWire Python SDK installed.

Read about the different ways to install pandas.

Read about DateTime and how to install using pip.

Read about the SignalWire Python SDK and how to install it.

The API also requires that you authenticate yourself using your Project ID, API Token, and Space URL. If you do not know where to find these values, check out our guide to Navigating your SignalWire Space.

Step by Step Code Walkthrough

The first step, as always, will involve importing the required libraries and authenticating our SignalWire client using the authentication variables mentioned above. We will use datetime and pandas to enhance our results in this snippet. We will also use the List Calls endpoint with date range filters to narrow down our results to a particular month, although you can narrow down your results by many other factors too!

from datetime import datetime
from import Client as signalwire_client
import pandas as pd

client = signalwire_client("ProjectID", "AuthToken", signalwire_space_url='')
calls = client.calls.list(start_time_after=datetime(2022, 4, 1), start_time_before=datetime(2022, 4, 30))

In the next section, we will create two empty lists to store our overall call data for exporting as well as directional data for some summary statistics. We will loop through each call record in calls and append the direction to direction and all the other data to d. To finish up this section, we will store the number of total inbound calls and total outbound calls in their own variables to be used later.

d = []
direction = []

for record in calls:
d.append((record.from_,, record.start_time, record.sid, record.price, record.direction, record.duration))


Next, we will create a Pandas dataframe with column headers and add the data stored in d to the dataframe. This will let us export to CSV for easier record keeping and review!

df = pd.DataFrame(d, columns=('From', 'To', 'Date', 'Call SID',  'Price', 'Call Direction', 'Call Duration (s)'))
df.to_csv('MarchCalls.csv', index=False, encoding='utf-8')

In this last section, we will use the data above to create some quick summary stats to provide an overview of how the call traffic looked during this particular date range. Pandas provides an easy way to sum the total duration and cost columns while Python reformats the results to look more readable.

totalCalls = len(df)
totalCost = df['Price'].sum()
formattedCost = "${:,.2f}".format(totalCost)
totalDuration = round((df['Call Duration (s)'].sum())/60, 2)

print("You had " + str(totalCalls) + " total calls during your selected date range.")
print("There were " + str(total_inbound) + " inbound calls and " + str(total_outbound) + " outbound calls.")
print("The total cost of calls in your selected date range is approximately " + formattedCost + " USD.")
print("there was a total duration of " + str(totalDuration) + " minutes.")


What do I need to run this code?

We will need the following libraries (click their names to get instructions on how to install them):

The API also requires that you authenticate yourself using your Project ID, API Token, and Space URL. if you do not know where to find these values, check out our guide to Navigate your SignalWire Space

Step by Step Code Walkthrough

First, we need to import the necessary resources.

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class CallPriceSummary {
static String PROJECT_ID = "<ENTER-PROJECT-ID>";

static String API_TOKEN = "<ENTER-API-TOKEN>";

static String SPACE_NAME = "<ENTER-SPACE-NAME>";

static ArrayList<String[]> dataLines = new ArrayList<>();

Next, we need to create a static helper method that would be used to make calls to an endpoint, return a response that contains calls, and display them in the provided space. We will be using the SignalWire Calls endpoint on the Compatibility API to list all the calls made on a Signalwire Space.

The method loadCalls takes the parameters spaceName, projectId, and apiToken.

static JsonNode loadCalls(String spaceName, String projectId, String apiToken) {
String BASE_URL = String.format("", spaceName, projectId);

try {
HttpResponse<JsonNode> response = Unirest.get(BASE_URL)
.basicAuth(projectId, apiToken)
.header("accept", "application/json")

if (response.getStatus() == 200) return response.getBody();

} catch (UnirestException e) {
return null;
return null;

Now, we need to set the header of our CSV using a list that takes String[ ] values. The variable holding data to be exported to CSV would be called dataLines. After fetching the calls using the helper method, we would convert the JSON response to a class object Result which you can find inside the full recipe using Gson. Now we can loop through our result and call another helper method.

public static void main(String[] args) {
try {
dataLines.add(new String[]{"From", "To", "Date", "Call Sid", "Price", "Call direction", "Call duration (secs)"});

Gson gson = new Gson();

int totalCalls = 0;
double totalCost = 0d;
int totalDuration = 0;
int inbound = 0;
int outbound = 0;

JsonNode request = loadCalls(SPACE_NAME, PROJECT_ID, API_TOKEN);

if (request != null) {
SummaryResponse response = gson.fromJson(request.toString(), SummaryResponse.class);

for (Call call : response.calls) {
dataLines.add(new String[]{call.from,, call.date_created, call.sid, String.valueOf(call.price), call.direction, String.valueOf(call.duration)});
totalCalls = totalCalls + 1;
totalCost = totalCost + call.price;
totalDuration = totalDuration + call.duration;

if (Objects.equals(call.direction, "inbound")) {
} else {

System.out.println("You had " + totalCalls + " total calls during the selected range");
System.out.println("There were " + inbound + " inbound calls and " + outbound + " outbound calls.");
System.out.println("The total cost of calls in your selected range is approx. " + String.format("%.2f USD", totalCost));
System.out.println("There was a total duration of " + (totalDuration / 60) + " minutes");

} catch (Exception exception) {

In the above section, we will use the result of the data from loadCalls to create some quick summary stats to provide an overview of the call traffic during a particular date range.

As a result, we get the below screenshot:

Wrap up

This easy snippet shows how you can utilize SignalWire's APIs with some additional libraries to get even better reports built on your call traffic. Keep reading other voice snippets to find out how you can utilize our APIs in creative ways!

Sign Up Here

If you would like to test this example out, you can create a SignalWire account and space here.

Please feel free to reach out to us on our Community Slack or create a Support ticket in your SignalWire Space if you need guidance!