necessary information our Support will need to assist you! What are we going to do? This code snippet shows you how to filter faxes by Number, Status, and Date. Well be using our Compatibility API [List all Faxes](/rest/compatibility-api/endpoints/list-all-faxes) endpoint exclusively. Full code example: List Faxes Filtered by Number and Status python from signalwire.rest import Client as signalwire_client import pandas as pd from datetime import datetime # TODO: Update these variables with your own space_url = YOURSPACENAME.signalwire.com project_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx auth_token = PTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx client = signalwire_client( project_id, auth_token, signalwire_space_url = space_url) # TODO: Pick the start and end date. The format must be YYYY/MM/DD start_date = 2022/04/03 end_date = 2022/04/04 # TODO: Numbers to check for under both FROM and TO attributes # The format needs to be E.164: +12345678901 numbers = [ +###########, +###########, +###########, +###########, +###########] # TODO: Add/remove statuses from this list depending on which logs youre looking for # List of statuses to get the Fax SID for (useful in case you need to contact support) # These will be the only statuses exported to the faxes.csv # AVAILABLE STATUSES: queued, processing, sending, delivered, no-answer, busy, failed, canceled, received, receiving statuses_with_detail = [failed, canceled] # Faxes well need to give more information on and export to CSV faxes_with_detail = [] # Statuses of faxes where FROM matches any of the numbers in the numbers list from_statuses = [] # Statuses of faxes where TO matches any of the numbers in the numbers list to_statuses = [] # Statistics to be printed in the end stats = pd.DataFrame( columns = ( Queued, Processing, Sending, Delivered, No answer, Busy, Failed OUT, Canceled, Received, Receiving, Failed IN), index = numbers) # Statistics formatting options pd.set_option(display.colheader_justify, center) pd.set_option(display.max_rows, 1000) for current_number in numbers: start_datetime = datetime.strptime(start_date, %Y/%m/%d) end_datetime = datetime.strptime(end_date, %Y/%m/%d) # Listing all faxes FROM every number listed from_faxes = client.fax.faxes.list( from_ = current_number, date_created_after = start_datetime, date_created_on_or_before = end_datetime) # Listing all faxes TO every number listed to_faxes = client.fax.faxes.list( to = current_number, date_created_after = start_datetime, date_created_on_or_before = end_datetime) # Handle faxes where there is a FROM match for record in from_faxes: from_statuses.append((record.status)) the_status = record.status if the_status in statuses_with_detail: faxes_with_detail.append((record.from_, record.to, record.status, record.sid)) # Handle faxes where there is a TO match for record in to_faxes: to_statuses.append((record.status)) the_status = record.status if the_status in statuses_with_detail: faxes_with_detail.append((record.from_, record.to, record.status, record.sid)) # Append this numbers statistics stats.loc[current_number,:] = [ from_statuses.count(queued), from_statuses.count(processing), from_statuses.count(sending), from_statuses.count(delivered), from_statuses.count(no-answer), from_statuses.count(busy), from_statuses.count(failed), from_statuses.count(canceled), to_statuses.count(received), to_statuses.count(receiving), to_statuses.count(failed)] from_statuses = [] to_statuses = [] df = pd.DataFrame( faxes_with_detail, columns=( From Number, To Number, Status, Fax SID)) print(df) print(\n) print(stats) df.to_csv( faxes.csv, index = False, encoding = utf-8) Why use this snippet? Since faxes can be unreliable, it is crucial to be able to see our success rate at a glace. This code snippet allows us to do precisely this and get the following output: Code Walk-through -- ### What we need to run the code In order to run this code were going to need to have the following installed (click on top of them to get instructions on how to install them): - [SignalWire Python SDK](/compatibility-api/sdks); - [Pandas](https://pandas.pydata.org/docs/getting_started/install.html); - [DateTime](https://pypi.org/project/DateTime/). ### What we will need to change Were going to need to change the following: - **space_url**- Your Space URL is the domain of your Space, i.e. example.signalwire.com. This can also be found in an easily copyable format within the API tab in your SignalWire Space; - **project_id**- Your project ID is an alphanumeric string that tells the SignalWire SDK where to find your project. You can find this in an easily copyable format by going to your SignalWire Portal and clicking the API tab on the lefthand side; - **auth_token**- Your Auth Token is an alphanumeric string that helps to authenticate your HTTP requests to SignalWire. You can create this (if you haven’t already) or copy this in an easily copyable format by going to your SignalWire Portal and clicking the API tab. If you have not created an API token, press the blue new button. If you have, click show and copy the string; - **start_date**- This is the date from which we wish to look for faxes; - **end_date**- This is the date until which we wish to look for faxes; - **numbers**- This list should contain all of the numbers we wish to look for, in E.164 format; - **statuses_with_detail**- This list should contain all of the statuses we wish to get more information on. :::info Fax Statuses **Inbound**: Received, Receiving, and Failed. **Outbound**: Queued, Processing, Sending, Delivered, No answer, Busy, Failed, and Canceled. ::: python from signalwire.rest import Client as signalwire_client import pandas as pd from datetime import datetime # TODO: Update these variables with your own space_url = YOURSPACENAME.signalwire.com project_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx auth_token = PTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx client = signalwire_client( project_id, auth_token, signalwire_space_url = space_url) # TODO: Pick the start and end date. The format must be YYYY/MM/DD start_date = 2022/04/03 end_date = 2022/04/04 # TODO: Numbers to check for under both FROM and TO attributes # The format needs to be E.164: +12345678901 numbers = [ +###########, +###########, +###########, +###########, +###########] # TODO: Add/remove statuses from this list depending on which logs youre looking for # List of statuses to get the Fax SID for (useful in case you need to contact support) # These will be the only statuses exported to the faxes.csv # AVAILABLE STATUSES: queued, processing, sending, delivered, no-answer, busy, failed, canceled, received, receiving statuses_with_detail = [failed, canceled] ### Data structure preparation Here we create the necessary working lists to which we will be adding data as we iterate through the fax records. We also create the **stats** DataFrame. It is used solely for general stats per number and per status (regardless of the statuses we picked to get more detail on). Lastly, we set some Pandas formatting options that are only used in when printing to the terminal. Their purpose is to center the output for an easier time reading it and for it not to summarize the output until we get to 1000 rows. python # Faxes well need to give more information on and export to CSV faxes_with_detail = [] # Statuses of faxes where FROM matches any of the numbers in the numbers list from_statuses = [] # Statuses of faxes where TO matches any of the numbers in the numbers list to_statuses = [] # Statistics to be printed in the end stats = pd.DataFrame( columns = ( Queued, Processing, Sending, Delivered, No answer, Busy, Failed OUT, Canceled, Received, Receiving, Failed IN), index = numbers) # Statistics formatting options pd.set_option(display.colheader_justify, center) pd.set_option(display.max_rows, 1000) ### Retrieving and processing the fax data This is the most important part of the code, as it iterates through the selected list of numbers and carries on the following actions: 1. Get all faxes between the start and end dates, where the FROM number is the number were currently looking at; 2. Get all faxes between the start and end dates, where the TO number is the number were currently looking at; 3. Go through each of the faxes where the FROM number matches, and add the status to the **from_statuses** list. If the status is one of the ones we specified in **statuses_with_detail**, add the fax information to **faxes_with_detail** to be printed to the terminal and exported to CSV later on; 4. Go through each of the faxes where the TO number matches, and add the status to the **to_statuses** list. If the status is one of the ones we specified in **statuses_with_detail**, add the fax information to **faxes_with_detail** to be printed to the terminal and exported to CSV later on; 5. Add counts of **all** fax status for this particular number to the **stats** DataFrame, to then be printed in table format. python for current_number in numbers: start_datetime = datetime.strptime(start_date, %Y/%m/%d) end_datetime = datetime.strptime(end_date, %Y/%m/%d) # Listing all faxes FROM every number listed from_faxes = client.fax.faxes.list( from_ = current_number, date_created_after = start_datetime, date_created_on_or_before = end_datetime) # Listing all faxes TO every number listed to_faxes = client.fax.faxes.list( to = current_number, date_created_after = start_datetime, date_created_on_or_before = end_datetime) # Handle faxes where there is a FROM match for record in from_faxes: from_statuses.append((record.status)) the_status = record.status if the_status in statuses_with_detail: faxes_with_detail.append((record.from_, record.to, record.status, record.sid)) # Handle faxes where there is a TO match for record in to_faxes: to_statuses.append((record.status)) the_status = record.status if the_status in statuses_with_detail: faxes_with_detail.append((record.from_, record.to, record.status, record.sid)) # Append this numbers statistics stats.loc[current_number,:] = [ from_statuses.count(queued), from_statuses.count(processing), from_statuses.count(sending), from_statuses.count(delivered), from_statuses.count(no-answer), from_statuses.count(busy), from_statuses.count(failed), from_statuses.count(canceled), to_statuses.count(received), to_statuses.count(receiving), to_statuses.count(failed)] from_statuses = [] to_statuses = [] ### Printing the results We prepare the printing of results by creating a DataFrame from the **faxes_with_detail** list, that contains all of our faxes with statuses specified in the **statuses_with_detail** list. The DataFrame resulting from **faxes_with_detail** is printed to the terminal and exported to a CSV file called **faxes.csv**. The **stats** DataFrame (that gives us general stats on all faxes for the numbers we are looking for) is just printed in the terminal, but could also be exported to CSV if intended. python df = pd.DataFrame( faxes_with_detail, columns=( From Number, To Number, Status, Fax SID)) print(df) print(\n) print(stats) df.to_csv( faxes.csv, index = False, encoding = utf-8) Conclusion - Faxes can be unpredictable due to how old the technology is, but with SignalWire you can make using Fax less of a headache. Just in case something does go wrong, this code snippet should help you gather more information on the problematic faxes, and with the Fax SID our Support team will be able to assist you in getting to the bottom of any issues youre running into!