# Getting started

This guide will instruct you on how to get started using the Fax API. Before you can start sending and receiving faxes, you need to complete some basic configuration steps.

Let's get started!

Account required!
Using the Fax API requires [signing up for a free account](https://community.sinch.com/t5/Customer-Dashboard/How-to-sign-up-for-your-free-Sinch-account/ta-p/8058) on the Sinch Build Dashboard. If you haven't already done so, [sign up now](https://dashboard.sinch.com/signup)!

## 1. Get your Project ID and credentials

**Get your project ID and create your access key:** First, you'll need your project ID and to generate access keys. Access keys are used to authenticate calls when using Fax API. You can generate access keys and find your project ID in the [Sinch Build Dashboard](https://dashboard.sinch.com/settings/access-keys).

You'll need this info later!
Make sure you have your access key, access key secret, and project ID readily available. This information will be required when making the API call to send the text message. The access key and access key secret must be recorded during access key creation. The project ID can be found on the Sinch Build Dashboard's [Project Settings](https://dashboard.sinch.com/settings/project-settings) page.

Important!
The client ID will be readily visible. The secret ID, however, will only be visible upon new key creation. Create a new key and then save your secret ID in a safe place.

You will need both the client ID and the client secret for most endpoints in the Fax API.

## 2. Get a number

**Get your free Sinch testing number.** When you sign up for a Sinch Build Dashboard account, you get a free virtual number for testing. You must activate your test number before you can use it. To activate your number, simply click the [link](https://dashboard.sinch.com/numbers/buy-numbers?show=get-test-number&redirect=numbers/overview).

To send and receive faxes, you must have a Sinch number assigned to your [default Fax service](https://dashboard.sinch.com/fax/services).

To configure it to use with the Fax API, in your [dashboard](https://dashboard.sinch.com/numbers/your-numbers) select the number you want and under the **Voice Configuration** section ensure you have selected **Fax**.

Note:
While only one number is required, if you will have multiple services, we recommend having a number assigned to each service and set that number as the default number for that service.

## 3. Send a fax

Now you're ready to start sending faxes with the API.

The payload, along with instructions on how to populate placeholder variables, is below. Alternatively, each tab features a guide that will walk you through setting up a simple application in the identified coding language (make sure you bring all the information you gathered during this process!):

CLI
### Send a fax using the Sinch CLI

The Sinch CLI is the easiest way to send a fax using the Fax API.

Prerequisites
You'll need Node.js and NPM installed first!

1. Install the [Sinch CLI](/docs/functions/cli/installation) with the following command:

```shell
npm install -g @sinch/cli
```
2. Next, create the authentication config files for the CLI using the following command:

```shell
sinch auth login
```
You will be prompted to enter your Project ID, Access Key and Access Secret.
3. Now you're ready to send a fax. Enter the following command:

```shell
sinch fax send --to <your_fax_number> --file <path/to/file>
```
Change `your_fax_number>` to the E.164 phone number to which you want to send the fax, and change `<path/to/file>` to the file you want to send. You should receive a fax to the number you specified.


Payload
The payload to send a fax is below:

```json Payload
{
  "to": "YOUR_fax_number",
  "contentUrl": "https://developers.sinch.com/fax/fax.pdf"
}
```

This payload sends a sample PDF to the specified number. The placeholder values included in the payload above are detailed in the table below:

| Placeholder value | Your value |
|  --- | --- |
| YOUR_fax_number | This is a number you own that can receive faxes. Make sure it's in E.164 format with the leading `+`. |


If you already have experience making API calls, you could create a simple app that sends the fax in your preferred coding language, or even make a simple cURL command. Use the payload to make a `POST` API call to `https://fax.api.sinch.com/v3/projects/{projectId}/faxes`, where `{projectId}` is replaced with your project ID. Include authentication information in the header. Since this guide is intended for testing purposes, you can use your application key and application secret to authenticate using [basic authentication](/docs/fax/api-reference/authentication/basic), but for production we recommend using a stronger method of authentication, like [OAuth 2.0](/docs/fax/api-reference/authentication/oauth).

Node.js
### Send a fax with Node.js

You can quickly see how the Fax API works by sending yourself a fax using the Fax API and Node.js SDK.

Note:
Before you can get started, you need the following already set up:

- [NPM](https://www.npmjs.com/) and a familiarity with how to install packages.
- [Node.js](https://nodejs.org/en/) and a familiarity with how to create a new app.


#### Set up your Node.js application

To quickly get started setting up a simple client application using the Node SDK:

1. If you haven't already, clone the [sinch-sdk-node](https://github.com/sinch/sinch-sdk-node) repository.
2. Navigate to the `examples/getting-started/fax/send-fax/` folder.
3. Open a command prompt or terminal and run the following command to install the necessary dependencies:

```shell
npm install
```
4. Rename the `.env.example` [file](https://github.com/sinch/sinch-sdk-node/blob/main/examples/getting-started/fax/send-fax/.env.example) to `.env`. Using the [access key credentials](https://dashboard.sinch.com/settings/access-keys) from your Sinch Build Dashboard, populate the following fields with your values:
| Field | Description |
|  --- | --- |
| SINCH_PROJECT_ID | The unique ID of your Project. |
| SINCH_KEY_ID | The unique ID of your access key. |
| SINCH_KEY_SECRET | The secret that goes with your access key.  **Note:** For security reasons, this secret is only visible right after access key creation. |
5. Save the file.
6. Navigate to `examples/getting-started/fax/send-fax/src/fax/faxSample.js`.


faxSample.js
```javascript faxSample.js
//This code sends a fax to a specified number. 
/**
 * Class to send a demo fax using the Sinch Node.js SDK.
 */
export class FaxSample {
  /**
   * @param { import('@sinch/sdk-core').FaxService } faxService - the FaxService instance from the Sinch SDK containing the API methods.
   */
  constructor(faxService) {
    this.faxService = faxService;
  }

  async start() {
    const recipient = 'YOUR_FAX_NUMBER';
    const contentUrl = 'https://developers.sinch.com/fax/fax.pdf';
    const callbackUrl = 'FAX_CALLBACK_URL';

    const response = await this.faxService.faxes.send({
      sendFaxRequestBody: {
        to: recipient,
        contentUrl,
        ...(callbackUrl !== 'FAX_CALLBACK_URL' && { callbackUrl }),
      },
    });

    const fax = response[0];
    console.log('Fax ID:', fax.id);
    console.log('Status:', fax.status);
    console.log('Response:', response);
  }
}
```

1. The code provided in **faxSample.js** includes placeholder values. Replace the value of the following parameters with your own values:


| Parameter | Your value |
|  --- | --- |
| `recipient` | The phone number you assigned to your Fax service in your [dashboard](https://dashboard.sinch.com) in [E.164](https://community.sinch.com/t5/Glossary/E-164/ta-p/7537) format. |


1. Save the file.


### Run the code to send a fax using the Node.js SDK

Now open a terminal to `examples/getting-started/fax/send-fax/` and you can run the code with the following command:

```Shell
npm start
```

This code will send a fax to the recipient number you configured.

Java
### Send a fax with Java

You can quickly see how the Fax API works by sending yourself a fax using the Fax API.

Before you can get started, you need the following already set up:

* [JDK 8](https://www.oracle.com/java/technologies/downloads/) or later and a familiarity with how to create a new Java application.
* [Gradle](https://gradle.org/install/) and a familiarity with how use the Gradle build tools.


#### Set up your Java application

Create a new folder where you want to keep your app project. Then, open a terminal or command prompt to that location.

Create a new Java application using Gradle with the following command:

```shell
gradle init
```

In the prompts, select that you want to create an application, name your project and source package `app`, and then accept the defaults for the rest of the options.

#### Modify your application

Open the `App.java` file in your project folder, located in `\app\scr\main\java\app`, and populate that file with the "App.java" code found on this page.

App.java
```java App.java
package app;

import java.net.*;
import java.net.http.*;
import java.util.*;

public class App {
  private static final String key = "YOUR_access_id";
  private static final String secret = "YOUR_access_secret";
  private static final String projectId = "YOUR_project_id";
  private static final String to = "YOUR_to_number";
  private static final String contentUrl = "YOUR_content_url";
  private static final String callbackUrl = "YOUR_callback_url";

  public static void main(String[] args) throws Exception {
    var httpClient = HttpClient.newBuilder().build();

    var payload = String.join("\n"
      , "{"
      , "  \"to\": \"" + to + "\","
      , "  \"contentUrl\":" + contentUrl + "\","
      , "  \"callbackUrl\":" + callbackUrl + "\""
      , "}"
    );

    var host = "https://fax.api.sinch.com/v3/projects/" + projectId;
    var pathname = "/faxes";
    var request = HttpRequest.newBuilder()
      .POST(HttpRequest.BodyPublishers.ofString(payload))
      .uri(URI.create(host + pathname ))
      .header("Content-Type", "application/json")
      .header("Authorization", "Basic " + Base64.getEncoder().encodeToString((key + ":" + secret).getBytes()))
      .build();

    var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

    System.out.println(response.body());
  }
}
```

This code sends a fax to a specified number using the Sinch Fax API.

#### To

In this example you want to fax a phone number. Change the value of the `to` parameter to the phone number you verified in your [dashboard](https://dashboard.sinch.com) in [E.164](https://community.sinch.com/t5/Glossary/E-164/ta-p/7537) format.

Note:
When your account is in trial mode, you can only send a fax to your [verified numbers](https://dashboard.sinch.com/numbers/verified-numbers). If you want to fax any number, you need to upgrade your account!

#### Content URL

The Fax API can send either files directly or the URL of a web page or other online [resource](/docs/fax/api-reference/filetypes). For the purposes of this tutorial, use a web page because it's the easiest way to get started. Change the value of `YOUR_content_url` to the URL of the web page.

Note:
You can use any URL on the Internet (including ones with basic authentication), and we'll pull it down and make it a fax. This might be useful to you if you're using a web framework for templates and creating fax files.

If you are passing fax a secure URL (starting with `https://`), make sure that your SSL certificate (including your intermediate cert, if you have one) is installed properly, valid, and up-to-date.

#### Callback URL

If you provide a callback URL on your Fax service, the Fax API can send [notification events](/docs/fax/api-reference/fax/notifications/) to your server about your outgoing fax, such as when or if the fax was delivered. You can set that callback URL in your request body. Change the value of `YOUR_callback_url` to the URL of your server that's listening to incoming requests.

#### Fill in your parameters

Before you can run the code, you need to update some more values so you can connect to your Sinch account. Update the following parameters with your own values:

| Parameter | Your value |
|  --- | --- |
| `YOUR_project_id` | The project ID found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_key` | The access key found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_secret` | The access secret found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). **Note:** Access secrets are only available during initial key creation. |


Save the file.

### Send your first fax

Now you can execute the code and send your fax. Run the following command:

```shell
gradle run
```

You should receive a fax to the number you specified with the web page that you configured.

Troubleshooting tip
If after running your app you receive a 5000 error response, you may have forgotten to save your file after adding your authentication values. This is an easy mistake to make! Try saving the file and running the app again.

.NET
### Send a fax with .NET

You can quickly see how the Fax API works by sending yourself a fax using the Fax API.

Before you can get started, you need the following already set up:

* [.NET](https://dotnet.microsoft.com/en-us/download/) SDK and ASP.NET Runtime and a familiarity with how to create an app.


#### Set up your .NET application

Create a new project folder and open a command prompt. Execute the following command to create a new .NET console application:

```shell
dotnet new console
```

This creates a new console application and project.

#### Modify your application

1. Open the `Program.cs` file in your project folder. Replace everything in the file with the following code:


```csharp
Fax fax = new Fax("to_number", "YOUR_content_url", "YOUR_callback_url");
fax.sendFax(fax, "YOUR_project_id", "YOUR_access_key", "YOUR_access_secret");
Console.ReadLine();
```

1. Next, create a new file in the project folder named `Fax.cs`. Populate that file with the "Fax.cs" code found on this page.


Fax.cs
```dotnet Fax.cs
using System.Text;
using Newtonsoft.Json;

public class Fax
{
    public string to { get; set; } 
    public string url { get; set; }
    public string callbackUrl { get; set; }
    
    public Fax(string to, string url, string callbackUrl)
    {
        this.to = to;
        this.url = url;
        this.callbackUrl = callbackUrl;
    }

    public async void sendFax(Fax fax, string projectId, string accessKey, string accessSecret)
    {
        using (var client = new HttpClient())
        {
            var base64String = Convert.ToBase64String(Encoding.ASCII.GetBytes(accessKey + ":" + accessSecret));
            client.DefaultRequestHeaders.Add("Authorization", "Basic "+ base64String);
            string json = JsonConvert.SerializeObject(fax);
            var postData = new StringContent(json, Encoding.UTF8, "application/json");
            var request = await client.PostAsync("https://fax.api.sinch.com/v3/projects/" + projectId + "/faxes", postData);
            var response = await request.Content.ReadAsStringAsync();

            Console.WriteLine(response);
        }
 
    }

}
```

This code sends a fax to a specified number using the Sinch Fax API.

#### To

In this example you want to fax a phone number. Change the value of the `to_number` parameter to the phone number you verified in your [dashboard](https://dashboard.sinch.com) in [E.164](https://community.sinch.com/t5/Glossary/E-164/ta-p/7537) format.

Note:
When your account is in trial mode, you can only send a fax to your [verified numbers](https://dashboard.sinch.com/numbers/verified-numbers). If you want to fax any number, you need to upgrade your account!

#### Content URL

The Fax API can send either files directly or the URL of a web page or other online [resource](/docs/fax/api-reference/filetypes). For the purposes of this tutorial, use a web page because it's the easiest way to get started. Change the value of `YOUR_content_url` to the URL of the web page.

Note:
You can use any URL on the Internet (including ones with basic authentication), and we'll pull it down and make it a fax. This might be useful to you if you're using a web framework for templates and creating fax files.

If you are passing fax a secure URL (starting with `https://`), make sure that your SSL certificate (including your intermediate cert, if you have one) is installed properly, valid, and up-to-date.

#### Callback URL

If you provide a callback URL on your Fax service, the Fax API can send [notification events](/docs/fax/api-reference/fax/notifications/) to your server about your outgoing fax, such as when or if the fax was delivered. You can set that callback URL in your request body. Change the value of `YOUR_callback_url` to the URL of your server that's listening to incoming requests.

#### Fill in your parameters

Before you can run the code, you need to update some more values in the `Program.cs` file so you can connect to your Sinch account. Update the following parameters with your own values:

| Parameter | Your value |
|  --- | --- |
| `YOUR_project_id` | The project ID found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_key` | The access key found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_secret` | The access secret found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). **Note:** Access secrets are only available during initial key creation. |


Save the file.

#### Build your project

Before executing your code, you must first compile your application. Execute the following command:

```shell
dotnet build
```

### Send your first fax

Now you can execute the code and send your fax. Run the following command:

```shell
dotnet run
```

You should receive a fax to the number you specified with the web page that you configured.

Python
### Send a fax with Python

You can quickly see how the Fax API works by sending yourself a fax using the Fax API.

#### What you need to know before you start

Before you can get started, you need the following already set up:

* Set all Fax API [configuration settings](/docs/fax/getting-started).
* [Python](https://www.python.org/) and a familiarity with how to create a new file.
* [PIP (package installer for Python)](https://pypi.org/project/pip/) and a familiarity with how to install Python modules.


### Set up your Python application and install dependencies

We'll be using the `requests` module to make HTTP requests. Open a command prompt and use the following command to install the `requests` module:

```shell
pip install requests
```

Create a new file named `send-fax.py` and paste the provided "send-fax.py" code found on this page into the file.

Note:
This tutorial uses basic authentication for testing purposes. We recommend using OAuth token-based authentication for production.

send-fax.py
```python send-fax.py
#Use this code to send a fax using the Fax API. 
# Find the Sinch phone number assigned to your app
# and your access key and secret 
# at dashboard.sinch.com/settings/access-keys
import requests

key = "YOUR_access_key"
secret = "YOUR_access_secret"
project_id = "YOUR_project_id"
to = "YOUR_to_number"
content_url = "YOUR_content_url"
callback_url = "YOUR_callback_url"
url = "https://fax.api.sinch.com/v3/projects/" + project_id + "/faxes"

payload = {
  "to": to,
  "contentUrl": content_url,
  "callbackUrl": callback_url
}

headers = { "Content-Type": "application/json" }

response = requests.post(url, json=payload, headers=headers, auth=(key, secret))

data = response.json()
print(data)
```

This code sends a fax to a specified number using the Sinch Fax API.

#### To

In this example you want to fax a phone number. Change the value of the `to` parameter to the phone number you verified in your [dashboard](https://dashboard.sinch.com) in [E.164](https://community.sinch.com/t5/Glossary/E-164/ta-p/7537) format.

Note:
When your account is in trial mode, you can only send a fax to your [verified numbers](https://dashboard.sinch.com/numbers/verified-numbers). If you want to fax any number, you need to upgrade your account!

#### Content URL

The Fax API can send either files directly or the URL of a web page or other online [resource](/docs/fax/api-reference/filetypes). For the purposes of this tutorial, use a web page because it's the easiest way to get started. Change the value of `YOUR_content_url` to the URL of the web page.

Note:
You can use any URL on the Internet (including ones with basic authentication), and we'll pull it down and make it a fax. This might be useful to you if you're using a web framework for templates and creating fax files.

If you are passing fax a secure URL (starting with `https://`), make sure that your SSL certificate (including your intermediate cert, if you have one) is installed properly, valid, and up-to-date.

#### Callback URL

If you provide a callback URL on your Fax service, the Fax API can send [notification events](/docs/fax/api-reference/fax/notifications) to your server about your outgoing fax, such as when or if the fax was delivered. You can set that callback URL in your request body. Change the value of `YOUR_callback_url` to the URL of your server that's listening to incoming requests.

#### Fill in your parameters

Before you can run the code, you need to update some more values in the `Index.js` file so you can connect to your Sinch account. Update the following parameters with your own values:

| Parameter | Your value |
|  --- | --- |
| `YOUR_project_id` | The project ID found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_key` | The access key found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_secret` | The access secret found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). **Note:** Access secrets are only available during initial key creation. |


Save the file.

### Send your first fax

Now you can execute the code and send your fax. Run the following command:

```shell
python send-fax.py
```

You should receive a fax to the number you specified with the web page that you configured.

Troubleshooting tip
If after running your app you receive a 5000 error response, you may have forgotten to save your file after adding your authentication values. This is an easy mistake to make! Try saving the file and running the app again.

PHP
### Send a fax with PHP

You can quickly see how the Fax API works by sending yourself a fax using the API.

Before you can get started, you need the following already set up:

* [PHP 8.1](https://www.php.net/manual/en/install.php) or later and a familiarity with how to create a new file.


#### Create your PHP file

Create a new file named **send-fax.php** and paste the provided "send-fax.php" code into the file.

Note:
This tutorial uses basic authentication for testing purposes. We recommend using OAuth token-based authentication for production.

send-fax.php
```php send-fax.php
<?php
// Requires libcurl

const key = "YOUR_access_key";
const secret = "YOUR_access_secret";
const projectId = "YOUR_project_id";
const to = "YOUR_to_number";
const contentUrl = "YOUR_content_url";
const callbackUrl = "YOUR_callback_url";

$payload = [
  "to" => to,
  "contentUrl" => contentUrl,
  "callbackUrl" => callbackUrl
];

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_HTTPHEADER => [
    "Content-Type: application/json",
    "Authorization: Basic " . base64_encode(key . ":" . secret)
  ],
  CURLOPT_POSTFIELDS => json_encode($payload),
  CURLOPT_URL => "https://fax.api.sinch.com/v3/projects/" + projectId + "/faxes",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
]);

$response = curl_exec($curl);
$error = curl_error($curl);

curl_close($curl);

if ($error) {
  echo "cURL Error #:" . $error;
} else {
  echo $response;
}

?>
```

This code sends a fax to a specified number using the Sinch Fax API.

#### To

In this example you want to fax a phone number. Change the value of the `to` parameter to the phone number you verified in your [dashboard](https://dashboard.sinch.com) in [E.164](https://community.sinch.com/t5/Glossary/E-164/ta-p/7537) format.

Note:
When your account is in trial mode, you can only send a fax to your [verified numbers](https://dashboard.sinch.com/numbers/verified-numbers). If you want to fax any number, you need to upgrade your account!

#### Content URL

The Fax API can send either files directly or the URL of a web page or other online [resource](/docs/fax/api-reference/filetypes). For the purposes of this tutorial, use a web page because it's the easiest way to get started. Change the value of `YOUR_content_url` to the URL of the web page.

Note:
You can use any URL on the Internet (including ones with basic authentication), and we'll pull it down and make it a fax. This might be useful to you if you're using a web framework for templates and creating fax files.

If you are passing fax a secure URL (starting with `https://`), make sure that your SSL certificate (including your intermediate cert, if you have one) is installed properly, valid, and up-to-date.

#### Callback URL

If you provide a callback URL on your Fax service, the Fax API can send [notification events](/docs/fax/api-reference/fax/notifications/) to your server about your outgoing fax, such as when or if the fax was delivered. You can set that callback URL in your request body. Change the value of `YOUR_callback_url` to the URL of your server that's listening to incoming requests.

#### Fill in your parameters

Before you can run the code, you need to update some more values so you can connect to your Sinch account. Update the following parameters with your own values:

| Parameter | Your value |
|  --- | --- |
| `YOUR_project_id` | The project ID found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_key` | The access key found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). |
| `YOUR_access_secret` | The access secret found on your Sinch [dashboard](https://dashboard.sinch.com/settings/access-keys). **Note:** Access secrets are only available during initial key creation. |


Save the file.

### Send your first fax using PHP

Now you can execute the code and send your fax. Run the following command:

```shell
php send-fax.php
```

You should receive a fax to the number you specified with the web page that you configured.

Troubleshooting tip
If after running your app you receive a 5000 error response, you may have forgotten to save your file after adding your authentication values. This is an easy mistake to make! Try saving the file and running the app again.

## 4. Receive a fax

You can also receive faxes using the Fax API. The easiest way to receive a fax sent to your Sinch number is to set up an email address in the [Build Dashboard](https://dashboard.sinch.com/fax/services/) in the **Fax to Email** tab of your Fax service. Alternatively, each tab below features a guide that will walk you through setting up a simple server application in the identified coding language (make sure you bring all the information you gathered during this process!):

Node.js
### Handle an incoming fax with Node.js

Before you can get started, you need the following already set up:

* [NPM](https://www.npmjs.com/) and a familiarity with how to install packages.
* [Node.js](https://nodejs.org/en/) and a familiarity with how to create a new app.
* A Sinch phone number configured for the Fax API.


To quickly get started setting up a simple client application using the Node.js SDK:

1. First, we'll open a tunnel which will allow your machine to receive requests from the Sinch servers. We are using [ngrok](https://ngrok.com/) for this. If you don't have ngrok installed already, install it with the following command:

```shell
npm install ngrok -g
```
2. Open a terminal or command prompt and enter:

```shell
ngrok http 3001
```
3. Copy the HTTPS address that ends with **.ngrok.io** to save for a future step.
4. If you haven't already, clone the [sinch-sdk-node](https://github.com/sinch/sinch-sdk-node) repository.
5. Navigate to the `examples/getting-started/fax/receive-fax/` folder.
6. Open a command prompt or terminal and run the following command to install the necessary dependencies:

```shell
npm install
```
7. Rename the `.env.example` [file](https://github.com/sinch/sinch-sdk-node/blob/main/examples/getting-started/fax/receive-fax/.env.example) to `.env`. Uncomment `SINCH_FAX_SERVICE_ID` and `WEBHOOK_URL`. Using the [access key credentials](https://dashboard.sinch.com/settings/access-keys) from your Sinch Build Dashboard, populate the following fields with your values:
| Field | Description |
|  --- | --- |
| SINCH_PROJECT_ID | The unique ID of your Project. |
| SINCH_KEY_ID | The unique ID of your access key. |
| SINCH_KEY_SECRET | The secret that goes with your access key.  **Note:** For security reasons, this secret is only visible right after access key creation. |
| SINCH_FAX_SERVICE_ID | The unique ID for your [fax service](https://dashboard.sinch.com/fax/services) |
| WEBHOOK_URL | The ngrok URL you saved from step 3. |
8. Save the file.


#### Start your server

At this point, you can start your server with the following command:

```shell
npm start
```

server.js
```javascript server.js
import express from 'express';
import { SinchClient } from '@sinch/sdk-core';
import { faxController } from './fax/controller.js';
import * as dotenv from 'dotenv';
dotenv.config();

const app = express();
const port = process.env.PORT || 3001;

/** @type {import('@sinch/sdk-core').SinchClientParameters} */
const sinchClientParameters = {
  projectId: process.env.SINCH_PROJECT_ID,
  keyId: process.env.SINCH_KEY_ID,
  keySecret: process.env.SINCH_KEY_SECRET,
};

app.use(express.json({ limit: '25mb' }));
app.use(express.urlencoded({ limit: '25mb', extended: true }));

faxController(app);

const updateIncomingWebhookUrl = async () => {
  const serviceId = process.env.SINCH_FAX_SERVICE_ID;
  const webhookUrl = process.env.WEBHOOK_URL;

  if (!serviceId || !webhookUrl) {
    return;
  }

  const sinchClient = new SinchClient(sinchClientParameters);
  const response = await sinchClient.fax.services.update({
    serviceId,
    updateServiceRequestBody: {
      incomingWebhookUrl: webhookUrl,
      webhookContentType: 'application/json',
    },
  });

  console.log(`Incoming webhook URL updated to ${response.incomingWebhookUrl}`);
};

app.listen(port, async () => {
  console.log(`Server is listening on port ${port}`);
  try {
    await updateIncomingWebhookUrl();
  } catch (error) {
    console.error('Failed to update incoming webhook URL:', error);
  }
});
```

This code starts your webserver and updates your incoming webhook URL. We'll come back to what those things are in a moment.

You should notice a few things.

- First, your console should show that the server has started on port 3001 of your localhost.
- Additionally, you should see a message in your console that the incoming webhook URL for your fax service was updated automatically. There is code in the sample that makes a [request to the Fax API](/docs/fax/api-reference/fax/services/updateservice) to update the incoming webhook URL.


Tip:
You can also update your incoming webhook URL in the dashboard yourself. Navigate to your fax services on your [dashboard](https://dashboard.sinch.com/fax/services). Next to your service click the **Edit** button. You'll see a field labeled "Incoming webhook URL." Enter your URL into that field and click **Save**.

Now your server is listening and your incoming webhook URL is configured, so you're almost ready to test everything and send a fax that you can receive. But before we do, let's take a closer look at webhooks. If you already know about webhooks, skip right to [sending yourself a fax](#call-your-sinch-phone-number).

#### Understanding webhooks

Webhooks (also known as "callbacks" or "notifications") are the method that the Fax API uses to inform you when your Sinch number is sent a fax. Basically, a [notification](/docs/fax/api-reference/fax/notifications) is a request that the Sinch servers send to your server whenever something happens (otherwise known as an "event"), such as when you send or receive a fax. There are two different kinds of events, the Fax Completed and the Incoming Fax event, but the one we're concerned about is the Incoming Fax event.

An *Incoming Fax* event happens whenever someone sends a fax to one of your Sinch numbers. All of the notification events the Fax API sends expect a 200 OK response in return.

And that's it! Now we can test.

### Send your Sinch number a fax

Using the app we created in the previous step, send a fax to your Sinch number. The fax should be picked up by the Sinch servers and a PDF of your fax will be downloaded to your machine. Now you know how to handle an incoming fax.

Java
### Handle an incoming fax with Java

Before you can get started, you need the following already set up:

* [JDK 21](https://www.oracle.com/java/technologies/downloads/) or later and a familiarity with how to create a new Java application.
* [Gradle 8.4](https://gradle.org/install/) or later and a familiarity with how use the Gradle build tools.
* [ngrok](https://ngrok.com/). You'll use ngrok to open a tunnel to your local server.


#### Set up your Java application

Create a new folder where you want to keep your app project. Then, open a terminal or command prompt to that location.

Create a new Java application using Gradle with the following command:

```shell
gradle init
```

In the prompts, select that you want to create an application, name your project and source package `app`, and then accept the defaults for the rest of the options.

#### Install your dependencies

We will be using Springboot to create a lightweight webserver that will listen for HTTP requests from the Sinch servers to handle incoming calls. We'll be using Lombok to deserialize requests.

In your project folder, navigate to the `/app` folder and open the `build.gradle` file. Replace all of the code in the file with the following code:

```shell
plugins {
    id 'application'
    id 'org.springframework.boot' version '3.1.5'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'java'
}

configurations {
    compileOnly {
    extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

application {
    mainClass = 'app.App'
}
```

Save and close the file.

#### Modify your application

Open the `App.java` file in your project folder, located in `\app\scr\main\java\app`, and populate that file with the "App.java" code found on this page and save the file.

App.java
```java App.java
package app;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.extern.jackson.Jacksonized;


@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

	@Controller
	static class WebhookController {

		@PostMapping
		@ResponseBody
		String webhook(@RequestBody IncomingFax payload) {
			try {
                File file = new File(payload.fax.id + ".pdf");
                byte[] decodedBytes = Base64.getDecoder().decode(payload.file);
                FileOutputStream stream = new FileOutputStream(file);
                stream.write(decodedBytes);
                stream.close(); 
            } catch (IOException e) {
                System.out.println("An error occurred");
                e.printStackTrace();
            }
            return "200 OK";
		}
	}

    
    @lombok.Value
    @lombok.Builder
    @Jacksonized
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    static class IncomingFax {
        String event;
        String eventTime;
        Fax fax;
        String fileType;
        String file;
    }
    @lombok.Value
    @lombok.Builder
    @Jacksonized
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    static class Fax {
        String id;
    }
}
```

This file contains the logic to download fax content from the Sinch servers.

#### Start your server

At this point, you can start your server with the following command:

```shell
gradle run
```

#### Start your ngrok tunnel

Now you need to start your ngrok tunnel so that the Sinch servers can access the webserver running on your local machine. Run the following command to start your tunnel:

```shell
ngrok http 8080
```

This starts a tunnel to your webserver, which is running on port 8080 of your localhost.

Copy the http ngrok URL. Navigate to your [Fax service](https://dashboard.sinch.com/fax/services) on your dashboard. Select your default service and click **Edit**. You'll see a field labeled "Incoming webhook URL." Paste your ngrok URL into that field and click **Save**.

Now your server is listening and your incoming webhook URL is configured, so you're almost ready to test everything and send a fax that you can receive. But before we do, let's take a closer look at webhooks. If you already know about webhooks, skip right to [sending yourself a fax](#send-your-sinch-number-a-fax).

#### Understanding webhooks

Webhooks (also known as "callbacks" or "notifications") are the method that the Fax API uses to inform you when your Sinch number is sent a fax. Basically, a [notification](/docs/fax/api-reference/fax/notifications) is a request that the Sinch servers send to your server whenever something happens (otherwise known as an "event"), such as when you send or receive a fax. There are two different kinds of events, the Fax Completed and the Incoming Fax event, but the one we're concerned about is the Incoming Fax event.

An *Incoming Fax* event happens whenever someone sends a fax to one of your Sinch numbers. All of the notification events the Fax API sends expect a 200 OK response in return.

And that's it! Now we can test.

### Send your Sinch number a fax

Using the app we created in the previous step, send a fax to your Sinch number. The fax should be picked up by the Sinch servers and a PDF of your fax will be downloaded to your machine. Now you know how to handle an incoming fax.

.NET
### Handle an incoming fax with .NET

Before you can get started, you need the following already set up:

* [.NET](https://dotnet.microsoft.com/en-us/download/) SDK and .NET Runtime and a familiarity with how to create an app.
* [ngrok](https://ngrok.com) and a familiarity with how to start a network tunnel. You can use any method you want to make your server accessible over the internet, but we like ngrok and it's what we'll use in this guide.


#### Set up your .NET application

Create a new project folder and open a command prompt. Execute the following command to create a new .NET web application:

```shell
dotnet new web
```

This creates a new web application and project.

#### Set up your file

1. In your project folder, open the Program.cs file and paste the following code into the file, replacing all the existing content:


```csharp
using Microsoft.AspNetCore.Mvc;
using ReceiveFax;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost("/", ([FromBody]IncomingFaxEvent incomingFax) => IncomingFax.ReceiveFax(incomingFax));
app.Run();
```

This code starts your webserver and sets up the POST mapping.

1. Next, create a new file in the project named `IncomingFax.cs`, and paste the **IncomingFax.cs** code from this page into the file.


IncomingFax.cs
```dotnet IncomingFax.cs
namespace ReceiveFax;

public record IncomingFaxEvent
{
    public string Event {get; set;}
    public string EventTime {get; set;}
    public Fax Fax {get; set;}
    public string FileType {get;set;}
    public string File {get;set;}
}
public record Fax
{
    public string Id {get;set;}
}

public class IncomingFax
{
    public static HttpResponseMessage ReceiveFax(IncomingFaxEvent incomingFax)
    {
        HttpResponseMessage res = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
        
        byte[] rawBytes = Convert.FromBase64String(incomingFax.File);

        using (FileStream stream = File.Create(incomingFax.Fax.Id + ".pdf"))
        {
            stream.Write(rawBytes, 0, rawBytes.Length);
        }

        return res;
    }
}
```

This file contains the logic to download fax content from the Sinch servers.

#### Start your server

You can start your webserver by running the following command:

```shell
dotnet run
```

Take note of which port on which your server is running.

#### Start your ngrok tunnel

At this point you need to start your ngrok tunnel so that the Sinch servers can access the webserver running on your local machine. Run the following command to start your tunnel:

```shell
ngrok http [PORT]
```

Make sure you replace `[PORT]` with the port on your which server is running.

Copy the http ngrok URL. Navigate to your [Fax service](https://dashboard.sinch.com/fax/services) on your dashboard. Select your default service and click **Edit**. You'll see a field labeled "Incoming webhook URL." Paste your ngrok URL into that field and click **Save**.

Now your server is listening and your incoming webhook URL is configured, so you're almost ready to test everything and send a fax that you can receive. But before we do, let's take a closer look at webhooks. If you already know about webhooks, skip right to [sending yourself a fax](#send-your-sinch-number-a-fax).

#### Understanding webhooks

Webhooks (also known as "callbacks" or "notifications") are the method that the Fax API uses to inform you when your Sinch number is sent a fax. Basically, a [notification](/docs/fax/api-reference/fax/notifications) is a request that the Sinch servers send to your server whenever something happens (otherwise known as an "event"), such as when you send or receive a fax. There are two different kinds of events, the Fax Completed and the Incoming Fax event, but the one we're concerned about is the Incoming Fax event.

An *Incoming Fax* event happens whenever someone sends a fax to one of your Sinch numbers. All of the notification events the Fax API sends expect a 200 OK response in return.

And that's it! Now we can test.

### Send your Sinch number a fax

Using the app we created in the previous step, send a fax to your Sinch number. The fax should be picked up by the Sinch servers and a PDF of your fax will be downloaded to your machine. Now you know how to handle an incoming fax.

Python
### Handle an incoming fax with Python

Before you can get started, you need the following already set up:

* [Python](https://www.python.org/) and a familiarity with how to create a new file.
* [PIP (package installer for Python)](https://pypi.org/project/pip/) and a familiarity with how to install Python modules.
* [Flask](https://flask.palletsprojects.com/en/2.0.x/installation/) and a familiarity with how to set up a Flask environment and app.
* [ngrok](https://ngrok.com/). You'll use ngrok to open a tunnel to your local server.


#### Set up your Flask Python application

Create a new folder where you want your app project and open a command prompt to that location. Create a new environment with the following command:

```shell
py -3 -m venv venv
```

Activate the environment using the following command:

```shell
venv/Scripts/activate
```

#### Install your dependencies

We will be using Flask to create a lightweight webserver that will listen for requests from the Sinch servers to handle incoming faxes. Because the webserver is running on your local machine, you will also need a method for making the server accessible over the internet. In this guide we'll be using [ngrok](https://www.ngrok.com) (and in particular the [pyngrok](https://pyngrok.readthedocs.io/en/latest/index.html) module) to do that, but if you have another way you'd prefer to do it, feel free to use that. Additionally, we'll be using the `requests` module to make HTTP requests.

Use the following command to install the `Flask`, `requests`, and `pyngrok` modules:

```shell
pip install Flask requests pyngrok
```

#### Create your file

In your project folder, create a new file named `app.py`. Populate that file with the provided "app.py" code found on this page.

app.py
```python app.py
#This file is used to start a lightweight webserver to handle incoming faxes. 
from flask import Flask
from flask import request
from pyngrok import ngrok
import requests
import base64

key = "YOUR_access_key"
secret = "YOUR_access_secret"
project_id = "YOUR_project_id"
service_id = "YOUR_service_id"

app = Flask(__name__)

http_tunnel = ngrok.connect(5000)

url = "https://fax.api.sinch.com/v3/projects/" + project_id + "/services/" + service_id

payload = {
    "incomingWebhookUrl": http_tunnel.public_url,
    "webhookContentType": 'application/json'
}

headers = {
    "Content-Type": "application/json"
    }

response = requests.patch(url, json=payload, headers=headers, auth=(key, secret))

print(response)

print("Your callback URL has been set to " + http_tunnel.public_url)

@app.route('/', methods=['POST'])
def result():
    req = request.get_json()
    base64_bytes = base64.b64decode(req['file'], validate=True)
    if req['event'] == "INCOMING_FAX":
        with open(req['fax']['id'] + ".pdf", "wb") as file1:
            file1.write(base64_bytes)
    return "200 OK"
```

This code starts your webserver, creates an ngrok tunnel, updates your incoming webhook URL, and also contains the logic to download fax content from the Sinch servers. We'll come back to what those things are in a moment.

Before you save your file and start your server, there's a couple of values you to need to update.

#### Update your parameter values

Update the values of the following parameters:

| Parameter | Your value |
|  --- | --- |
| `YOUR_access_key` | The key found on your Sinch [dashboard](https://dashboard.sinch.com/account/access-keys). |
| `YOUR_access_secret` | The secret found on your Sinch [dashboard](https://dashboard.sinch.com/account/access-keys). **Note:** Access secrets are only available during initial key creation. |
| `YOUR_project_id` | The project ID found on your Sinch [dashboard](https://dashboard.sinch.com/account/access-keys). |
| `YOUR_service_id` | The service ID found on your Sinch [dashboard](https://dashboard.sinch.com/fax/services). |


#### Start your server

At this point, you can start your server with the following command:

```shell
flask run
```

You should notice a few things.

- First, your console should show that the server has started on port 5000 of your localhost.
- Second, the ngrok tunnel has started and you should see the URL displayed in the console.
- Additionally, you should see a message in your console that the incoming webhook URL for your fax service was updated automatically. There is code in the sample that makes a [request to the Fax API](/docs/fax/api-reference/fax/services/updateservice) to update the incoming webhook URL.


Tip:
You can also update your incoming webhook URL in the dashboard yourself. Navigate to your fax services on your [dashboard](https://dashboard.sinch.com/fax/services). Next to your service click the **Edit** button. You'll see a field labeled "Incoming webhook URL." Enter your URL into that field and click **Save**.

Now your server is listening and your incoming webhook URL is configured, so you're almost ready to test everything and send a fax that you can receive. But before we do, let's take a closer look at webhooks. If you already know about webhooks, skip right to [sending yourself a fax](#call-your-sinch-phone-number).

#### Understanding webhooks

Webhooks (also known as "callbacks" or "notifications") are the method that the Fax API uses to inform you when your Sinch number is sent a fax. Basically, a [notification](/docs/fax/api-reference/fax/notifications) is a request that the Sinch servers send to your server whenever something happens (otherwise known as an "event"), such as when you send or receive a fax. There are two different kinds of events, the Fax Completed and the Incoming Fax event, but the one we're concerned about is the Incoming Fax event.

An *Incoming Fax* event happens whenever someone sends a fax to one of your Sinch numbers. All of the notification events the Fax API sends expect a 200 OK response in return.

And that's it! Now we can test.

### Send your Sinch number a fax

Using the app we created in the previous step, send a fax to your Sinch number. The fax should be picked up by the Sinch servers and a PDF of your fax will be downloaded to your machine. Now you know how to handle an incoming fax.