Skip to main content

API2Convert Python SDK

CI PyPI version Python License

The official Python client for the API2Convert file-conversion API. Convert, compress and transform images, documents, audio, video, ebooks, archives and CAD — and run operations like OCR, merge, thumbnail and website capture — in one line of code.

from api2convert import Api2Convert

client = Api2Convert("YOUR_API_KEY")

client.convert("invoice.docx", "pdf").save("invoice.pdf")

That single call creates a job, uploads your file, starts it, waits for it to finish and gives you back a result you can save. No polling loops, no manual upload handling.

Requirements

  • Python 3.10+
  • httpx (installed automatically)

Install

pip install api2convert

Get an API key from the API2Convert dashboard / documentation.

Quick start

from api2convert import Api2Convert

# Reads the API2CONVERT_API_KEY environment variable when no key is passed.
client = Api2Convert("YOUR_API_KEY")

# 1) From a local file
client.convert("photo.png", "jpg").save("photo.jpg")

# 2) From a URL
client.convert("https://example.com/photo.png", "jpg").save("photo.jpg")

# 3) With conversion options (discover them via client.options("jpg"))
client.convert("photo.png", "jpg", {"quality": 85, "width": 1280, "height": 720}).save("out/")

convert(source, to, options=None, ...) — source is a local path, a public URL, or an open binary stream; to is the target format; options is the conversion options map for that target. Less-common controls are keyword-only arguments: category, timeout, output_index, filename, download_password. The returned ConversionResult lets you:

result = client.convert("report.docx", "pdf")

result.save("report.pdf")       # stream to a file
result.save("downloads/")       # ...or a directory (keeps the server filename)
data = result.contents()        # ...or get the raw bytes
url = result.url()              # ...or just the download URL

Password-protect the result

Pass download_password and the output is locked behind it. The SDK remembers the password and sends it automatically when you download — you don't pass it again:

result = client.convert("statement.docx", "pdf", download_password="hunter2")

result.save("statement.pdf")    # the password is applied for you

The download URL still needs the password from anywhere else (a browser, curl, another process), via the X-Api2convert-Download-Password header. When you already hold an OutputFile — e.g. from the Jobs API — hand the password to download():

client.download(output, "hunter2").save("out/")

Asynchronous conversions & webhooks

For long-running jobs, start the conversion and get notified via a webhook instead of waiting:

job = client.convert_async("movie.mov", "mp4", callback="https://your-app.example.com/webhooks/api2convert")

In your webhook handler, verify and parse the callback:

from api2convert import Api2Convert
from api2convert import SignatureVerificationError

payload = request.body                       # the RAW body (bytes or str)
signature = request.headers.get("X-Oc-Signature")

try:
    event = Api2Convert.webhooks().construct_event(payload, signature, "YOUR_WEBHOOK_SECRET")
    job = event.job
    # ... react to job.status.code ...
except SignatureVerificationError:
    ...  # respond 400

Signed webhooks are being rolled out. Until they are enabled for your account no signature is sent — call Api2Convert.webhooks().parse(payload) (or pass an empty secret) to deserialize the callback without verifying.

Cloud storage

Read an input straight from your own cloud storage, and/or deliver the converted output into a bucket — no local upload or download in between. Supports Amazon S3, Azure, FTP and Google Cloud.

Import an input with the per-provider CloudInput factory (keys are flat and lowercase, exactly as the API expects) and convert it like any other source:

from api2convert import Api2Convert, CloudInput

client = Api2Convert("YOUR_API_KEY")

s3_input = CloudInput.amazon_s3(
    bucket="my-bucket",
    file="invoices/report.docx",
    accesskeyid="AKIA...",
    secretaccesskey="...",
)

client.convert(s3_input, "pdf").save("report.pdf")

To deliver the result into a bucket instead, attach an OutputTarget via output_targets. When any output target is set the conversion delivers straight to your storage and produces no local file — so there is nothing to save():

from api2convert import Api2Convert, CloudProvider, OutputTarget

client = Api2Convert("YOUR_API_KEY")

target = OutputTarget.of(
    CloudProvider.AMAZON_S3,
    parameters={"bucket": "my-bucket", "file": "out/report.pdf"},
    credentials={"accesskeyid": "AKIA...", "secretaccesskey": "..."},
)

# Delivered to the bucket — the job completes without a downloadable output.
client.convert("report.docx", "pdf", output_targets=[target])

azure(...), ftp(...) and google_cloud(...) build inputs the same way; output uses the generic OutputTarget for every provider. Credentials ride in the request body but are redacted in exception messages and object inspection (repr) as [REDACTED] — they are never logged or printed.

Error handling

Every failure is a typed exception extending api2convert.Api2ConvertError:

from api2convert import (
    Api2Convert,
    AuthenticationError,
    ConversionFailedError,
    RateLimitError,
    ValidationError,
)

try:
    Api2Convert("KEY").convert("photo.png", "jpg").save("photo.jpg")
except ValidationError as e:
    ...  # bad target / option — str(e) explains
except AuthenticationError:
    ...  # bad or missing API key
except RateLimitError as e:
    ...  # too many requests — retry after e.retry_after seconds
except ConversionFailedError as e:
    ...  # the job failed — inspect e.errors()
Exception When
AuthenticationError 401 / 403 — bad or missing key
PaymentRequiredError 402 — no remaining quota
ValidationError 400 / 422 — invalid request (e.g. unknown target)
NotFoundError 404 — resource doesn't exist
RateLimitError 429 — exposes .retry_after
ServerError 5xx
NetworkError transport failure / non-JSON success body
ConversionFailedError the job reached failed; exposes .job and .errors()
ConversionTimeoutError the job didn't finish within the poll timeout
SignatureVerificationError a webhook payload failed verification

Transient failures (429, 5xx, network errors) are retried automatically with exponential backoff.

Power user: the full job API

convert() is sugar over the Jobs API. Drop down to it for compound jobs, merges, presets, custom polling or job chaining:

job = client.jobs.create({
    "process": False,
    "conversion": [{"target": "pdf", "options": {"pdf_a": True}}],
})

client.jobs.upload(job, "contract.docx")                          # local file
client.jobs.add_input(job.id, {"type": "remote", "source": "https://example.com/appendix.docx"})

client.jobs.start(job.id)
done = client.jobs.wait(job.id, timeout_seconds=120)

for output in done.output:
    client.download(output).save("out/")

Available resources: client.jobs, client.conversions (the catalog + option discovery), client.presets, client.stats, client.contracts.

Discover the valid options for any target:

options = client.options("jpg")            # -> {"quality": {...}, "width": {...}, ...}

Configuration

client = Api2Convert(
    "YOUR_API_KEY",
    timeout=30,             # per-request network timeout (seconds)
    max_retries=2,          # automatic retries for transient failures
    poll_interval=1.0,      # first poll interval when waiting (seconds)
    poll_max_interval=5.0,  # backoff cap (seconds)
    poll_timeout=300,       # give up waiting after this many seconds
)

Bring your own configured httpx.Client by passing http_client=....

Security — never publish your API key

  • Never hard-code or commit your API key. Load it from the environment (API2CONVERT_API_KEY) or a secrets manager.
  • In CI, store it as a masked & protected variable and never print it to logs.
  • Treat the per-job upload token and your webhook signing secret with the same care.
  • The SDK never logs your key/token and never puts them in exception messages.
  • If a key is ever exposed, revoke and rotate it in the API2Convert dashboard immediately.

Development

python -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'

ruff check src tests examples && ruff format --check src tests examples   # lint + format
mypy src examples                                                         # static typing (strict)
pytest -m "not live"                                     # offline unit tests

Live conformance tests run against the real API when API2CONVERT_API_KEY is set:

API2CONVERT_API_KEY=... pytest -m live

Examples

Runnable, self-contained programs live in examples/ — one per documented guide. Each reads the key from API2CONVERT_API_KEY (and honours API2CONVERT_BASE_URL). Run any of them with, e.g., API2CONVERT_API_KEY=your-key python examples/quickstart.py.

Example Guide
quickstart.py Convert a remote file, look the job up, download the output
convert_files.py Browse the conversions catalog, then convert
uploading_files.py One-call upload + convert of a local file
job_lifecycle.py Drive create → add input → start → wait → outputs by hand
add_watermark.py Stamp a PNG onto a PDF (multi-input job)
create_thumbnails.py Render a document page preview
compress_files.py Shrink a file with the compress operation
create_archives.py Bundle several files into a ZIP
create_hashes.py Compute a SHA-256 checksum
extract_assets.py Extract embedded assets from a document
file_analysis.py Extract file metadata as JSON
compare_files.py Diff two images
capture_website.py Screenshot a URL to PNG
audio_operations.py Re-encode audio (WAV → AAC)
image_operations.py Resize an image
webhooks.py Start a conversion asynchronously with a callback
presets.py List saved conversion presets
statistics.py Read API usage for a month
rate_limits.py Inspect the account's contracts
authentication.py Verify the API key with an authenticated call

The live conformance suite mirrors these examples 1:1 — each test performs the same operation and asserts success — plus two negative tests (an unknown target is a typed ValidationError; a bad key is a typed AuthenticationError that never leaks the key).

It runs automatically against the real API on every release tag (see .github/workflows/live-conformance.yml), so a published version is always verified end to end.

This SDK is hand-written and kept in sync with the API by an AI agent — see AGENTS.md and docs/SDK_CONTRACT.md. Notable changes are recorded in docs/CHANGELOG.md.

License

MIT — see LICENSE.

Metadata

Release files for api2convert 10.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for api2convert 10.3.1
File Size Uploaded Provenance Actions
api2convert-10.3.1.tar.gz 70.1 kB With provenance Details for api2convert-10.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for api2convert 10.3.1
File Interpreter ABI Platform Actions
api2convert-10.3.1-py3-none-any.whl Python 3 none any Details for api2convert-10.3.1-py3-none-any.whl

Total release size: 108.5 kB

Release files / api2convert-10.3.1.tar.gz

Download URL api2convert-10.3.1.tar.gz
Size 70.1 kB
Tags Source
SHA-256 checksum
How to use checksums
935ca68786fdcf91edbd65004b8ae4e503772eeecc791e166d6d0c6c6077cebd
BLAKE2b-256 checksum
How to use checksums
4417ed053abba5be9f9106f834cbb571a61513c38708bc31c1f9e89a6939d7ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release files / api2convert-10.3.1-py3-none-any.whl

Download URL api2convert-10.3.1-py3-none-any.whl
Size 38.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6e2cb8f3a58822152ca2c56b74f39818fb11a6c0abf3c5cab898ef5ebb62a7ab
BLAKE2b-256 checksum
How to use checksums
9891d976d53b310cb58c8083667fcb3e806adb3e441244db1c0214b6b3d28da5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Security for api2convert 10.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for api2convert-10.3.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page