> ## Documentation Index > Fetch the complete documentation index at: https://docs.firecrawl.dev/llms.txt > Use this file to discover all available pages before exploring further. # Java > Firecrawl Java SDK is a wrapper around the Firecrawl API to help you easily turn websites into markdown. ## Installation The official Java SDK is maintained in the Firecrawl monorepo at [apps/java-sdk](https://github.com/firecrawl/firecrawl/tree/main/apps/java-sdk). To install the Firecrawl Java SDK, add the dependency from Maven Central: ```kotlin theme={null} repositories { mavenCentral() } dependencies { implementation("com.firecrawl:firecrawl-java:1.1.1") } ``` ```groovy theme={null} repositories { mavenCentral() } dependencies { implementation 'com.firecrawl:firecrawl-java:1.1.1' } ``` ```xml theme={null} com.firecrawl firecrawl-java 1.1.1 ``` Requires Java 11 or later. ## Usage 1. Get an API key from [firecrawl.dev](https://firecrawl.dev) 2. Set the API key as an environment variable named `FIRECRAWL_API_KEY`, or pass it with `FirecrawlClient.builder().apiKey(...)` Here is a quick example using the current SDK API surface: ```java theme={null} import com.firecrawl.client.FirecrawlClient; import com.firecrawl.models.CrawlJob; import com.firecrawl.models.CrawlOptions; import com.firecrawl.models.Document; import com.firecrawl.models.ScrapeOptions; import java.util.List; public class Example { public static void main(String[] args) { FirecrawlClient client = FirecrawlClient.fromEnv(); Document doc = client.scrape( "https://firecrawl.dev", ScrapeOptions.builder() .formats(List.of((Object) "markdown")) .build() ); CrawlJob crawl = client.crawl( "https://firecrawl.dev", CrawlOptions.builder().limit(5).build() ); System.out.println(doc.getMarkdown()); System.out.println("Crawled pages: " + (crawl.getData() != null ? crawl.getData().size() : 0)); } } ``` ### Scraping a URL To scrape a single URL, use the `scrape` method. ```java theme={null} import com.firecrawl.models.Document; import com.firecrawl.models.ScrapeOptions; import java.util.List; Document doc = client.scrape( "https://firecrawl.dev", ScrapeOptions.builder() .formats(List.of((Object) "markdown", "html")) .onlyMainContent(true) .waitFor(5000) .build() ); System.out.println(doc.getMarkdown()); System.out.println(doc.getMetadata().get("title")); ``` ### Parsing uploaded files The latest Java SDK package (`com.firecrawl:firecrawl-java`) supports direct file uploads to `/v2/parse`. `parse` does not support `changeTracking` or browser-only options like `screenshot`, `branding`, `actions`, `waitFor`, `location`, and `mobile`. ```java Java theme={null} import com.firecrawl.client.FirecrawlClient; import com.firecrawl.models.Document; import com.firecrawl.models.ParseFile; import com.firecrawl.models.ParseOptions; import java.nio.charset.StandardCharsets; import java.util.List; FirecrawlClient client = FirecrawlClient.fromEnv(); ParseFile file = ParseFile.builder() .filename("upload.html") .content("

Java Parse

" .getBytes(StandardCharsets.UTF_8)) .contentType("text/html") .build(); Document parsed = client.parse( file, ParseOptions.builder().formats(List.of("markdown")).build() ); System.out.println(parsed.getMarkdown()); ``` #### JSON Extraction Extract structured JSON with `JsonFormat` via the `scrape` endpoint: ```java theme={null} import com.firecrawl.models.Document; import com.firecrawl.models.JsonFormat; import com.firecrawl.models.ScrapeOptions; import java.util.List; import java.util.Map; JsonFormat jsonFmt = JsonFormat.builder() .prompt("Extract the product name and price") .schema(Map.of( "type", "object", "properties", Map.of( "name", Map.of("type", "string"), "price", Map.of("type", "number") ) )) .build(); Document doc = client.scrape( "https://example.com/product", ScrapeOptions.builder() .formats(List.of((Object) jsonFmt)) .build() ); System.out.println(doc.getJson()); ``` ### Crawling a Website To crawl a website and wait for completion, use `crawl`. ```java theme={null} import com.firecrawl.models.CrawlJob; import com.firecrawl.models.CrawlOptions; import com.firecrawl.models.Document; import com.firecrawl.models.ScrapeOptions; import java.util.List; CrawlJob job = client.crawl( "https://firecrawl.dev", CrawlOptions.builder() .limit(50) .maxDiscoveryDepth(3) .scrapeOptions( ScrapeOptions.builder() .formats(List.of((Object) "markdown")) .build() ) .build() ); System.out.println("Status: " + job.getStatus()); System.out.println("Progress: " + job.getCompleted() + "/" + job.getTotal()); if (job.getData() != null) { for (Document page : job.getData()) { System.out.println(page.getMetadata().get("sourceURL")); } } ``` ### Start a Crawl Start a job without waiting using `startCrawl`. ```java theme={null} import com.firecrawl.models.CrawlOptions; import com.firecrawl.models.CrawlResponse; CrawlResponse start = client.startCrawl( "https://firecrawl.dev", CrawlOptions.builder().limit(100).build() ); System.out.println("Job ID: " + start.getId()); ``` ### Checking Crawl Status Check crawl progress with `getCrawlStatus`. ```java theme={null} import com.firecrawl.models.CrawlJob; CrawlJob status = client.getCrawlStatus(start.getId()); System.out.println("Status: " + status.getStatus()); System.out.println("Progress: " + status.getCompleted() + "/" + status.getTotal()); ``` ### Cancelling a Crawl Cancel a running crawl with `cancelCrawl`. ```java theme={null} import java.util.Map; Map result = client.cancelCrawl(start.getId()); System.out.println(result); ``` ### Mapping a Website Discover links on a site using `map`. ```java theme={null} import com.firecrawl.models.MapData; import com.firecrawl.models.MapOptions; import java.util.Map; MapData data = client.map( "https://firecrawl.dev", MapOptions.builder() .limit(100) .search("blog") .build() ); if (data.getLinks() != null) { for (Map link : data.getLinks()) { System.out.println(link.get("url") + " - " + link.get("title")); } } ``` ### Searching the Web Search with optional search settings using `search`. ```java theme={null} import com.firecrawl.models.SearchData; import com.firecrawl.models.SearchOptions; import java.util.Map; SearchData results = client.search( "firecrawl web scraping", SearchOptions.builder() .limit(10) .build() ); if (results.getWeb() != null) { for (Map result : results.getWeb()) { System.out.println(result.get("title") + " - " + result.get("url")); } } ``` ### Batch Scraping Scrape multiple URLs in parallel using `batchScrape`. ```java theme={null} import com.firecrawl.models.BatchScrapeJob; import com.firecrawl.models.BatchScrapeOptions; import com.firecrawl.models.Document; import com.firecrawl.models.ScrapeOptions; import java.util.List; BatchScrapeJob job = client.batchScrape( List.of("https://firecrawl.dev", "https://firecrawl.dev/blog"), BatchScrapeOptions.builder() .options( ScrapeOptions.builder() .formats(List.of((Object) "markdown")) .build() ) .build() ); if (job.getData() != null) { for (Document doc : job.getData()) { System.out.println(doc.getMarkdown()); } } ``` ### Agent Run an AI-powered agent with `agent`. ```java theme={null} import com.firecrawl.models.AgentOptions; import com.firecrawl.models.AgentStatusResponse; AgentStatusResponse result = client.agent( AgentOptions.builder() .prompt("Find the pricing plans for Firecrawl and compare them") .build() ); System.out.println(result.getData()); ``` With a JSON schema for structured output: ```java theme={null} import com.firecrawl.models.AgentOptions; import com.firecrawl.models.AgentStatusResponse; import java.util.List; import java.util.Map; AgentStatusResponse result = client.agent( AgentOptions.builder() .prompt("Extract pricing plan details") .urls(List.of("https://firecrawl.dev")) .schema(Map.of( "type", "object", "properties", Map.of( "plans", Map.of( "type", "array", "items", Map.of( "type", "object", "properties", Map.of( "name", Map.of("type", "string"), "price", Map.of("type", "string") ) ) ) ) )) .build() ); System.out.println(result.getData()); ``` ### Usage & Metrics Check concurrency and remaining credits: ```java theme={null} import com.firecrawl.models.ConcurrencyCheck; import com.firecrawl.models.CreditUsage; ConcurrencyCheck concurrency = client.getConcurrency(); System.out.println("Concurrency: " + concurrency.getConcurrency() + "/" + concurrency.getMaxConcurrency()); CreditUsage credits = client.getCreditUsage(); System.out.println("Remaining credits: " + credits.getRemainingCredits()); ``` ## Async Support Async variants are built in and return `CompletableFuture`. ```java theme={null} import com.firecrawl.models.Document; import com.firecrawl.models.ScrapeOptions; import java.util.List; import java.util.concurrent.CompletableFuture; CompletableFuture future = client.scrapeAsync( "https://example.com", ScrapeOptions.builder() .formats(List.of((Object) "markdown")) .build() ); future.thenAccept(doc -> System.out.println(doc.getMarkdown())); ``` ## Browser The Java SDK includes Browser Sandbox helpers. ### Create a Session ```java theme={null} import com.firecrawl.models.BrowserCreateResponse; BrowserCreateResponse session = client.browser(120, 60, true); System.out.println(session.getId()); System.out.println(session.getCdpUrl()); System.out.println(session.getLiveViewUrl()); ``` ### Execute Code ```java theme={null} import com.firecrawl.models.BrowserExecuteResponse; BrowserExecuteResponse run = client.browserExecute( session.getId(), "await page.goto(\"https://example.com\"); console.log(await page.title());", "node", 60 ); System.out.println(run.getStdout()); System.out.println(run.getExitCode()); ``` ### Scrape-Bound Interactive Session Use a scrape job ID to run follow-up browser code in the same replayed context: * `interact(...)` runs code in the scrape-bound browser session (and initializes it on first use). * `stopInteraction(...)` explicitly stops the interactive session when you are done. ```java theme={null} import com.firecrawl.models.BrowserDeleteResponse; import com.firecrawl.models.BrowserExecuteResponse; String scrapeJobId = "550e8400-e29b-41d4-a716-446655440000"; BrowserExecuteResponse scrapeRun = client.interact( scrapeJobId, "console.log(page.url());", "node", 60 ); System.out.println(scrapeRun.getStdout()); BrowserDeleteResponse deleted = client.stopInteraction(scrapeJobId); System.out.println("Deleted: " + deleted.isSuccess()); ``` ### List & Close Sessions ```java theme={null} import com.firecrawl.models.BrowserDeleteResponse; import com.firecrawl.models.BrowserListResponse; import com.firecrawl.models.BrowserSession; BrowserListResponse active = client.listBrowsers("active"); if (active.getSessions() != null) { for (BrowserSession s : active.getSessions()) { System.out.println(s.getId() + " - " + s.getStatus()); } } BrowserDeleteResponse closed = client.deleteBrowser(session.getId()); System.out.println("Closed: " + closed.isSuccess()); ``` ## Configuration `FirecrawlClient.builder()` supports the following options: | Option | Type | Default | Description | | --------------- | -------------- | ----------------------------------------------------------------- | ---------------------------------------- | | `apiKey` | `String` | `FIRECRAWL_API_KEY` env var or `firecrawl.apiKey` system property | Your Firecrawl API key | | `apiUrl` | `String` | `https://api.firecrawl.dev` (or `FIRECRAWL_API_URL`) | API base URL | | `timeoutMs` | `long` | `300000` | HTTP request timeout in ms | | `maxRetries` | `int` | `3` | Automatic retries for transient failures | | `backoffFactor` | `double` | `0.5` | Exponential backoff factor in seconds | | `asyncExecutor` | `Executor` | `ForkJoinPool.commonPool()` | Custom executor for async methods | | `httpClient` | `OkHttpClient` | Built from `timeoutMs` | Pre-configured OkHttpClient instance | ```java theme={null} import com.firecrawl.client.FirecrawlClient; FirecrawlClient client = FirecrawlClient.builder() .apiKey("fc-your-api-key") .apiUrl("https://api.firecrawl.dev") .timeoutMs(300_000) .maxRetries(3) .backoffFactor(0.5) .build(); ``` ### Custom HTTP Client You can pass a pre-configured `OkHttpClient` to control connection pooling, interceptors, SSL configuration, proxy settings, and any other OkHttp feature. When provided, the `timeoutMs` setting is ignored in favor of the client's own configuration. ```java theme={null} import com.firecrawl.client.FirecrawlClient; import okhttp3.OkHttpClient; import java.net.InetSocketAddress; import java.net.Proxy; import java.util.concurrent.TimeUnit; OkHttpClient custom = new OkHttpClient.Builder() .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080))) .addInterceptor(chain -> { System.out.println("Request: " + chain.request().url()); return chain.proceed(chain.request()); }) .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .build(); FirecrawlClient client = FirecrawlClient.builder() .apiKey("fc-your-api-key") .httpClient(custom) .build(); ``` ## Error Handling The SDK throws runtime exceptions under `com.firecrawl.errors`. ```java theme={null} import com.firecrawl.errors.AuthenticationException; import com.firecrawl.errors.FirecrawlException; import com.firecrawl.errors.JobTimeoutException; import com.firecrawl.errors.RateLimitException; import com.firecrawl.models.Document; try { Document doc = client.scrape("https://example.com"); } catch (AuthenticationException e) { System.err.println("Auth failed: " + e.getMessage()); } catch (RateLimitException e) { System.err.println("Rate limited: " + e.getMessage()); } catch (JobTimeoutException e) { System.err.println("Job " + e.getJobId() + " timed out after " + e.getTimeoutSeconds() + "s"); } catch (FirecrawlException e) { System.err.println("Error " + e.getStatusCode() + ": " + e.getMessage()); } ``` > Are you an AI agent that needs a Firecrawl API key? See [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) for automated onboarding instructions.