Prerequisites
Before making requests, ensure the following are in place:- The Hagaki Renderer service is running and reachable on port 8899.
- Asset directories are present at the expected paths relative to the service binary:
../asset/private/frame— frame images../asset/private/idol— character images../asset/public/render— output directory for cached renders
The service binds to
0.0.0.0:8899 by default. If you are running it behind a reverse proxy or in a container, substitute your actual host and port in the examples below.Render a single card
Construct the card payload
Build a JSON object describing the card you want to render. All fields except
offset_x, offset_y, and save_name are required.card-payload.json
| Field | Type | Description |
|---|---|---|
id | u32 | Character ID. |
variant | u8 | Card variant index. |
dye | u32 | Dye color value applied to supported frames. |
kindled | boolean | Whether the kindled effect is active. |
frame_type | u8 | Frame to use: 0 = Moonweaver, 1 = Essentia, 2 = Snowglow. |
offset_x | i32? | Optional horizontal offset for the character image in pixels. |
offset_y | i32? | Optional vertical offset for the character image in pixels. |
save_name | string? | Optional filename (without extension) for the cached render on disk. |
Encode the payload as a base64 hash
Serialize the JSON to a string and encode it as standard base64, no padding. This encoded string becomes the
{hash} path segment.The service decodes using the standard base64 alphabet (
+ and /), with no padding. Strip the trailing = padding but do not replace + or /. Most shell base64 utilities produce the standard alphabet by default, so only the padding removal (tr -d '=') is needed.Interpret the response headers
A successful response returns
200 OK with a PNG body and the following headers:| Header | Example value | Description |
|---|---|---|
Content-Type | image/png | Always PNG. |
X-Source | rendered on request | rendered on request for a fresh render; loaded from disk cache when the PNG was already saved. |
X-Processing-Time | 12.34ms | Wall-clock time the renderer took to produce the image. |
Inspect headers with curl
Render a fan spread
A fan render composes multiple cards into a single fanned-out image. The payload wraps acards array using the same per-card structure as above, plus an optional top-level save_name.
The fan layout applies a 5° tilt between adjacent cards arranged along a circular arc with a center distance of 3000 px. The more cards you include, the wider the spread.
Error responses
| Status | Meaning |
|---|---|
400 | The hash could not be decoded, or the decoded JSON does not match the expected shape. |
500 | The render timed out (limit: 5 seconds), a required asset file is missing, or the PNG buffer could not be written. |
418 | The request path did not match any known endpoint. |
Next steps
API reference
Full parameter reference for all three endpoints: card, fan, and album.
Frame types
Detailed breakdown of Moonweaver, Essentia, and Snowglow frame capabilities.