Twilio Programmable Fax Quickstart - Send and Receive Faxes - Twilio
Register for SIGNAL by 8/31 for $250 off. Register now.

Programmable Fax Quickstart

Twilio's Programmable Fax lets you send, receive, and manage faxes in your web applications with just a few lines of code.

This Python SMS Quickstart will teach you the basics of fax using our Communications REST API and either cURL or your choice of language helper library. This quickstart includes detailed instructions for those helper libraries in your choice of Python, PHP, C#, Node.js, Java, and Ruby.

In this Quickstart, you will learn how to:

  1. Sign up for Twilio and get your first Fax-enabled Twilio phone number
  2. Set up your development environment to send and receive faxes
  3. Send your first fax
  4. Receive an incoming fax

Let's get started!

Getting Started

Before you can commence world domination via facsimile, you'll need to own a Twilio phone number capable of sending and receiving faxes. In the Twilio Console (sign up for a Twilio account if you haven't already), you can search for phone numbers capable of sending and receiving faxes.

Search for fax numbers

Buy a number from the list by clicking the "Buy" button.

Buy Fax-enabled number

Now that you have a fax-capable number, let's look at how we can send faxes using the REST API.

Send a fax

Sending a fax requires a Twilio Account SID and Auth Token. You can find your credentials on the Console dashboard. Your API request will use these credentials for HTTP basic authentication. There are three parameters that you must also pass along with your request.

  1. From - the Twilio number the fax will be sent from. Use the one you bought in the console before.
  2. To - the number you'd like to send the fax to.
  3. MediaUrl - a fully qualified URL to a PDF document you'd like to send as the content for a fax.

Note: You should pass your phone numbers to the API in the E.164 format. For our cURL example we manually encoded the "+" sign at the beginning of each phone number to its encoded value, "%2B".

Another Note: Please make sure you are using the latest version of your favorite language's Twilio helper library.

Loading Code Samples...
Language
SDK Version:
  • 5.x
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// Download the helper library from https://www.twilio.com/docs/node/install
// Your Account Sid and Auth Token from twilio.com/console
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.fax.faxes
  .create({
     from: '+15017122661',
     to: '+15558675310',
     mediaUrl: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf'
   })
  .then(fax => console.log(fax.sid))
  .done();
// Install the C# / .NET helper library from twilio.com/docs/csharp/install

using System;
using Twilio;
using Twilio.Rest.Fax.V1;


class Program 
{
    static void Main(string[] args)
    {
        // Find your Account Sid and Token at twilio.com/console
        const string accountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        const string authToken = "your_auth_token";

        TwilioClient.Init(accountSid, authToken);

        var fax = FaxResource.Create(
            from: "+15017122661",
            to: "+15558675310",
            mediaUrl: new Uri("https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf")
        );

        Console.WriteLine(fax.Sid);
    }
}
<?php

// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once '/path/to/vendor/autoload.php';

use Twilio\Rest\Client;

// Find your Account Sid and Auth Token at twilio.com/console
$sid    = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$token  = "your_auth_token";
$twilio = new Client($sid, $token);

$fax = $twilio->fax->v1->faxes
                       ->create("+15558675310", // to
                                "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf", // mediaUrl
                                array("from" => "+15017122661")
                       );

print($fax->sid);
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Your Account Sid and Auth Token from twilio.com/console
account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
auth_token = 'your_auth_token'
@client = Twilio::REST::Client.new(account_sid, auth_token)

fax = @client.fax.faxes
  .create(
     from: '+15017122661',
     to: '+15558675310',
     media_url: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf'
   )

puts fax.sid
# Download the helper library from https://www.twilio.com/docs/python/install
from twilio.rest import Client


# Your Account Sid and Auth Token from twilio.com/console
account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
auth_token = 'your_auth_token'
client = Client(account_sid, auth_token)

fax = client.fax.faxes \
    .create(
         from_='+15017122661',
         to='+15558675310',
         media_url='https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf'
     )

print(fax.sid)
// Install the Java helper library from twilio.com/docs/java/install

import com.twilio.Twilio;
import com.twilio.rest.fax.v1.Fax;

import java.net.URI;

public class Example {
    // Find your Account Sid and Token at twilio.com/console
    public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    public static final String AUTH_TOKEN = "your_auth_token";

    public static void main(String[] args) {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
        Fax fax = Fax.creator(
                "+15558675310",
                URI.create("https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf"))
            .setFrom("+15017122661").create();

        System.out.println(fax.getSid());
    }
}
curl -X POST https://fax.twilio.com/v1/Faxes \
--data-urlencode "From=+15017122661" \
--data-urlencode "To=+15558675310" \
--data-urlencode "MediaUrl=https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf" \
-u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token
{
  "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "api_version": "v1",
  "date_created": "2015-07-30T20:00:00Z",
  "date_updated": "2015-07-30T20:00:00Z",
  "direction": "outbound",
  "from": "+15017122661",
  "media_url": "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf",
  "media_sid": "MEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "num_pages": null,
  "price": null,
  "price_unit": null,
  "quality": "superfine",
  "sid": "FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "status": "queued",
  "to": "+15558675310",
  "duration": null,
  "links": {
    "media": "https://fax.twilio.com/v1/Faxes/FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Media"
  },
  "url": "https://fax.twilio.com/v1/Faxes/FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
Code to send a fax with cURL or your choice of web language.
Send an outbound fax

Code to send a fax with cURL or your choice of web language.

Within moments of running the above code, your fax should be happily on its way to a lucky recipient. To get updated on the status of the fax (including when sending failed), you can specify a StatusCallback parameter in your request to provide a URL which will be requested when the status of an outbound fax changes.

Receive faxes in your web application

When your Twilio number receives an incoming fax, Twilio will send an HTTP request to a server you control. This callback mechanism is known as a webhook.  When Twilio sends your application a request, it expects a response in the TwiML XML format telling it how to respond to the message. 

Here's an example of a simple web application set up to receive a fax demonstrating our helper libraries in a variety of web languages.

Loading Code Samples...
Language
SDK Version:
  • 5.x
SDK Version:
  • 7.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 4.x
require 'rubygems'
require 'sinatra'

# Define a handler for when the fax is initially sent
post '/fax/sent' do
  # Let's manually build some TwiML. We can choose to receive the
  # fax with <Receive>, or reject with <Reject>.
  content_type 'text/xml'

  <<-TWIML
    <Response>
        <Receive action="/fax/received"/>
    </Response>'
    TWIML
end

# Define a handler for when the fax is finished sending to us - if successful,
# We will have a URL to the contents of the fax at this point
post '/fax/received' do
  # log the URL of the PDF received in the fax
  logger.info(params['MediaUrl'])

  # Respond with empty 200/OK to Twilio
  status 200
  body ''
end
using System.Web.Mvc;

namespace TwilioFax.Web.Controllers
{
    public class FaxController : Controller
    {
        // Define a handler for when the fax is initially sent
        [HttpPost]
        public ActionResult Sent()
        {
            // Let's manually build some TwiML. We can choose to receive the
            // fax with <Receive>, or reject with <Reject>.
            const string xmlString = "<Response>" +
                                        "<Receive action =\"/fax/received\"/>" +
                                      "</Response>";

            return this.Content(xmlString, "text/xml");
        }

        // Define a handler for when the fax is finished sending to us - if successful,
        // We will have a URL to the contents of the fax at this point
        [HttpPost]
        public ActionResult Received()
        {
            // log the URL of the PDF received in the fax
            System.Diagnostics.Debug.WriteLine(Request["MediaUrl"]);

            // Respond with empty 200/OK to Twilio
            return new EmptyResult();
        }
    }
}
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class FaxController extends Controller {

    public function __construct()
    {
        parent::__construct();

        // set content-type for all requests returned by this controller
        $this->set_output->set_content_type('text/xml');
    }

    // Define a handler for when the fax is initially sent
    public function sent()
    {
        $twimlResponse = new SimpleXMLElement("<Response></Response>");
        $receiveEl = $twimlResponse->addChild('Receive');
        $receiveEl->addAttribute('action', '/fax/received');

        $this->output->set_output($twimlResponse->asXML());
    }

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    public function received()
    {
        // log the URL of the PDF received in the fax
        log_message('info', $this->input->post("MediaUrl"));

        // Respond with empty 200/OK to Twilio
        $this->set_status_header(200);
        $this->output->set_output('');
    }
}
#!/usr/bin/env python
"""Fax snippet."""

from flask_script import Manager
from flask import Flask, Response, request

app = Flask(__name__)


@app.route('/fax/sent', methods=['POST'])
def fax_sent():
    """Define a handler for when the fax is initially sent."""
    # Let's manually build some TwiML. We can choose to receive the
    # fax with <Receive>, or reject with <Reject>.
    twiml = """
        <Response>
            <Receive action="/fax/received"/>
        </Response>
    """

    return Response(twiml, mimetype='text/xml')


@app.route('/fax/received', methods=['POST'])
def fax_received():
    """Define a handler for when the fax finished sending to us."""
    # We will have a URL to the contents of the fax at this point
    # log the URL of the PDF received in the fax
    print(request.form.get('MediaUrl'))

    # Respond with empty 200/OK to Twilio
    return '', 200


if __name__ == "__main__":
    Manager(app).run()
import spark.Route;

import static spark.Spark.post;

public class IndexFax {

    private static Route faxSent = (request, response) -> {
        // Let's manually build some TwiML. We can choose to receive the
        // fax with <Receive>, or reject with <Reject>.
        String twiml = "<Response>" +
                            "<Receive action=\"/fax/received\"/>" +
                        "</Response>";

        // Send Fax twiml response
        response.type("text/xml");
        return twiml;
    };

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    private static Route faxReceived  = (request, response) -> {
        // log the URL of the PDF received in the fax
        System.out.println(request.params(":mediaUrl"));

        // Respond with empty 200/OK to Twilio
        response.status(200);
        return null;
    };

    public static void main(String[] args) {
        post("/fax/sent", faxSent);

        post("/fax/received", faxReceived);
    }
}
const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

// Parse any incoming POST parameters
app.use(bodyParser({ extended: false }));

// Define a handler for when the fax is initially sent
app.post('/fax/sent', (req, res) => {
  // Let's manually build some TwiML. We can choose to receive the
  // fax with <Receive>, or reject with <Reject>.
  const twiml = `
  <Response>
    <Receive action="/fax/received"/>
  </Response>
  `;

  // Send Fax twiml response
  res.type('text/xml');
  res.send(twiml);
});

// Define a handler for when the fax is finished sending to us - if successful,
// We will have a URL to the contents of the fax at this point
app.post('/fax/received', (req, res) => {
  // log the URL of the PDF received in the fax
  console.log(req.body.MediaUrl);

  // Respond with empty 200/OK to Twilio
  res.status(200);
  res.send();
});

// Start the web server
http.createServer(app).listen(3000, () => {
  console.log('Express server listening on port 3000');
});
testable: false
Code to receive an incoming fax with a selection of languages and web frameworks.
Receive an incoming fax

Code to receive an incoming fax with a selection of languages and web frameworks.

There are two routes you'll probably need in your application:

  1. One to return TwiML when the fax is initially sent to your number
  2. A second when the fax has completed sending

Before we can start directing Twilio how to handle our faxes, 

Chances are that during development, you'll be running this code on localhost. Unfortunately, Twilio can't directly call a server running on your computer - you'll either need to deploy this code to a public server, or run a tunnel such as ngrok that provides an externally accessible URL. We'll show you how to set that up next.

Allow Twilio to talk to your web application

If you haven't already, install ngrok and ensure the ngrok command is on your system path (or runnable on your Windows machine).

The following command would use ngrok to expose port 3000 to the public Internet from the command line in Mac OSX or a *NIX flavor. Replace 3000 with whatever port number you're using to run your web application.

ngrok http 3000

Next, you'll see a screen similar to the following:

ngrok terminal output

Now we have a new external URL, visibly on the public internet.

Configure this address as the webhook for one of your phone numbers in the console. Select your phone number of choice then change the "A FAX COMES IN" field to the external URL to your service. For example in this case: https://sadfs3423.ngrok.io/fax/sent.

Fax webhook configuration

Now, you're all wired up - time to try it out...

Send a fax to your Twilio phone number – if you're watching ngrok, you should see a pair of HTTP requests in the ngrok console. If everything worked, you should have printed the URL of a PDF containing your inbound fax to the console.

Next steps

Now that you understand the basics of sending and receiving faxes, you can check out the Fax REST API reference, or dive deeper into TwiML and webhooks to understand the lifecycle of receiving faxes via HTTP requests.

Happy faxing!

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.

Loading Code Samples...
SDK Version:
  • 5.x
Response Format:
  • json
SDK Version:
  • 7.x
SDK Version:
  • 3.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 5.x
Format:
  • JSON
// Download the helper library from https://www.twilio.com/docs/node/install
// Your Account Sid and Auth Token from twilio.com/console
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.fax.faxes
  .create({
     from: '+15017122661',
     to: '+15558675310',
     mediaUrl: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf'
   })
  .then(fax => console.log(fax.sid))
  .done();
// Install the C# / .NET helper library from twilio.com/docs/csharp/install

using System;
using Twilio;
using Twilio.Rest.Fax.V1;


class Program 
{
    static void Main(string[] args)
    {
        // Find your Account Sid and Token at twilio.com/console
        const string accountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        const string authToken = "your_auth_token";

        TwilioClient.Init(accountSid, authToken);

        var fax = FaxResource.Create(
            from: "+15017122661",
            to: "+15558675310",
            mediaUrl: new Uri("https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf")
        );

        Console.WriteLine(fax.Sid);
    }
}
<?php

// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once '/path/to/vendor/autoload.php';

use Twilio\Rest\Client;

// Find your Account Sid and Auth Token at twilio.com/console
$sid    = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$token  = "your_auth_token";
$twilio = new Client($sid, $token);

$fax = $twilio->fax->v1->faxes
                       ->create("+15558675310", // to
                                "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf", // mediaUrl
                                array("from" => "+15017122661")
                       );

print($fax->sid);
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'

# Your Account Sid and Auth Token from twilio.com/console
account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
auth_token = 'your_auth_token'
@client = Twilio::REST::Client.new(account_sid, auth_token)

fax = @client.fax.faxes
  .create(
     from: '+15017122661',
     to: '+15558675310',
     media_url: 'https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf'
   )

puts fax.sid
# Download the helper library from https://www.twilio.com/docs/python/install
from twilio.rest import Client


# Your Account Sid and Auth Token from twilio.com/console
account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
auth_token = 'your_auth_token'
client = Client(account_sid, auth_token)

fax = client.fax.faxes \
    .create(
         from_='+15017122661',
         to='+15558675310',
         media_url='https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf'
     )

print(fax.sid)
// Install the Java helper library from twilio.com/docs/java/install

import com.twilio.Twilio;
import com.twilio.rest.fax.v1.Fax;

import java.net.URI;

public class Example {
    // Find your Account Sid and Token at twilio.com/console
    public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    public static final String AUTH_TOKEN = "your_auth_token";

    public static void main(String[] args) {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
        Fax fax = Fax.creator(
                "+15558675310",
                URI.create("https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf"))
            .setFrom("+15017122661").create();

        System.out.println(fax.getSid());
    }
}
curl -X POST https://fax.twilio.com/v1/Faxes \
--data-urlencode "From=+15017122661" \
--data-urlencode "To=+15558675310" \
--data-urlencode "MediaUrl=https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf" \
-u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token
{
  "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "api_version": "v1",
  "date_created": "2015-07-30T20:00:00Z",
  "date_updated": "2015-07-30T20:00:00Z",
  "direction": "outbound",
  "from": "+15017122661",
  "media_url": "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf",
  "media_sid": "MEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "num_pages": null,
  "price": null,
  "price_unit": null,
  "quality": "superfine",
  "sid": "FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "status": "queued",
  "to": "+15558675310",
  "duration": null,
  "links": {
    "media": "https://fax.twilio.com/v1/Faxes/FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Media"
  },
  "url": "https://fax.twilio.com/v1/Faxes/FXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
SDK Version:
  • 5.x
SDK Version:
  • 7.x
SDK Version:
  • 5.x
SDK Version:
  • 6.x
SDK Version:
  • 4.x
require 'rubygems'
require 'sinatra'

# Define a handler for when the fax is initially sent
post '/fax/sent' do
  # Let's manually build some TwiML. We can choose to receive the
  # fax with <Receive>, or reject with <Reject>.
  content_type 'text/xml'

  <<-TWIML
    <Response>
        <Receive action="/fax/received"/>
    </Response>'
    TWIML
end

# Define a handler for when the fax is finished sending to us - if successful,
# We will have a URL to the contents of the fax at this point
post '/fax/received' do
  # log the URL of the PDF received in the fax
  logger.info(params['MediaUrl'])

  # Respond with empty 200/OK to Twilio
  status 200
  body ''
end
using System.Web.Mvc;

namespace TwilioFax.Web.Controllers
{
    public class FaxController : Controller
    {
        // Define a handler for when the fax is initially sent
        [HttpPost]
        public ActionResult Sent()
        {
            // Let's manually build some TwiML. We can choose to receive the
            // fax with <Receive>, or reject with <Reject>.
            const string xmlString = "<Response>" +
                                        "<Receive action =\"/fax/received\"/>" +
                                      "</Response>";

            return this.Content(xmlString, "text/xml");
        }

        // Define a handler for when the fax is finished sending to us - if successful,
        // We will have a URL to the contents of the fax at this point
        [HttpPost]
        public ActionResult Received()
        {
            // log the URL of the PDF received in the fax
            System.Diagnostics.Debug.WriteLine(Request["MediaUrl"]);

            // Respond with empty 200/OK to Twilio
            return new EmptyResult();
        }
    }
}
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class FaxController extends Controller {

    public function __construct()
    {
        parent::__construct();

        // set content-type for all requests returned by this controller
        $this->set_output->set_content_type('text/xml');
    }

    // Define a handler for when the fax is initially sent
    public function sent()
    {
        $twimlResponse = new SimpleXMLElement("<Response></Response>");
        $receiveEl = $twimlResponse->addChild('Receive');
        $receiveEl->addAttribute('action', '/fax/received');

        $this->output->set_output($twimlResponse->asXML());
    }

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    public function received()
    {
        // log the URL of the PDF received in the fax
        log_message('info', $this->input->post("MediaUrl"));

        // Respond with empty 200/OK to Twilio
        $this->set_status_header(200);
        $this->output->set_output('');
    }
}
#!/usr/bin/env python
"""Fax snippet."""

from flask_script import Manager
from flask import Flask, Response, request

app = Flask(__name__)


@app.route('/fax/sent', methods=['POST'])
def fax_sent():
    """Define a handler for when the fax is initially sent."""
    # Let's manually build some TwiML. We can choose to receive the
    # fax with <Receive>, or reject with <Reject>.
    twiml = """
        <Response>
            <Receive action="/fax/received"/>
        </Response>
    """

    return Response(twiml, mimetype='text/xml')


@app.route('/fax/received', methods=['POST'])
def fax_received():
    """Define a handler for when the fax finished sending to us."""
    # We will have a URL to the contents of the fax at this point
    # log the URL of the PDF received in the fax
    print(request.form.get('MediaUrl'))

    # Respond with empty 200/OK to Twilio
    return '', 200


if __name__ == "__main__":
    Manager(app).run()
import spark.Route;

import static spark.Spark.post;

public class IndexFax {

    private static Route faxSent = (request, response) -> {
        // Let's manually build some TwiML. We can choose to receive the
        // fax with <Receive>, or reject with <Reject>.
        String twiml = "<Response>" +
                            "<Receive action=\"/fax/received\"/>" +
                        "</Response>";

        // Send Fax twiml response
        response.type("text/xml");
        return twiml;
    };

    // Define a handler for when the fax is finished sending to us - if successful,
    // We will have a URL to the contents of the fax at this point
    private static Route faxReceived  = (request, response) -> {
        // log the URL of the PDF received in the fax
        System.out.println(request.params(":mediaUrl"));

        // Respond with empty 200/OK to Twilio
        response.status(200);
        return null;
    };

    public static void main(String[] args) {
        post("/fax/sent", faxSent);

        post("/fax/received", faxReceived);
    }
}
const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

// Parse any incoming POST parameters
app.use(bodyParser({ extended: false }));

// Define a handler for when the fax is initially sent
app.post('/fax/sent', (req, res) => {
  // Let's manually build some TwiML. We can choose to receive the
  // fax with <Receive>, or reject with <Reject>.
  const twiml = `
  <Response>
    <Receive action="/fax/received"/>
  </Response>
  `;

  // Send Fax twiml response
  res.type('text/xml');
  res.send(twiml);
});

// Define a handler for when the fax is finished sending to us - if successful,
// We will have a URL to the contents of the fax at this point
app.post('/fax/received', (req, res) => {
  // log the URL of the PDF received in the fax
  console.log(req.body.MediaUrl);

  // Respond with empty 200/OK to Twilio
  res.status(200);
  res.send();
});

// Start the web server
http.createServer(app).listen(3000, () => {
  console.log('Express server listening on port 3000');
});
testable: false