Skip to content

Releases: getabyssale/abyssale-python-sdk

v1.7.0

Choose a tag to compare

@antoox-yk antoox-yk released this 21 Oct 09:36
b623d1e

Models regenerated against API version v2026-10-21, which also brings v2026-10-20. Minor: three methods were added and an enum gained members. Nothing was removed or narrowed, so there is no upgrade step beyond installing it.

Added

  • rename_design(design_id, {"name": ...}), move_design(design_id, {"project_id": ...}) and delete_design(design_id) on both the sync and async clients: PUT /designs/{designId}/name, PUT
    /designs/{designId}/project and DELETE /designs/{designId}. All three return a DesignNameResult (id, name), exported from abyssale.models. Moving a design resets its approval status; deleting has no restore. A design list_designs does not list raises AbyssaleAPIError with id "template_not_found"; a destination that is not a project of the workspace, "project_not_found".
  • Border on image layers: stroke_width (0 to 60) and stroke_color on an image element override. The frame is drawn outside the image box and follows its mask. Bodies are plain dicts, so nothing to change.
  • Justified text: a text element's alignment accepts justify, justify-left, justify-center and justify-right, alone or after a vertical half ("middle justify-center"). Text layers only.

Full changelog: https://github.com/getabyssale/abyssale-python-sdk/blob/main/CHANGELOG.md
API changelog: https://developers.abyssale.com/rest-api/changelog

v1.6.0

Choose a tag to compare

@antoox-yk antoox-yk released this 19 Oct 08:57
cbce016

Models regenerated against API version v2026-10-19, which also brings v2026-10-12. Minor: the text-to-image model enum gained a member. Nothing was removed or narrowed, so there is no upgrade step beyond installing it. abyssale.__api_version__ now reads v2026-10-19.

Added

  • textEffect tweens reveal a text per letter, word or line (v2026-10-19): a design import's keyframe attr may carry textEffectSplit (letter, the default, word or line) and textEffectTiming
    (in, the default, out or inOut, the layout of an effect that plays out). The keyframe attr model is an open map, so no model changed; only its documentation did.
  • ideogram-4.5 joins the text_to_image_properties.model enum (v2026-10-12).

Changed

  • inpaint_images has a maximum per model (v2026-10-12), from 3 to 16 images; the table is in the field's description and the model caps the list at 16. A request with more than the selected model accepts is rejected by the API with a validation error.

Full changelog: https://github.com/getabyssale/abyssale-python-sdk/blob/main/CHANGELOG.md
API changelog: https://developers.abyssale.com/rest-api/changelog

v1.5.0

Choose a tag to compare

@antoox-yk antoox-yk released this 07 Oct 15:56
0dc23f7

Generated from API version v2026-10-07, which also brings v2026-10-02.

Minor: the three listings gained keyword arguments. Every existing call keeps working, including list_designs(type="static"): type now also takes a list.

Added

  • Search, filters, sort and paging on list_designs (v2026-10-07): query (words in any order, in the design or the project name), name, project, orientation, size, format, updated_since, created_since, sort, order, page and per_page. type, size and format take a string or a list, sent comma-separated as the API expects; the dates take an ISO 8601 string, a date or a datetime.
  • Filters and paging on list_fonts (name, category, weight, style) and list_projects (name). Both took no argument before.
  • Models: Font.category (Google fonts), and leonardo-remove-bg among the background-removal models (v2026-10-02).

The total across pages (the X-Total-Count header) is not exposed: the listings still return a plain list. When paging, a page shorter than per_page is the last one.

See List Designs for what each filter does, and the API changelog.

v1.4.0

Choose a tag to compare

@antoox-yk antoox-yk released this 01 Oct 14:54
c96a4d6

Generated from API version v2026-10-01, which also brings v2026-09-30.

Minor: the models gained the upscale settings and new model names. Nothing was removed or narrowed, so there is no upgrade step beyond installing it.

Added

  • Upscale on the image element (v2026-09-30): upscale and upscale_properties on the asynchronous image element, modelled by UpscaleProperties (model: seedvr-upscale, topaz-precision, crystal-upscaler or bria-increase-resolution; upscale_factor: 1 to 4). Asynchronous generation only: the API refuses it on synchronous generation. Request bodies stay plain dicts, so this is documentation for what you send, not a new class to import.
  • Three text-to-image and inpainting models (v2026-09-30): gpt-image-2.5-sunburst, gpt-image-2.5-flare and seedream-5-pro.
  • design_in_open_product among the documented error ids.

Changed

  • Colour fields document radial gradients (v2026-10-01). Every field that takes a linear gradient also takes radial-gradient(cx% cy% r%,<stops>): a centre and a radius as percentages of the layer's box, then the same 2 to 8 stops. A colour is a str either way, so only the field descriptions changed. See the API changelog.

v1.3.1

Choose a tag to compare

@antoox-yk antoox-yk released this 25 Sep 13:26
3f8ae7d

Generated from API version v2026-09-25.

Patch: no model gained or lost a field and no type changed (a colour is a str either way). The regeneration only rewrote the descriptions of the colour fields to the one colour grammar v2026-09-25 publishes.

Changed

  • Colour fields document what you may send. Hex is #RRGGBB, #RRGGBBAA, #RGB or #RGBA; CMYK is cmyk(C,M,Y,K) or cmyka(C,M,Y,K,A), each component an integer 0–100, optionally followed by %. A gradient stop is #RRGGBB, #RGB or cmyk(C,M,Y,K) at an offset of 0% to 100%. A stop has no alpha: its transparency is the stop opacity (0 to 1).

Worth knowing: an API change, not an SDK one

v2026-09-25 refuses with 400 invalid_payload colours it used to draw wrong or fail on:

  • a CMYK component or alpha above 100
  • a gradient stop offset above 100%
  • a stop opacity above 1
  • a 4-digit hex gradient stop

Request bodies are plain dicts passed through untouched, so this reaches you whatever SDK version you run, as an AbyssaleAPIError whose id is invalid_payload. See the API changelog.

v1.3.0

Choose a tag to compare

@antoox-yk antoox-yk released this 24 Sep 13:06
f201c73

Generated from API version v2026-09-24.

Minor, not patch: the models gained fields. No method changed, no signature moved, and nothing that worked against 1.2.0 needs touching. A generation body is a plain dict either way.

Added

  • A button element accepts icon_url, icon_encoded and icon_color. icon_url is a public HTTP(s) URL of an image to place beside the label; icon_encoded is its base64 / data-URI twin, for an icon
    held in memory (icon_url wins if both are sent). icon_color recolours the icon and only applies to an SVG. Sending an icon for a button designed without one adds it on the left, at the label's font size.
    The icon's size, gap and side belong to the design and are not overridable per generation.

    client.generate_image(
        template_id,
        elements={"button_0": {"icon_url": "https://example.com/star.svg", "icon_color": "#FF0000"}},
    )
  • A button element accepts text_shadow_color, text_shadow_blur, text_shadow_offset_x and text_shadow_offset_y. A button has two shadows: the existing shadow_* properties are the shadow of the
    button box, and these four are the shadow of its label.

  • An image element accepts the five auto-focus properties at the top level: auto_focus_model, focus_objects, focus_framing, focus_target and focus_zoom, the flat form of auto_focus_properties.*.
    The nested form wins when both are sent. The face model is deprecated; use people with focus_framing.

  • An image element accepts expand and expand_properties: AI image expansion (outpainting), which extends the image past its borders to fill the target area instead of cropping or letterboxing it.

Changed

  • Colour fields document a linear gradient of 2 to 8 stops instead of exactly two, and say where print accepts one: only a shape or button background_color. The models are unchanged; a colour is a str
    either way.

v1.2.0

Choose a tag to compare

@antoox-yk antoox-yk released this 02 Sep 09:22

Generated from API version v2026-09-02.

Minor, not patch: one new client method. Nothing existing changed shape, so there is no upgrade step beyond installing it.

Added

  • get_credits() on both clients — the new GET /credits, returning the workspace's remaining credits for the current billing period as generation_credits and ai_credits, each a CreditBlock of available, limit, consumed and extra. The read
    costs no credits.

Two things to know before branching on the numbers. available and limit are null on an unlimited plan — and since the generated models type nullable fields as plain int (as they do for Design.project_id), the tolerant parse is what keeps the
None readable; test for None before comparing, because available > 0 raises on an unlimited workspace. And available counts the recurring allowance only, so what a request can still spend is available + extra.

  • CreditsBalance and CreditBlock are exported from abyssale.models.

v1.1.0

Choose a tag to compare

@antoox-yk antoox-yk released this 21 Aug 13:35
cecf511

Generated from API version v2026-08-21.

Minor, not patch: three new client methods and a new public module. Nothing existing changed shape,
so there is no upgrade step beyond installing it.

Added

abyssale.webhooks — a new public module (the third, after abyssale and
abyssale.models) with verify_webhook_signature and signature_timestamp. It imports only the
standard library
: no client, no httpx. That is the point of it being separate — a process that
only receives deliveries should not have to hold a credential that can spend credits, and a test
asserts the import graph so the property cannot rot.

Pass the raw body: the signature covers the bytes as sent, so a parsed-and-re-serialised dict
reorders keys and never matches. It returns False and never raises on a missing, malformed, forged
or stale header — anyone who finds a webhook URL can POST to it, and an exception in a handler is a
500 plus, on most frameworks, a retried delivery. It checks every v1 in the header, because a
rotation puts two there for 24 hours.

get_signing_secret(), rotate_signing_secret(force=False), revoke_signing_secret() on both
clients — the three /signing-secret endpoints. Deliveries are unsigned until
get_signing_secret() is called once; fetching the secret is what turns signing on. A refused
second rotate raises AbyssaleAPIError with id="previous_secret_still_active" and is not
retried
— it is a state conflict, not a transient failure. force is omitted from the query
string entirely when false, so an ordinary rotate stays a bare POST.

SigningSecret response model, generated from the spec.

Fixed

  • FocusZoom is a string enum, not a boolean. It generated as False_ = False — a boolean
    member in a type: string enum — because the spec wrote enum: [off, low, medium, max]
    unquoted and PyYAML reads bare off as a YAML 1.1 boolean. openapi-typescript reads YAML 1.2,
    where it is a string, which is why only this SDK carried the defect. Now off = 'off', matching
    the deployed bundle.

v1.0.0

Choose a tag to compare

@antoox-yk antoox-yk released this 21 Aug 13:29

Generated from API version v2026-08-20.

First release. Covers every operation in that spec — 18 of them — plus two polling helpers over
its status endpoints. Response models are generated from its schemas. Requires Python 3.10+.

Added

  • Abyssale and AsyncAbyssale, over httpx. Both are context managers and both accept a
    caller-supplied httpx client.
  • All 18 endpoints — auth; design list/read/format read; sync and async generation; multipage
    PDF; generation-request status; file read; fonts; projects list/create; export; dynamic image
    URL; workspace templates, categories, duplication and duplication status.
  • wait_for_generation_request / wait_for_duplication_request — exponential backoff with
    jitter, a 30-minute default deadline, and a budget of three consecutive transient failures that
    resets on any successful poll. Partial success resolves: a finalized request carrying both banners
    and per-format errors is a result, not an exception. Only a request that finalized with no banners
    at all and at least one error raises.
  • Retries that follow the spec's error contract — 5xx on idempotent methods only (every POST
    bills credits, and a 504 does not mean the render did not happen); the full ladder for a 429
    carrying Retry-After; exactly one one-second probe for a bare 429, because
    rate_limit_exceeded conflates spent credits with the gateway's per-second ceiling;
    feature_not_in_plan never retried, whatever headers the response carries.
  • max_retry_wait ($ABYSSALE_MAX_RETRY_WAIT_MS, default 30s) — the longest single
    Retry-After the SDK will sleep through on your behalf. The rate limiter can name a cool-off of
    ~1700s once a quota is spent, and max_retries multiplies it, so honouring it blindly would turn
    one call into 83 minutes of silence. Past the bound the call fails immediately with
    AbyssaleRateLimitError, retry_after carrying the server's figure so the decision is yours.
    Pass math.inf to wait however long the server asks.
  • An exception hierarchy under AbyssaleError, built from the API's single error envelope — the
    machine-readable id is always on the exception, and errors holds the per-field problems when
    the failure was a payload problem.
  • Pydantic response models generated from the spec, with the Alpha design-import surface
    stripped by scripts/fetch_spec.py.
  • Seven runnable examples in examples/, each exercising a documented operation end to end.

Notes

  • Request bodies are plain dicts. The elements schema is an anyOf of ten deliberately
    overlapping branches with no discriminator, and the API accepts unknown element names by design,
    so bodies are passed through untouched rather than modelled.
  • Parsing never fails a successful response. Unknown fields are kept, and a field the spec
    calls required but the response omits does not raise — the spec is hand-maintained and the API is
    the authority.