Sending Faxes

Last updated: 2024-01-31Contributors
Edit this page

Faxes remain a key way in which many business and industries share and transmit documents, and is another type of message that can be sent using the RingCentral SMS and Fax API. Using this API, developers can send one or more documents at a time to a single recipient. This for example makes it possible for a developer to attach and transmit a cover page that is stored independently from the core document being transmitted.

The Fax API is different from other RingCentral APIs in that it packages the message and each document as a separate MIME attachment. The root attachment is a JSON object which specifies the recipient(s) of the fax, the fax quality (resolution), the cover page text and other necessary parameters such as a predefined cover page. Subsequent attachments are the documents to be transmitted in sequence. The Fax API accepts both multipart/form-data and multipart/mixed content-type headers.

To send a fax message using the Fax API, you cannot set the "from" phone number. Instead, the server will choose the preselected fax number from your extension outbound Fax settings in your user extension service portal. Therefore, if you need to use your direct number to send Fax messages, login your service Web portal and change your outbound Fax settings.

You can schedule to send a fax by specify the sendTime parameter to a future date and time. If you need to delete/cancel a scheduled fax message, you must keep the fax message id, and use the message id to delete the message from the message store using the delete message API.

RingCentral platform supported FAX content types

Application Type File Extension
Adobe Acrobat / Adobe Reader .pdf
Adobe PhotoShop .psd
Microsoft Word .doc, .docx
Microsoft Word Document Template .dot
Microsoft Word for Mac .mcw
Microsoft Excel .xls, .xlsx, .xlsb
Microsoft PowerPoint .ppt, .pptx
Microsoft Visio .vsd, .vdx
Microsoft Publisher .pub
Microsoft Works .wps
Microsoft Windows Write .wri
Microsoft Fax .awd
Generic Graphic Formats .tif, .tiff, .gif, .jpg, .jpeg, .bmp, .png, .pcx, .tga
Rich Text Format .rtf
Text Files .txt, .log, .h, .cpp, .c, .err, .hpp
Lotus 1-2-3 .wk1, .wk3, .wk4
Quattro Pro DOS .wq1
Extensible Markup Language .xml
Hypertext Markup Language .html, .htm
Comma Separated Values .csv

Attachment Limitations

  • The combined size of all attachments does not exceed 50 MB.
  • The file name of the attached files does not include ampersands (e.g. &) or other special characters such as @#$%^&*, etc...
  • The attachments does not exceed 200 pages.

Transmission speed

The time required for transmitting fax messages depends on the quality and content of the fax that will be sent. For documents that contain mostly text, it usually takes approximately 1 minute per page for the document to be delivered. When sending documents that contain graphics (scanned pages of documents), or for faxes sent to a slow fax line, it may take 5 minutes per page or more to be delivered.

Attaching Documents

Documents being sent via fax can reside on the server's file system and be attached as a local file. For example, in Javascript you can attach a local file in the following manner:

form = new FormData();
form.append('fax-document-1', require('fs').createReadStream('test.pdf'));

For larger files, it may be more economical to stream the file via a URL:

var form = new FormData();
http.request('https://www.ringcentral.com/content/dam/rc-2018/en_us/images/logo.jpg', function(response) {
  form.append('fax-document-1', response);
});

Bear in mind of course that each language will utilize different libraries and capabilities with regards to creating MIME attachments.

Code Samples

The following code samples show how to send a simple single document fax.

Running the code

  • If you have tried the SMS quick start, you can just copy all the functions below and add them to the quick start project then call the send_fax() function. Otherwise, edit the variables in ALL CAPS with your app and user credentials before running the code.
  • If you run on your production account, remember to use app credentials for production and change the RingCentral server URL to "https://platform.ringcentral.com"
const RC = require('@ringcentral/sdk').SDK

// Instantiate the SDK and get the platform instance
var rcsdk = new RC({
    server: "https://platform.devtest.ringcentral.com",
    clientId: "SANDBOX-APP-CLIENTID",
    clientSecret: "SANDBOX-APP-CLIENTSECRET"
});
var platform = rcsdk.platform();

/* Authenticate a user using a personal JWT token */
platform.login({ jwt: "SANDBOX-JWT" })

// For the purpose of testing the code, we put the recipient number in the variable.
// Feel free to set the recipient number directly.
var RECIPIENT = "RECIPIENT-PHONE-NUMBER"

platform.on(platform.events.loginSuccess, function(e){
    send_fax()
});

platform.on(platform.events.loginError, function(e){
    console.log("Unable to authenticate to platform. Check credentials.", e.message)
    process.exit(1)
});

/*
 Send a high resolution fax message to a recipient number
*/
async function send_fax() {
  try {
    var FormData = require('form-data');
    formData = new FormData();
    var bodyParams = {
        to: [{ 'phoneNumber': RECIPIENT }],
        // To send fax to multiple recipients, add more 'phoneNumber' object. E.g.
        /*
        to: [
           { phoneNumber: "Recipient1-Phone-Number" },
           { phoneNumber: "Recipient2-Phone-Number" }
         ],
        */
        faxResolution: 'High',
        coverPageText: "This is a demo Fax page from Node JS"
    }

    formData.append('json', new Buffer.from(JSON.stringify(bodyParams)), {
        filename: 'request.json',
        contentType: 'application/json'
    });

    formData.append('attachment', require('fs').createReadStream('test.jpg'));

    let endpoint = "/restapi/v1.0/account/~/extension/~/fax"
    var resp = await platform.post(endpoint, formData)
    var jsonObj = await resp.json()
    console.log("FAX sent. Message id: " + jsonObj.id)
    check_fax_message_status(jsonObj.id)
  } catch(e) {
    console.log(e.message)
  }
}


/*
 Check the sending message status until it's out of the queued status
*/
async function check_fax_message_status(messageId){
    try {
        let endpoint = `/restapi/v1.0/account/~/extension/~/message-store/${messageId}`
        let resp = await platform.get(endpoint);
        let jsonObj = await resp.json()
        console.log("Message status: ", jsonObj.messageStatus)
        if (jsonObj.messageStatus == "Queued"){
          await sleep (10000);
          check_fax_message_status(jsonObj.id);
        }
    } catch (e) {
      console.log(e.message)
    }
}

const sleep = async (ms) => {
  await new Promise(r => setTimeout(r, ms));
}
import time
from ringcentral import SDK

# Send a high resolution fax message to a recipient number
def send_fax():
    try:
        builder = rcsdk.create_multipart_builder()
        builder.set_body({
            'to': [{ 'phoneNumber': RECIPIENT }],
            # To send fax to multiple recipients, add more 'phoneNumber' object. E.g.
            #
            # to: [
            #       { 'phoneNumber': "Recipient1-Phone-Number" },
            #       { 'phoneNumber': "Recipient2-Phone-Number" }
            # ],
            'faxResolution': "High",
            'coverPageText': "This is a demo Fax page from Python"
        })

        with open('test.jpg', "rb") as f:
            content = f.read()
            attachment = ('test.jpg', content)
            builder.add(attachment)
            request = builder.request('/restapi/v1.0/account/~/extension/~/fax')
        resp = platform.send_request(request)
        jsonObj = resp.json()
        print ("Fax sent. Message id: " + str(jsonObj.id))
        check_fax_message_status(jsonObj.id)
    except Exception as e:
        print (e)


# Check the sending message status until it's no longer in the queued status
def check_fax_message_status(messageId):
    try:
        endpoint = "/restapi/v1.0/account/~/extension/~/message-store/" + str(messageId)
        resp = platform.get(endpoint)
        jsonObj = resp.json()
        print ("Message status: " + jsonObj.messageStatus)
        if jsonObj.messageStatus == "Queued":
            time.sleep(10)
            check_fax_message_status(jsonObj.id)
    except Exception as e:
        print (e)


# Authenticate a user using a personal JWT token
def login():
    try:
      platform.login( jwt=os.environ.get('RC_JWT') )
      send_fax()
    except Exception as e:
      print ("Unable to authenticate to platform. Check credentials." + str(e))

# Instantiate the SDK and get the platform instance
rcsdk = SDK("SANDBOX-APP-CLIENTID", "SANDBOX-APP-CLIENTSECRET", "https://platform.devtest.ringcentral.com")
platform = rcsdk.platform()

login()

# For the purpose of testing the code, we put the recipient number in the variable.
# Feel free to set the recipient number directly.
RECIPIENT = "RECIPIENT-PHONE-NUMBER"
####################################
<?php
require('vendor/autoload.php');

// Instantiate the SDK and get the platform instance
$rcsdk = new RingCentral\SDK\SDK( "SANDBOX-APP-CLIENTID", "SANDBOX-APP-CLIENTSECRET", "https://platform.devtest.ringcentral.com" );
$platform = $rcsdk->platform();

/* Authenticate a user using a personal JWT token */
try {
  $platform->login(["jwt" => "SANDBOX-JWT"]);
}catch (\RingCentral\SDK\Http\ApiException $e) {
  // Getting error messages using PHP native interface
  print 'Expected HTTP Error: ' . $e;
  exit ("Error message: " . $e->apiResponse->response()->error() . PHP_EOL;
}

// For the purpose of testing the code, we put the recipient number in the variable.
// Feel free to set the recipient number directly.
$RECIPIENT = "RECIPIENT-PHONE-NUMBER";

send_fax();

/*
* Send a high resolution fax message to a recipient number
*/
function send_fax(){
  global $platform, $rcsdk, $RECIPIENT;
  try {
    $bodyParams = $rcsdk->createMultipartBuilder()
        ->setBody(array(
          'to' => array(array('phoneNumber' => $RECIPIENT)),
          // To send fax to multiple recipients, add more 'phoneNumber' object. E.g.
          /*
          'to' => array(
             array('phoneNumber' => "Recipient1-Phone-Number"),
             array('phoneNumber' => "Recipient2-Phone-Number")
          ),
          */
          'faxResolution' => "High",
        ))
        ->add(fopen('test.jpg', 'r'))
        ->request('/restapi/v1.0/account/~/extension/~/fax');

    $resp = $platform->sendRequest($bodyParams);
    print_r ("FAX sent. Message id: " . $resp->json()->id);
    check_fax_message_status($resp->json()->id);
  }catch (\RingCentral\SDK\Http\ApiException $e) {
    // Getting error messages using PHP native interface
    print 'Expected HTTP Error: ' . $e;
    print '  Message: ' . $e->apiResponse->response()->error() . PHP_EOL;
  }
}

/*
 Check the sending message status until it's out of the queued status
*/
function check_fax_message_status($messageId){
  global $platform;
  try {
      $endpoint = "/restapi/v1.0/account/~/extension/~/message-store/".$messageId;
      $resp = $platform->get($endpoint);
      $jsonObj = $resp->json();
      print("Message status: " . $jsonObj->messageStatus . PHP_EOL);
      if ($jsonObj->messageStatus == "Queued"){
        sleep(10);
        check_fax_message_status($jsonObj->id);
      }
  } catch (\RingCentral\SDK\Http\ApiException $e) {
    exit("Message: " . $e->message . PHP_EOL);
  }
}
?>
require 'ringcentral'

# Send a high resolution fax message to a recipient number
def send_fax()
  begin
    bodyParams = {
      to: [{ phoneNumber: RECIPIENT }],
      # To send fax to multiple recipients, add more 'phoneNumber' object. E.g.
      #
      # to: [
      #       { phoneNumber: "Recipient1-Phone-Number" },
      #       { phoneNumber: "Recipient2-Phone-Number" }
      # ],
      faxResolution: "High",
      coverPageText: "This is a demo Fax page from Ruby"
    }
    files = [
              ['test.jpg', 'image/jpeg']
            ]

    endpoint =  "/restapi/v1.0/account/~/extension/~/fax"
    resp = $platform.post(endpoint, payload: bodyParams, files: files)
    puts ("Fax sent. Message id: " + resp.body['id'].to_s)
    check_fax_message_status(resp.body['id'])
  rescue StandardError => e
    puts (e)
  end
end

# Check the sending message status until it's out of the queued status
def check_fax_message_status(messageId)
  begin
    endpoint = "/restapi/v1.0/account/~/extension/~/message-store/" + messageId.to_s
    resp = $platform.get(endpoint)
    puts ("Message status: " + resp.body['messageStatus'])
    if (resp.body['messageStatus'] == "Queued")
      sleep(10)
      check_fax_message_status(resp.body['id'])
    end
  rescue StandardError => e
    puts (e)
  end
end

# Authenticate a user using a personal JWT token
def login()
  begin
    $platform.authorize( jwt: "SANDBOX_JWT" )
    send_fax()
  rescue StandardError => e
    puts ("Unable to authenticate to platform. Check credentials." + e.to_s)
  end
end

# Instantiate the SDK and get the platform instance
$platform = RingCentral.new( "SANDBOX-APP-CLIENTID", "SANDBOX-APP-CLIENTSECRET", "https://platform.devtest.ringcentral.com" )

login()

# For the purpose of testing the code, we put the recipient number in the variable.
# Feel free to set the recipient number directly.
RECIPIENT = "RECIPIENT-PHONE-NUMBER"
####################################
using System;
using System.Threading.Tasks;
using RingCentral;

namespace Send_Fax
{
    class Program
    {
        static RestClient restClient;
        static string RECIPIENT = "RECIPIENT-PHONE-NUMBER";
        static async Task Main(string[] args)
        {
          try
          {
            // Instantiate the SDK
            restClient = new RestClient( "SANDBOX-APP-CLIENTID", "SANDBOX-APP-CLIENTSECRET", "https://platform.devtest.ringcentral.com");

            // Authenticate a user using a personal JWT token
            await restClient.Authorize("SANDBOX_JWT");
            await send_fax();
          }
          catch (Exception ex)
          {
            Console.WriteLine(ex.Message);
          }
        }

        /*
         Send a high resolution fax message to a recipient number
        */
        static private async Task send_fax()
        {
          try
          {
            var bodyParams = new CreateFaxMessageRequest();

            bodyParams.to = new FaxReceiver[] { new FaxReceiver { phoneNumber = RECIPIENT } };
            // To send fax to multiple recipients, add more 'phoneNumber' object. E.g.
            /*
            bodyParams.to = new FaxReceiver[] {
                new FaxReceiver { phoneNumber = "Recipient1-Phone-Number" },
                new FaxReceiver { phoneNumber = "Recipient1-Phone-Number" }
            };
            */
            bodyParams.faxResolution = "High";
            bodyParams.coverPageText = "This is a demo Fax page from C#";
            // Make sure you have the test.pdf file saved within the project location.
            // Otherwise, change the location path and file name accordingly
            var attachment = new Attachment { filename = "test.pdf", contentType = "application/pdf", content = System.IO.File.ReadAllBytes("test.pdf") };
            var attachments = new Attachment[] { attachment };
            bodyParams.attachments = attachments;

            var resp = await restClient.Restapi().Account().Extension().Fax().Post(bodyParams);
            Console.WriteLine("Fax sent. Message id: " + resp.id);
            await check_fax_message_status(resp.id.ToString());
          }
          catch (Exception ex)
          {
            Console.WriteLine(ex.Message);
          }
        }

        /*
         Check the sending message status until it's no longer in the queued status
        */
        static private async Task check_fax_message_status(string messageId)
        {
            try
            {
                var resp = await restClient.Restapi().Account().Extension().MessageStore(messageId).Get();
                Console.WriteLine("Message status: " + resp.messageStatus);
                if (resp.messageStatus == "Queued")
                {
                    Thread.Sleep(10000);
                    await check_fax_message_status(resp.id.ToString());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}
package Send_Fax;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import com.ringcentral.*;
import com.ringcentral.definitions.*;

public class Send_Fax {
    static String RECIPIENT = "RECIPIENT-PHONE-NUMBER";
    static RestClient restClient;

    public static void main(String[] args) {
      // Instantiate the SDK
      restClient = new RestClient( "SANDBOX-APP-CLIENTID", "SANDBOX-APP-CLIENTSECRET", "https://platform.devtest.ringcentral.com");
      var obj = new Send_Fax();
      try {
        // Authenticate a user using a personal JWT token
        restClient.authorize( "SANDBOX_JWT" );
        obj.send_fax();
      } catch (RestException | IOException e) {
        e.printStackTrace();
      }
    }
    /*
     Send a high resolution fax message to a recipient number
    */
    public static void send_fax() throws RestException, IOException{
      try {
        CreateFaxMessageRequest bodyParams = new CreateFaxMessageRequest();
        bodyParams.to = new FaxReceiver[]{
          new FaxReceiver().phoneNumber(RECIPIENT)
        };
        // To send fax to multiple recipients, add more 'phoneNumber' object. E.g.
        /*
        bodyParams.to = new FaxReceiver[] {
          new FaxReceiver().phoneNumber("Recipient1-Phone-Number"),
          new FaxReceiver().phoneNumber("Recipient2-Phone-Number")
        };
        */
        bodyParams.faxResolution = "High";
        bodyParams.coverPageText = "Send Fax from Java app.";

        // Make sure you have the test.pdf file saved under the specified location below.
        // Otherwise, change the location path and file name accordingly
        Attachment attachment = new Attachment()
                    .filename("test.pdf")
                    .contentType("application/pdf")
                    .content(Files.readAllBytes(Paths.get("./src/test/resources/test.pdf")));

        Attachment[] attachments = new Attachment[] { attachment };
        bodyParams.attachments = attachments;

        var response = restClient.restapi().account().extension().fax().post(bodyParams);
        System.out.println("Fax sent. Message id: " + response.id.toString());
        check_fax_message_status(response.id.toString());
      } catch(RestException e) {
        System.out.println(e.getMessage());
      }
    }
    /*
      Check the sending message status until it's no longer in the queued status
    */
    private void check_fax_message_status(String messageId) throws IOException {
      try {
        var resp = restClient.restapi().account().extension().messageStore(messageId).get();
        System.out.println("Message status: " + resp.messageStatus);
        if (resp.messageStatus.equals("Queued")) {
          try {
            Thread.sleep(10000);
            check_fax_message_status(resp.id.toString());
          } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println(e);
          }
        }
      } catch (RestException e) {
        System.out.println(e.getMessage());
      }
    }
}