Asynchronous Generation
Generate multiple formats of images, videos, GIFs, HTML5 banners or PDFs in one call. The endpoint returns a generation_request_id immediately, and results arrive by webhook or polling.
Use it whenever you need many formats at once, or an output type that takes longer to render — GIFs, videos, print PDFs. For a single on-demand image, use the synchronous endpoint.
AI image features belong here
Having no completion bound, this is the only endpoint that accepts text_to_image (AI generation and inpainting), and it is the recommended home for remove_bg as well — both add an AI round-trip that the synchronous endpoint's 10-second cap cannot absorb. remove_bg is deprecated there for exactly that reason.
How it works

- Send a request with your design ID and customization parameters
- Receive a
generation_request_idimmediately - Retrieve results once generation is complete — via webhook or polling
Endpoint
Multi-page PDFs use a different endpoint
POST /async/banner-builder/{designId}/generate-multipage-pdf — see Generate Multi-Page PDF for Printing.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
designId | string (uuid) | Yes | Unique identifier of the design to generate from. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
elements | object | No | Dictionary of element overrides keyed by layer name. See Element Properties. Omit to render the design's saved default content. |
template_format_names | array | No | List of format IDs to generate (e.g. ["facebook-feed", "instagram-post"]). Omit or pass an empty array to generate all formats. |
callback_url | string (uri) | No | URL that will receive a POST request with the NEW_BANNER_BATCH payload when generation completes. |
image_file_type | string | No | Output file type: "png", "jpeg", "webp", "avif", "gif", "pdf", "html5", "mp4" ("auto" ≡ omitted). Must match the design type (else 400 invalid_filetype): static → jpeg/png/webp/avif/pdf, animated → mp4/gif/html5, print → pdf. When omitted: static → jpeg (png when the format background is transparent); animated → mp4; print → pdf. |
file_compression_level | integer | No | Output quality, 1–100 — 100 is the best quality (least compression), 1 the smallest file. Despite the name, higher = better. |
html5 | object | No | HTML5 output options (animated designs only). Fields: page_title, click_tag, ad_network, include_backup_image, repeat. |
gif | object | No | GIF output options (animated designs only). Fields: max_fps (2–9), repeat. |
video | object | No | Video output options (animated designs only). Fields: fps (2–30). |
print | object | No | Print output options (printer designs only). Fields: color_profile (UUID), display_crop_marks. |
original_visual_id | string (uuid) | No | Regenerate an existing visual in place — see Visual Versioning. The request must target exactly one format, else 400 more_than_one_format. |
pages | object | No | printer_multipage designs only: per-page element overrides keyed by page id ({"page_1": {…}}) — see Multi-Page PDF. Ignored on other design types. |
Response
| Field | Type | Description |
|---|---|---|
generation_request_id | string (uuid) | Unique identifier of the batch generation request. Use this to poll for status or match incoming webhook events. |
Plan-gated output types
html5, mp4, gif and PDF outputs are plan-dependent. A plan restriction answers 429 with id: rate_limit_exceeded and a message naming the gated output (e.g. "429 GIF is not included in your plan, please update your plan.") — the same shape as running out of credits. A build rejection (e.g. text that cannot fit) answers 400 with id: cannot_build_banner.
Receiving results
No time guarantee
Batches are queued and worker-driven: there is no hard completion bound (unlike the 10-second synchronous cap). Most batches complete within a couple of minutes — but build on the webhook or on patient polling, never on a fixed client-side wait.
Once generation is complete, Abyssale delivers results in one of three ways:
| Method | How | When to use |
|---|---|---|
| Job-Specific Callback | Include callback_url in the request body | One-time endpoint, or to override the global webhook |
| Global Webhook | Configure a webhook in the Abyssale dashboard subscribed to NEW_BANNER_BATCH | All async results delivered to a single persistent endpoint |
| Polling | Poll GET /generation-request/{generationRequestId} | When you can't receive inbound webhooks |
Webhook payload
Abyssale sends a POST request to the callback URL with the following JSON body:
{
"event_type": "NEW_BANNER_BATCH",
"generation_request_id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"banners": [
{
"id": "64238d01-d402-474b-8c2d-fbc957e9d290",
"version": 1,
"sharing_id": "5fcec999-2bfb-4dd7-ba38-2d9e16c49149",
"file": {
"type": "jpeg",
"url": "https://production-banners.s3.eu-west-1.amazonaws.com/demo/ee6739f4-b563-428a-a6e8-ec3cb8bd03d4.jpeg",
"cdn_url": "https://cdn.abyssale.com/demo/ee6739f4-b563-428a-a6e8-ec3cb8bd03d4.jpeg",
"filename": "ee6739f4-b563-428a-a6e8-ec3cb8bd03d4.jpeg"
},
"format": { "id": "facebook-feed", "width": 1200, "height": 628, "unit": "px" },
"template": {
"id": "46d22c62-d134-44d3-a040-138e4ea9ea08",
"name": "Summer campaign — FB feed",
"created_at": 1749827107,
"updated_at": 1749827107
}
}
],
"errors": [
{ "template_format_name": "instagram-story", "reason": "Element text_title error: The text cannot fit within the defined space." }
]
}Each banners[] item has the same shape as the synchronous response. errors[] items are per-format failures — {template_format_name, reason} — and never fail the rest of the batch.
Polling

The response is identical to the webhook payload (minus event_type — this is a REST response, not an event) with one addition — an is_finalized boolean. When true, the request is complete and will not change:
{
"is_finalized": false,
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"banners": [],
"errors": []
}- While the batch runs the endpoint answers
202withis_finalized: false; once complete it answers200withis_finalized: true. A202does not mean the arrays are empty —bannersanderrorsfill in as individual formats finish, so a poll mid-run returns partial results. Branch onis_finalized, not on array length. - An unknown id answers
404 generation_request_not_found; generation requests expire after 7 days (410 generation_request_gone). - There is no completion bound — most batches finish within a couple of minutes. The endpoint is rate-limited; don't poll aggressively.
Sample request
curl -X POST \
-H "x-api-key: {YOUR-API-KEY}" \
-H "Content-Type: application/json" \
-d '{
"callback_url": "https://webhook.mycompany.com/images",
"template_format_names": ["facebook-feed", "instagram-post", "iab-medium"],
"elements": {
"primary_text": {
"payload": "New branding available.",
"color": "#FF0000"
}
}
}' \
https://api.abyssale.com/async/banner-builder/{designId}/generateimport abyssale from '@abyssale/sdk';
// Set ABYSSALE_API_KEY env var before running
const { data, error } = await abyssale.generateMultiFormatMedia('{designId}', {
callback_url: "https://webhook.mycompany.com/images",
template_format_names: ["facebook-feed", "instagram-post", "iab-medium"],
elements: {
primary_text: { payload: "New branding available.", color: "#FF0000" }
}
});
if (error) console.error(error);
else console.log(data.generation_request_id);from abyssale import Abyssale
# Set ABYSSALE_API_KEY env var before running
with Abyssale() as client:
accepted = client.generate_multi_format_media("{designId}", {
"callback_url": "https://webhook.mycompany.com/images",
"template_format_names": ["facebook-feed", "instagram-post", "iab-medium"],
"elements": {
"primary_text": {"payload": "New branding available.", "color": "#FF0000"},
},
})
print(accepted.generation_request_id)Sample response
{ "generation_request_id": "df75afa8-5a77-4e03-aeef-6d1b6dd0580a" }Related
- Generate Multi-Format Images
- Generate Multi-Format Videos
- Generate Multi-Format Animated GIFs
- Generate HTML5 Banner Ads
- Generate Multi-Format PDFs for Printing
- Generate Multi-Page PDF for Printing
- Node.js SDK · Python SDK — every method, config, retries and the polling helpers
