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-KeyAuthorization: Bearer <key>
Optional idempotency headers are also supported:
Idempotency-KeyX-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/pdfreturn generated outputs and signed URLs./v1/toolsreturns 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:
imagepdf
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 beimagehtml— required HTML stringcss— optional CSS stringwidth— optional viewport width, default1000height— optional viewport height, default1500format— optional output format, defaultpng; onlyjpegproduces JPEG, other values become PNG
Notes
- If
width * heightexceeds the render pixel limit, the request fails withrender_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 bepdfhtml— required HTML stringcss— optional CSS stringwidth,height— optional viewport valuespdfFormat— optional, defaultA4; onlyLETTERmaps to LetterpdfLandscape— optional boolean, defaultfalsepdfMargin— optional integer, default24preferCSSPageSize— optional boolean, defaulttruescale— optional numeric, default1printMode— optional boolean, defaultfalseprintBackground— optional boolean, defaulttrue
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:
actionimageswatermarkImageformatwidth,height,enlargecropX,cropY,cropWidth,cropHeightrotate,flipH,flipVtargetSizeKB,qualitykeepMetadata,normalizeOrientationblur,sharpen,grayscale,sepiabrightness,contrast,saturationpad,padTop,padRight,padBottom,padLeft,padColorborder,borderColor,borderRadiusbackgroundColor,backgroundBlurwatermarkText,watermarkFontSize,watermarkColor,watermarkOpacity,watermarkPosition,watermarkMargin,watermarkScalepdfMode,pdfPageSize,pdfOrientation,pdfMargin,pdfEmbedFormat,pdfJpegQualitycolorSpaceincludeRawExif
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:
metadatareturns 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 #
actionfilessortByNamepagesformatqualitydensitywatermarkTextwatermarkImageopacitypositionfontSizecolorxydegreesorderpassworduserPasswordownerPasswordrangesprefix
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:
cleanAllMetadatatitleauthorsubjectkeywordscreatorproducer
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:
pagesaccepts selectors such asall,first, and CSV page rangesrangesis required forsplitpasswordis required fordecryptuserPasswordis required forencrypt- 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:
metadatacolorsdetect-formatorientationhashsimilaritydimensionsqualitytransparencyefficiency
Shared tools parameters #
actionimagestoolsortools[]includeRawExifpaletteSizehashTypequalitySampletransparencySamplesimilarityModesimilarityThresholdefficiencyFormatefficiencyQuality
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,multitasktools/tools[]— required, comma-separated or repeated listimages— required file inputs- any applicable tool-specific fields may be included in the same multipart request
Notes
action=singlerequires exactly one tool.toolsandtools[]are both accepted.toolsinput is parsed as a lowercase comma-separated list.similarityModesupportspairsandtofirst.- 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_allowedinvalid_api_keykey_expiredendpoint_not_allowedrate_limit_exceededrate_limit_store_unavailabletimeoutserver_busyfile_too_largetoo_many_filestotal_upload_exceededdimension_exceededinvalid_uploadunsupported_media_typemonthly_quota_exceededinvalid_parametermissing_fieldhtml_too_largerender_size_exceededhtml_render_failedimage_processing_failedpdf_tool_failedtool_processing_failed
Final notes #
/v1/h2iuses JSON bodies./v1/image,/v1/pdf, and/v1/toolsusemultipart/form-data./v1/toolsreturns JSON analysis results rather than generated file URLs.encryptanddecryptdepend onqpdfbeing available in the runtime environment.- Generated output URLs are signed and protected for output-fetch paths according to the configured signed URL behavior.
