Python Examples

This page shows complete Python examples for the external Davix H2I API.

Requests are processed by the H2I engine (PixLab) through the public external endpoints:

  • /v1/h2i
  • /v1/image
  • /v1/pdf
  • /v1/tools

External requests require API key authentication. Supported authentication methods are:

  • X-Api-Key
  • Authorization: Bearer <key>

Optional idempotency headers are also supported:

  • Idempotency-Key
  • X-Idempotency-Key

In production, body/query API key transport is rejected.

Setup #

These examples use Python with the requests library.

import json
import requestsBASE = "https://pixlab.davix.dev"
API_KEY = "<YOUR_API_KEY>"

Authentication #

Use either of these patterns:

headers = {
"X-Api-Key": API_KEY,
}

or

headers = {
"Authorization": f"Bearer {API_KEY}",
}

Optional idempotency #

All examples below may include:

"Idempotency-Key": "your-request-id-001"

Valid idempotency keys are 8 to 128 characters and may contain A-Z, a-z, 0-9, ., _, :, and -. The server echoes a valid key back as the Idempotency-Key response header. Invalid values return invalid_idempotency_key.

Notes about outputs #

  • /v1/h2i, /v1/image, and /v1/pdf return generated outputs and signed URLs.
  • /v1/tools returns structured JSON analysis results rather than generated file URLs.
  • Static output fetches for /h2i/*, /image/*, and /pdf/* are behind signed URL protection. /tools/* is signed when signed output mode is enabled.

Helper functions #

These helpers are used by the examples below.

def api_json_request(url: str, payload: dict, headers: dict | None = None) -> tuple[int, dict | str]:
response = requests.post(url, headers=headers or {}, json=payload, timeout=300)
try:
return response.status_code, response.json()
except ValueError:
return response.status_code, response.textdef api_multipart_request(
url: str,
data: list[tuple[str, str]],
files: list[tuple[str, tuple[str, object, str]]],
headers: dict | None = None,
) -> tuple[int, dict | str]:
response = requests.post(url, headers=headers or {}, data=data, files=files, timeout=300)
try:
return response.status_code, response.json()
except ValueError:
return response.status_code, response.text

Endpoint: POST /v1/h2i #

Supported actions:

  • image
  • pdf

Action: image #

Converts HTML into an image.

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "h2i-image-001",
}payload = {
"action": "image",
"html": '<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center">Hello</div>',
"css": "body{margin:0}",
"width": 1200,
"height": 1600,
"format": "jpeg",
}status, data = api_json_request(f"{BASE}/v1/h2i", payload, headers)
print(status)
print(json.dumps(data, indent=2) if isinstance(data, dict) else data)

Parameters

  • action — required, must be image
  • html — required HTML string
  • css — optional CSS string
  • width — optional viewport width, default 1000
  • height — optional viewport height, default 1500
  • format — optional output format, default png; only jpeg produces JPEG, other values become PNG

Notes

  • If width * height exceeds the render pixel limit, the request fails with render_size_exceeded.

Action: pdf #

Converts HTML into a PDF.

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-001",
}payload = {
"action": "pdf",
"html": "<h1>Invoice</h1>",
"css": "body{font-family:sans-serif}",
"width": 1000,
"height": 1500,
"pdfFormat": "LETTER",
"pdfLandscape": False,
"pdfMargin": 24,
"preferCSSPageSize": True,
"scale": 1,
"printMode": False,
"printBackground": True,
}status, data = api_json_request(f"{BASE}/v1/h2i", payload, headers)
print(status)
print(json.dumps(data, indent=2) if isinstance(data, dict) else data)

Parameters

  • action — required, must be pdf
  • html — required HTML string
  • css — optional CSS string
  • width, height — optional viewport values
  • pdfFormat — optional, default A4; only LETTER maps to Letter
  • pdfLandscape — optional boolean, default false
  • pdfMargin — optional integer, default 24
  • preferCSSPageSize — optional boolean, default true
  • scale — optional numeric, default 1
  • printMode — optional boolean, default false
  • printBackground — optional boolean, default true

Endpoint: POST /v1/image #

Supported actions: format, resize, crop, transform, compress, enhance, padding, frame, background, watermark, pdf, metadata, multitask. The endpoint uses multipart/form-data. For most non-metadata actions, the route runs a shared pipeline, so the action label mostly affects logging and documentation grouping rather than branching.

Shared image parameters #

These parameters are reused across image actions:

  • action
  • images
  • watermarkImage
  • format
  • width, height, enlarge
  • cropX, cropY, cropWidth, cropHeight
  • rotate, flipH, flipV
  • targetSizeKB, quality
  • keepMetadata, normalizeOrientation
  • blur, sharpen, grayscale, sepia
  • brightness, contrast, saturation
  • pad, padTop, padRight, padBottom, padLeft, padColor
  • border, borderColor, borderRadius
  • backgroundColor, backgroundBlur
  • watermarkText, watermarkFontSize, watermarkColor, watermarkOpacity, watermarkPosition, watermarkMargin, watermarkScale
  • pdfMode, pdfPageSize, pdfOrientation, pdfMargin, pdfEmbedFormat, pdfJpegQuality
  • colorSpace
  • includeRawExif

Action: format #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-002",
}data = [
("action", "format"),
("format", "webp"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: resize #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-003",
}data = [
("action", "resize"),
("width", "1024"),
("height", "768"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: crop #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-004",
}data = [
("action", "crop"),
("cropX", "0"),
("cropY", "0"),
("cropWidth", "800"),
("cropHeight", "600"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: transform #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-005",
}data = [
("action", "transform"),
("rotate", "90"),
("flipH", "true"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: compress #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-006",
}data = [
("action", "compress"),
("targetSizeKB", "200"),
("quality", "80"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: enhance #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-007",
}data = [
("action", "enhance"),
("sharpen", "1"),
("contrast", "1.1"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: padding #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-008",
}data = [
("action", "padding"),
("pad", "20"),
("padColor", "#ffffff"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: frame #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-009",
}data = [
("action", "frame"),
("border", "4"),
("borderColor", "#000000"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: background #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-010",
}data = [
("action", "background"),
("backgroundColor", "#ffffff"),
]with open("./samples/a.png", "rb") as image_file:
files = [
("images", ("a.png", image_file, "image/png")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: watermark #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-011",
}data = [
("action", "watermark"),
("watermarkText", "H2I"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: pdf #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-012",
}data = [
("action", "pdf"),
("format", "pdf"),
("pdfMode", "single"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: metadata #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-013",
}data = [
("action", "metadata"),
("normalizeOrientation", "true"),
("includeRawExif", "true"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: multitask #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-014",
}data = [
("action", "multitask"),
("width", "1200"),
("format", "webp"),
("watermarkText", "H2I"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/image", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

For /v1/image:

  • metadata returns JSON metadata results
  • other actions return generated-file results with signed URLs under /image/<file>

Endpoint: POST /v1/pdf #

Supported actions: merge, to-images, compress, extract-images, watermark, rotate, metadata, reorder, delete-pages, extract, flatten, encrypt, decrypt, split. The endpoint uses multipart/form-data. One optional watermarkImage upload is accepted, and for non-merge actions the first uploaded PDF is used as the primary input.

Shared PDF parameters #

  • action
  • files
  • sortByName
  • pages
  • format
  • quality
  • density
  • watermarkText
  • watermarkImage
  • opacity
  • position
  • fontSize
  • color
  • x
  • y
  • degrees
  • order
  • password
  • userPassword
  • ownerPassword
  • ranges
  • prefix

Action: merge #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-015",
}data = [
("action", "merge"),
("sortByName", "true"),
]with open("./samples/one.pdf", "rb") as file_one, open("./samples/two.pdf", "rb") as file_two:
files = [
("files", ("one.pdf", file_one, "application/pdf")),
("files", ("two.pdf", file_two, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: to-images #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-016",
}data = [
("action", "to-images"),
("pages", "all"),
("format", "png"),
("density", "144"),
("quality", "85"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: compress #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-017",
}data = [
("action", "compress"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: extract-images #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-018",
}data = [
("action", "extract-images"),
("pages", "all"),
("imageFormat", "jpeg"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: watermark #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-019",
}data = [
("action", "watermark"),
("watermarkText", "CONFIDENTIAL"),
("opacity", "0.3"),
("position", "center"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: rotate #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-020",
}data = [
("action", "rotate"),
("degrees", "90"),
("pages", "1,2"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: metadata #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-021",
}data = [
("action", "metadata"),
("title", "Updated"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Supported metadata fields for this action:

  • cleanAllMetadata
  • title
  • author
  • subject
  • keywords
  • creator
  • producer

Action: reorder #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-022",
}data = [
("action", "reorder"),
("order", "[3,1,2]"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: delete-pages #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-023",
}data = [
("action", "delete-pages"),
("pages", "2-4"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: extract #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-024",
}data = [
("action", "extract"),
("pages", "1-3"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: flatten #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-025",
}data = [
("action", "flatten"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: encrypt #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-026",
}data = [
("action", "encrypt"),
("userPassword", "userpass"),
("ownerPassword", "ownerpass"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

userPassword is required for encrypt. ownerPassword is optional and defaults to userPassword if omitted. encrypt and decrypt depend on qpdf being available in the runtime environment.

Action: decrypt #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-027",
}data = [
("action", "decrypt"),
("password", "userpass"),
]with open("./samples/locked.pdf", "rb") as pdf_file:
files = [
("files", ("locked.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: split #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-028",
}data = [
("action", "split"),
("ranges", "1-2,3-5"),
("prefix", "chapter_"),
]with open("./samples/doc.pdf", "rb") as pdf_file:
files = [
("files", ("doc.pdf", pdf_file, "application/pdf")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/pdf", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

For /v1/pdf:

  • pages accepts selectors such as all, first, and CSV page ranges
  • ranges is required for split
  • password is required for decrypt
  • userPassword is required for encrypt
  • page-limited operations can return pdf_page_limit_exceeded

Endpoint: POST /v1/tools #

Top-level action values are single and multitask, but actual analyzer selection is controlled through tools or tools[].

Documented tool names:

  • metadata
  • colors
  • detect-format
  • orientation
  • hash
  • similarity
  • dimensions
  • quality
  • transparency
  • efficiency

Shared tools parameters #

  • action
  • images
  • tools or tools[]
  • includeRawExif
  • paletteSize
  • hashType
  • qualitySample
  • transparencySample
  • similarityMode
  • similarityThreshold
  • efficiencyFormat
  • efficiencyQuality

Tool: metadata #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-029",
}data = [
("action", "single"),
("tools", "metadata"),
("includeRawExif", "true"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: colors #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-030",
}data = [
("action", "single"),
("tools", "colors"),
("paletteSize", "8"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: detect-format #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-031",
}data = [
("action", "single"),
("tools", "detect-format"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: orientation #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-032",
}data = [
("action", "single"),
("tools", "orientation"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: hash #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-033",
}data = [
("action", "single"),
("tools", "hash"),
("hashType", "phash"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: similarity #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-034",
}data = [
("action", "single"),
("tools", "similarity"),
("similarityMode", "tofirst"),
("similarityThreshold", "8"),
]with open("./samples/a.jpg", "rb") as image_a, open("./samples/b.jpg", "rb") as image_b:
files = [
("images", ("a.jpg", image_a, "image/jpeg")),
("images", ("b.jpg", image_b, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: dimensions #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-035",
}data = [
("action", "single"),
("tools", "dimensions"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: transparency #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-036",
}data = [
("action", "single"),
("tools", "transparency"),
("transparencySample", "64"),
]with open("./samples/a.png", "rb") as image_file:
files = [
("images", ("a.png", image_file, "image/png")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: quality #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-037",
}data = [
("action", "single"),
("tools", "quality"),
("qualitySample", "256"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Tool: efficiency #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-038",
}data = [
("action", "single"),
("tools", "efficiency"),
("efficiencyFormat", "webp"),
("efficiencyQuality", "80"),
]with open("./samples/a.jpg", "rb") as image_file:
files = [
("images", ("a.jpg", image_file, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Action: multitask #

headers = {
"X-Api-Key": API_KEY,
"Idempotency-Key": "idem-ext-039",
}data = [
("action", "multitask"),
("tools", "metadata,dimensions,hash,similarity,quality"),
("hashType", "phash"),
("similarityMode", "tofirst"),
("similarityThreshold", "10"),
("qualitySample", "256"),
]with open("./samples/a.jpg", "rb") as image_a, open("./samples/b.jpg", "rb") as image_b:
files = [
("images", ("a.jpg", image_a, "image/jpeg")),
("images", ("b.jpg", image_b, "image/jpeg")),
]
status, response_data = api_multipart_request(f"{BASE}/v1/tools", data, files, headers)print(status)
print(json.dumps(response_data, indent=2) if isinstance(response_data, dict) else response_data)

Parameters

  • action — required, multitask
  • tools / tools[] — required, comma-separated or repeated list
  • images — required file inputs
  • any applicable tool-specific fields may be included in the same multipart request

Notes

  • action=single requires exactly one tool.
  • tools and tools[] are both accepted.
  • tools input is parsed as a lowercase comma-separated list.
  • similarityMode supports pairs and tofirst.
  • The multitask request format is flat multipart form-data. There is no nested tasks[] JSON structure in the implementation.
  • Unknown tool names are ignored rather than causing a dedicated error.

Tools response shape #

/v1/tools returns structured analysis results in this form:

{
"results": [
{
"originalName": "a.jpg",
"sizeBytes": 123456,
"tools": {}
}
],
"request_id": "req_abc123"
}

Similarity can also add similarity-specific structures depending on mode.


Common external errors #

These are the main external error codes relevant to Python usage:

  • api_key_location_not_allowed
  • invalid_api_key
  • key_expired
  • endpoint_not_allowed
  • rate_limit_exceeded
  • rate_limit_store_unavailable
  • timeout
  • server_busy
  • file_too_large
  • too_many_files
  • total_upload_exceeded
  • dimension_exceeded
  • invalid_upload
  • unsupported_media_type
  • monthly_quota_exceeded
  • invalid_parameter
  • missing_field
  • html_too_large
  • render_size_exceeded
  • html_render_failed
  • image_processing_failed
  • pdf_tool_failed
  • tool_processing_failed

Final notes #

  • /v1/h2i uses JSON bodies.
  • /v1/image, /v1/pdf, and /v1/tools use multipart/form-data.
  • /v1/tools returns JSON analysis results rather than generated file URLs.
  • encrypt and decrypt depend on qpdf being available in the runtime environment.
  • Generated output URLs are signed and protected for output-fetch paths according to the configured signed URL behavior.
Was it helpful ?
Scroll to Top