Documentation menu

Getting started

API reference

Guides

Trust and support

Code examples

Complete programs in five languages. Each one reads the key from SAHIFA_API_KEY, calls the live API and saves the result. They use only the standard library, except requests for Python. All of them are run against the API before every change to this page.

Requirements

LanguageVersionRun with
curl7.76+ (for --fail-with-body)bash pdf.sh
JavaScriptNode.js 18+ (built-in fetch)node pdf.mjs
Python3.8+ and pip install requestspython pdf.py
.NET.NET 8+dotnet run pdf.cs on .NET 10, or paste into Program.cs of a console app
JavaJava 18+ for the PDF example (UTF-8 source), 11+ for the othersjava Pdf.java

HTML to PDF

An Arabic invoice with a page footer, saved as invoice.pdf.

# HTML to PDF with an Arabic footer. Requires: SAHIFA_API_KEY in the environment.
curl https://api.sahifa.dev/v3/convert/pdf \
  --user "api:$SAHIFA_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "source": "<html dir=\"rtl\" lang=\"ar\"><body><h1>فاتورة ضريبية</h1><p>الإجمالي: 1,150.00 ر.س</p></body></html>",
    "format": "A4",
    "margin": "20mm",
    "footer": { "source": "<div style=\"width:100%;text-align:center\">صفحة {{page}} من {{total}}</div>" }
  }' \
  --fail-with-body --output invoice.pdf

Screenshot of a web page

The whole page as PNG, with cookie consent pop-ups hidden, saved as page.png.

# Full-page screenshot of a URL, without cookie banners. Requires: SAHIFA_API_KEY.
curl --get https://api.sahifa.dev/take \
  --data-urlencode "access_key=$SAHIFA_API_KEY" \
  --data-urlencode "url=https://example.com" \
  --data "format=png" \
  --data "full_page=true" \
  --data "block_cookie_banners=true" \
  --fail-with-body --output page.png

Retrying

Retries on 429 and 503 with an increasing wait, and honours Retry-After. Other errors are raised immediately.

# curl retries 408, 429, 500, 502, 503 and 504 responses on its own, honouring Retry-After.
curl https://api.sahifa.dev/v3/convert/pdf \
  --user "api:$SAHIFA_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{ "source": "https://example.com" }' \
  --retry 4 --retry-delay 2 --retry-max-time 60 \
  --fail-with-body --output example.pdf

Browsers and front-end code

Do not call the API from a browser: the key would be visible to every visitor. Call it from your server and send the file to the browser. In Express, for example:

app.get('/invoices/:id.pdf', async (req, res) => {
  const html = await renderInvoiceHtml(req.params.id); // your template
  const pdf = await fetch('https://api.sahifa.dev/v3/convert/pdf', {
    method: 'POST',
    headers: { 'X-API-Key': process.env.SAHIFA_API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ source: html, format: 'A4', margin: '15mm' }),
  });
  if (!pdf.ok) return res.status(502).send('PDF could not be created');
  res.type('application/pdf').send(Buffer.from(await pdf.arrayBuffer()));
});

Using an existing PDFShift or ScreenshotOne library

If your code already uses a client library for either service, point its base URL to https://api.sahifa.dev and use your Sahifa key. See migrating.