Convert URL to PDF

The URL-to-PDF endpoint converts any publicly accessible webpage into a high-quality PDF document. The process is asynchronous to support rendering complex, media-heavy sites without timing out.

Endpoint

POST https://api.pdfik.net/url-to-pdf

Request Body

ParameterTypeRequiredDescription
urlstringYesThe public URL of the page to convert. Local/internal IPs are blocked.
webhook_urlstringNoOptional HTTP callback URL where the job outcome payload will be POSTed. Credentials must not be embedded in the URL (https://user:pass@host is rejected) — configure delivery headers in the dashboard instead.
optionsobjectNoCustom styling, margin, and watermark options. See PDF Options.
renderobjectNoTimeout and wait selectors for browser load states. See Browser Options.
authobjectNoAuthorization settings for pages requiring login credentials (Pro+ plans only).
testbooleanNoRun the job in test mode: full pipeline, no real render, a sample PDF is returned. Quotas are not debited. Defaults to false.

Authentication Settings (auth)

If the target URL requires credentials, supply an auth object containing:

  • type (string, required): The authorization type. Must be either 'basic' or 'bearer'.
  • value (string, required): The credentials to send.
    • For basic: Provide the string format 'username:password'.
    • For bearer: Provide the raw authorization token string (e.g. 'eyJhbGci...').

Request Headers

HeaderRequiredDescription
X-API-KeyYesYour API key (sk_live_...).
Idempotency-KeyNo1-255 characters from A-Z a-z 0-9 _ - . :. Retrying a request with the same key returns the original job instead of creating (and billing) a duplicate. Recommended for retry-after-timeout logic.

The Asynchronous Flow

  1. Submit Job: Post the URL to /url-to-pdf. You'll receive a job_id and a status of queued.
  2. Poll Status: Send GET requests to /jobs/{job_id} until status is done (or failed).
  3. Download File: Send a request to /jobs/{job_id}/download to stream the PDF binary directly. The file is available for 24 hours after generation (the exact moment is the expires_at field in the status response); at most 3 download attempts and 1 active stream are allowed per file. See File Retention & Downloads.

Integration Examples

1. Simple Polling Loop (Bash)

This script submits a job, polls every 2 seconds, and downloads the PDF when ready:

#!/bin/bash
API_KEY="sk_test_YOUR_KEY"
URL="https://example.com"

# Step 1: Submit job
RESPONSE=$(curl -s -X POST https://api.pdfik.net/url-to-pdf \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"url\": \"$URL\"}")

JOB_ID=$(echo $RESPONSE | jq -r '.job_id')
echo "Job submitted: $JOB_ID"

# Step 2: Poll status
while true; do
  STATUS_RESP=$(curl -s -H "X-API-Key: $API_KEY" https://api.pdfik.net/jobs/$JOB_ID)
  STATUS=$(echo $STATUS_RESP | jq -r '.status')
  echo "Current status: $STATUS"
  
  if [ "$STATUS" = "done" ]; then
    break
  elif [ "$STATUS" = "failed" ]; then
    echo "Job failed!"
    exit 1
  fi
  sleep 2
done

# Step 3: Download
curl -H "X-API-Key: $API_KEY" https://api.pdfik.net/jobs/$JOB_ID/download -o output.pdf
echo "Saved output.pdf"

2. Node.js Integration

const axios = require('axios');
const fs = require('fs');

const API_KEY = 'sk_test_YOUR_KEY';

async function generatePdf(url) {
  // 1. Submit
  const submitRes = await axios.post('https://api.pdfik.net/url-to-pdf', 
    { url }, 
    { headers: { 'X-API-Key': API_KEY } }
  );
  const { job_id } = submitRes.data;

  // 2. Poll
  let status = 'queued';
  while (status !== 'done' && status !== 'failed') {
    await new Promise(r => setTimeout(r, 2000));
    const statusRes = await axios.get(`https://api.pdfik.net/jobs/${job_id}`, {
      headers: { 'X-API-Key': API_KEY }
    });
    status = statusRes.data.status;
  }

  if (status === 'failed') throw new Error('PDF Generation failed');

  // 3. Download
  const writer = fs.createWriteStream('output.pdf');
  const downloadRes = await axios.get(`https://api.pdfik.net/jobs/${job_id}/download`, {
    headers: { 'X-API-Key': API_KEY },
    responseType: 'stream'
  });

  downloadRes.data.pipe(writer);
  return new Promise((resolve, reject) => {
    writer.on('finish', resolve);
    writer.on('error', reject);
  });
}

3. JavaScript (ES6 Fetch)

const API_KEY = 'sk_test_YOUR_KEY';

async function generatePdf(url) {
  // 1. Submit the URL to start the PDF conversion job
  const submitRes = await fetch('https://api.pdfik.net/url-to-pdf', {
    method: 'POST',
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ url })
  });
  
  if (!submitRes.ok) throw new Error(`Failed to submit job: ${submitRes.statusText}`);
  const { job_id } = await submitRes.json();
  
  // 2. Poll the job status endpoint until it completes or fails
  let status = 'queued';
  while (status !== 'done' && status !== 'failed') {
    await new Promise(resolve => setTimeout(resolve, 2000));
    
    const statusRes = await fetch(`https://api.pdfik.net/jobs/${job_id}`, {
      headers: { 'X-API-Key': API_KEY }
    });
    
    if (statusRes.ok) {
      const data = await statusRes.json();
      status = data.status;
    }
  }
  
  if (status === 'failed') throw new Error('PDF generation job failed');
  
  // 3. Download the PDF file
  const downloadRes = await fetch(`https://api.pdfik.net/jobs/${job_id}/download`, {
    headers: { 'X-API-Key': API_KEY }
  });
  return await downloadRes.arrayBuffer(); // returns PDF binary buffer
}

4. Java (HttpClient)

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Paths;
import java.time.Duration;

public class PdfikClient {
    private static final String API_KEY = "sk_test_YOUR_KEY";
    private static final HttpClient httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    public static void main(String[] args) throws Exception {
        String targetUrl = "https://example.com";
        
        // 1. Submit Job
        String submitJson = "{\"url\":\"" + targetUrl + "\"}";
        HttpRequest submitRequest = HttpRequest.newBuilder()
                .uri(URI.create("https://api.pdfik.net/url-to-pdf"))
                .header("X-API-Key", API_KEY)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(submitJson))
                .build();

        HttpResponse<String> submitResponse = httpClient.send(submitRequest, HttpResponse.BodyHandlers.ofString());
        if (submitResponse.statusCode() != 202) {
            throw new RuntimeException("Job submission failed: " + submitResponse.body());
        }

        // Extract job_id
        String body = submitResponse.body();
        String jobId = body.split("\"job_id\":\"")[1].split("\"")[0];
        System.out.println("Job submitted successfully. ID: " + jobId);

        // 2. Poll Status
        String status = "queued";
        while (!status.equals("done") && !status.equals("failed")) {
            Thread.sleep(2000);
            
            HttpRequest statusRequest = HttpRequest.newBuilder()
                    .uri(URI.create("https://api.pdfik.net/jobs/" + jobId))
                    .header("X-API-Key", API_KEY)
                    .GET()
                    .build();

            HttpResponse<String> statusResponse = httpClient.send(statusRequest, HttpResponse.BodyHandlers.ofString());
            String statusBody = statusResponse.body();
            status = statusBody.split("\"status\":\"")[1].split("\"")[0];
            System.out.println("Current status: " + status);
        }

        if (status.equals("failed")) {
            throw new RuntimeException("PDF generation failed.");
        }

        // 3. Download File
        HttpRequest downloadRequest = HttpRequest.newBuilder()
                .uri(URI.create("https://api.pdfik.net/jobs/" + jobId + "/download"))
                .header("X-API-Key", API_KEY)
                .GET()
                .build();

        HttpResponse<java.nio.file.Path> downloadResponse = httpClient.send(
                downloadRequest, 
                HttpResponse.BodyHandlers.ofFile(Paths.get("output.pdf"))
        );
        System.out.println("PDF saved to: " + downloadResponse.body().toAbsolutePath());
    }
}