Skip to main content

Bannerbear Python Library

A Python wrapper for the Bannerbear API — an image generation and media processing service.

Documentation

Find the full API documentation here.

Requirements

Python 3.8 or higher.

Installation

pip install bannerbear

V5 API

The V5 API is the current generation of the Bannerbear API. V5 API keys are not compatible with V2 endpoints, and vice versa.

This library currently ships the V5 client only. V2 support may be added in a future release under bannerbear.v2.

Table of Contents

Authentication

from bannerbear.v5 import Client

bb = Client("your V5 API key")

Or set BANNERBEAR_API_KEY and instantiate without arguments:

bb = Client()

Account

bb.account()

Image Templates

Templates can be created, updated, and deleted through the API — config holds the full canvas.

bb.list_image_templates(page=1)
bb.get_image_template("template uid")

bb.create_image_template({
    "name": "My Template",
    "description": "Created from the API",
    "tags": ["portrait"],
    "width": 1080,
    "height": 1080,
    "config": {
        "objects": [
            {"id": "bg", "type": "rectangle", "left": 0, "top": 0,
             "width": 1080, "height": 1080, "background-color": "#0f172a"},
            {"id": "headline", "type": "text", "left": 80, "top": 400, "width": 920,
             "text": "Hello World!", "font-size": 72, "color": "#ffffff"},
        ]
    },
})

bb.update_image_template("template uid", {
    "name": "New Name",
    "description": "...",
    "tags": ["portrait"],
})

bb.delete_image_template("template uid")
Options for create_image_template / update_image_template
  • name required for create
  • description
  • tags
  • width / height: canvas size in pixels
  • config: full canvas configuration, {"objects": [...]}. Passing it replaces the existing config in place

Deleting is a soft delete: images already rendered from the template stay intact, but the template no longer appears in list/get calls and cannot be used for new renders.

Images

V5's modifications is a dict with two sub-keys:

  • template — template-level changes (width, height, etc.)
  • objects — list of per-layer changes
bb.create_image("template uid", {
    "modifications": {
        "template": {"width": 1080, "height": 1080},
        "objects": [
            {"name": "headline", "text": "Hello World!"},
            {
                "name": "photo",
                "image_url": "https://images.unsplash.com/photo-1555400038-63f5ba517a47?w=1000&q=80",
            },
        ],
    },
})

Synchronous generation routes to sync.api.bannerbear.com/v5 (10s timeout). synchronous is a keyword-only flag — it's a transport switch and is not sent in the request body:

bb.create_image("template uid", {"modifications": {"objects": [...]}}, synchronous=True)
Options for create_image
  • modifications: V5 modifications dict
  • formats: output formats, e.g. ["jpg", "pdf"]
  • scale: scale multiplier, 1–4
  • dpi: DPI metadata
  • quality: quality control
  • proxy: proxy and resize external images before rendering (bool)
  • metadata: include any metadata to reference at a later point
  • version: pin template version
  • synchronous (keyword-only): route to the sync host (SDK-only, not sent to the API)
bb.get_image("image uid")
bb.list_images(page=1)

Tools

Tools are standalone media operations that do not use a template. Every tool is asynchronous: the call returns a pending tool job. Poll get_tool_job until the status is "completed" or "failed", or subscribe to a webhook with the resource "tool_job".

job = bb.trim_video({"video_url": "https://example.com/clip.mp4", "start": 2.5, "end": 10.0})

job = bb.get_tool_job(job["uid"])
job["status"]  # "pending" | "running" | "completed" | "failed"
if job["status"] == "completed":
    print(job["outputs"]["video_url"])

bb.list_tool_jobs(page=1)

Every tool also accepts an optional metadata string.

Method Required Optional Output key
remove_bg image_url — image_url
create_pdf urls — pdf_url
trim_video video_url, start, end — video_url
concat_videos video_urls width, height video_url
resize_video video_url, width, height fit video_url
crop_video video_url, x, y, width, height — video_url
overlay_video base_video_url, overlay_video_url, x, y scale, start video_url
overlay_image video_url, image_url, x, y opacity video_url
subtitle_video video_url language, font, font_size, color, bold, italic, outline_color, outline_width, shadow_size, shadow_color, background_style, background_color, alignment video_url
generate_voiceover text, voice — audio_url
add_audio video_url, audio_url, mode volume, loop, ducking video_url
add_cover_art video_url, image_url — video_url
create_video_slideshow image_urls slide_duration, transition, transition_duration, width, height video_url
apply_color_filter video_url, filter — video_url
soften_video video_url, strength — video_url

A few examples:

bb.remove_bg({"image_url": "https://example.com/product.png"})

bb.subtitle_video({
    "video_url": "https://example.com/talk.mp4",
    "font": "montserrat",
    "font_size": 32,
    "color": "#ffffff",
    "background_style": "outline",
    "alignment": "2",
})

bb.generate_voiceover({"text": "Welcome to Bannerbear.", "voice": "rachel"})

bb.create_video_slideshow({
    "image_urls": ["https://example.com/1.jpg", "https://example.com/2.jpg"],
    "slide_duration": 3,
    "transition": "fade",
    "width": 1280,
    "height": 720,
})

create_tool_job calls any tool by name — the escape hatch for tools added after this release:

bb.create_tool_job("remove_bg", {"image_url": "https://example.com/product.png"})

Assets

Upload a file (max 5MB) and get back a durable CDN URL you can feed to image modifications or tools. Uploads are deduplicated per workspace by SHA-256, so re-uploading the same bytes returns the existing record instead of creating a duplicate.

with open("logo.png", "rb") as f:
    asset = bb.upload_asset(f.read(), "image/png")

asset["url"]

bb.get_asset("asset uid")
bb.list_assets(page=1)

Accepted mime types: image/jpeg, image/png, image/webp, image/gif, video/mp4, video/webm, video/quicktime, audio/mpeg, audio/wav, audio/mp4, audio/webm, audio/ogg, application/pdf.

check_assets maps each SHA-256 content hash to its existing asset (or None), so a syncing client can skip the upload round-trip for content it already pushed. Max 100 hashes per call.

import hashlib

data = open("logo.png", "rb").read()
digest = hashlib.sha256(data).hexdigest()
if bb.check_assets([digest])[digest] is None:
    bb.upload_asset(data, "image/png")

Publications

Publications are templates published to the public library. Installing one clones it into your workspace as a new image template.

bb.list_publications(page=1)
bb.get_publication("publication uid")

template = bb.install_publication("publication uid")
template["uid"]

Batches

Generate multiple images in one request (up to 100).

bb.create_batch({
    "type": "images",
    "items": [
        {"template": "template uid 1", "modifications": {"objects": [...]}},
        {"template": "template uid 2", "modifications": {"objects": [...]}},
    ],
})
bb.get_batch("batch uid")
bb.list_batches(page=1)

Webhooks

Webhooks are managed as a first-class resource in V5.

hook = bb.create_webhook({
    "name": "my-webhook",
    "url": "https://example.com/hook",
    "resource": "image",
    "event": "completed",
    "status": "active",
    "scope": "all_templates",
    "templates": [],
})

# IMPORTANT: signing_key is ONLY returned in the create response. Store it now —
# subsequent get_webhook calls will not include it.
print(hook["signing_key"])
Options for create_webhook / update_webhook
  • name required
  • url required — the URL that receives the events
  • resource: "image", "batch", or "tool_job"
  • event: "all_events", "completed", or "failed"
  • status: "active" or "disabled"
  • scope: "all_templates" or "specific_templates"
  • templates: template UIDs, used when scope is "specific_templates"

CRUD:

bb.get_webhook("webhook uid")
bb.update_webhook("webhook uid", {
    "name": "renamed",
    "url": "https://example.com/hook",
    "resource": "image",
    "event": "completed",
    "status": "active",
    "scope": "all_templates",
})
bb.delete_webhook("webhook uid")
bb.list_webhooks(page=1)

Instant URLs

Instant URLs are URLs bound to a template that can be manipulated with query strings.

Create an Instant URL base

iurl = bb.create_instant_url({
    "name": "my-instant-url",
    "template": "template uid",
    "mode": "encoded",         # or "named_params"
    "security": "signed",      # or "open"
    "status": "active",
    "scale": 1,                # 1, 2, 3, or 4
})

# IMPORTANT: signing_key is ONLY returned in the create response. Store it now.
print(iurl["signing_key"])
print(iurl["base_url"])
Options for create_instant_url / update_instant_url
  • name required
  • template required — image template UID
  • mode: "encoded" or "named_params"
  • security: "signed" or "open"
  • status: "active" or "disabled"
  • scale: 1, 2, 3, or 4
  • rate_limit: enable per-IP rate limiting
  • template_version: pin template version
  • max_renders: cap total renders
  • expires_at: ISO 8601 expiry

CRUD:

bb.get_instant_url("uid")
bb.update_instant_url("uid", {"name": "...", "template": "...", ...})
bb.delete_instant_url("uid")
bb.list_instant_urls(page=1)

Build an Instant URL with modifications

build_instant_url is a pure local helper — no API call. It composes the URL from a base + modifications and, if a signing key is provided, appends the HMAC signature.

# Encoded mode, signed
bb.build_instant_url(
    iurl["base_url"],
    mode="encoded",
    signing_key=iurl["signing_key"],
    modifications={
        "template": {"width": 1030, "height": 890},
        "objects": [{"name": "title", "text": "Hello!", "color": "#ffffff"}],
    },
)

# Named params mode, signed
bb.build_instant_url(
    iurl["base_url"],
    mode="named_params",
    signing_key=iurl["signing_key"],
    modifications={
        "template": {"width": 1030, "height": 890},
        "objects": [{"name": "title", "text": "Hello!"}],
    },
)

# Open (unsigned): omit signing_key
bb.build_instant_url(
    iurl["base_url"],
    mode="encoded",
    modifications={"objects": [{"name": "title", "text": "Hello!"}]},
)
Options for build_instant_url
  • base_url (positional, required) — from the create_instant_url response
  • modifications (kwarg, required) — same shape as create_image's modifications
  • mode (kwarg) — "encoded" (default) or "named_params"
  • signing_key (kwarg) — only needed when the instant URL was created with security="signed"

License

MIT. See LICENSE.

Metadata

Release files for bannerbear 1.1.0

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

Source distribution (sdist)

Source distribution for bannerbear 1.1.0
File Size Uploaded Provenance
bannerbear-1.1.0.tar.gz 8.3 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 18.4 kB

Release files / bannerbear-1.1.0.tar.gz

Download URL bannerbear-1.1.0.tar.gz
Size 8.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4d38198ed2349fd2a444f8f5c23c2fa73365f44a122ff0c54d750215871968bc
BLAKE2b-256 checksum
How to use checksums
c8433c3e40f0ed14248080883a2ccf1b07e81a0e394f044a6b8b11cea71dcafa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.5

Release files / bannerbear-1.1.0-py3-none-any.whl

Download URL bannerbear-1.1.0-py3-none-any.whl
Size 10.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
60626590906769c5e41967b42aea6938bfe53c41c66c6bf05065a1c4fa02ed97
BLAKE2b-256 checksum
How to use checksums
dea270c1139d875586368f151fe500d58cf35873228cd9a3b2352e1234d869b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.5

Security for bannerbear 1.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

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