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
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The public URL of the page to convert. Local/internal IPs are blocked. |
webhook_url | string | No | Optional 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. |
options | object | No | Custom styling, margin, and watermark options. See PDF Options. |
render | object | No | Timeout and wait selectors for browser load states. See Browser Options. |
auth | object | No | Authorization settings for pages requiring login credentials (Pro+ plans only). |
test | boolean | No | Run 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...').
- For
Request Headers
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key (sk_live_...). |
Idempotency-Key | No | 1-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
- Submit Job: Post the URL to
/url-to-pdf. You'll receive ajob_idand a status ofqueued. - Poll Status: Send
GETrequests to/jobs/{job_id}untilstatusisdone(orfailed). - Download File: Send a request to
/jobs/{job_id}/downloadto stream the PDF binary directly. The file is available for 24 hours after generation (the exact moment is theexpires_atfield 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());
}
}