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
- Account
- Image Templates
- Images
- Tools
- Assets
- Publications
- Batches
- Webhooks
- Instant URLs
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
namerequired for createdescriptiontagswidth/height: canvas size in pixelsconfig: 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 dictformats: output formats, e.g.["jpg", "pdf"]scale: scale multiplier, 1–4dpi: DPI metadataquality: quality controlproxy: proxy and resize external images before rendering (bool)metadata: include any metadata to reference at a later pointversion: pin template versionsynchronous(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
namerequiredurlrequired — the URL that receives the eventsresource:"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 whenscopeis"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
namerequiredtemplaterequired — image template UIDmode:"encoded"or"named_params"security:"signed"or"open"status:"active"or"disabled"scale: 1, 2, 3, or 4rate_limit: enable per-IP rate limitingtemplate_version: pin template versionmax_renders: cap total rendersexpires_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 thecreate_instant_urlresponsemodifications(kwarg, required) — same shape ascreate_image's modificationsmode(kwarg) —"encoded"(default) or"named_params"signing_key(kwarg) — only needed when the instant URL was created withsecurity="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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| bannerbear-1.1.0.tar.gz | 8.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bannerbear-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.4 kB
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.