# Handle an incoming fax with Java Now that you know how to [send yourself a fax a using the Fax API](/docs/fax/getting-started/java/send-fax), learn how to handle incoming faxes. In this guide you will learn: 1. How to [set up your your Java app](#set-up-your-java-application) 2. How to [start your server](#start-your-server) 3. About [callbacks](#understanding-callbacks) 4. How to [receive an incoming fax](#send-your-sinch-number-a-fax) ## 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). * [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 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 guide](/docs/fax/getting-started/java/send-fax), 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. ## Next steps Learn more about the Fax API: - [API specification](/docs/fax/api-reference/fax)